2014-11-13 8 views
4

Flask를 실행중인 내 서버에서 Flask-Socketio를 사용하고 있고 클라이언트에서 javascript를 실행하고 있습니다. 모든 클라이언트는 네임 스페이스 '/test'을 사용하여 서버에 연결합니다. 클라이언트에서 특정 동작이 발생하면 클라이언트가 연결된 모든 클라이언트를 반복하는 서버에서 함수를 트리거하도록합니다. 나는 연결된 클라이언트 목록을 반복하는 다음 코드 세그먼트를 사용하고 각 연결이 연결에 할당 된 'ID'키가Flask-Socketio : 네임 스페이스 키 오류. 연결된 클라이언트 목록을 얻으십시오.

for sessid, socket in request.namespace.socket.server.sockets.items(): 
    print "socket id : %r" % (socket['/test'].session['id']) 

.

그러나 때때로 서버는 네임 스페이스 키를 찾을 수 없음을 나타내는 다음과 같은 오류 제공 : 내가 서버에 연결 내 모든 소켓이에 연결되어 있기 때문에이 오류가 왜 이해가 안

Traceback (most recent call last): 
File "/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py", line 327, in run 
    result = self._run(*self.args, **self.kwargs) 
File "/usr/local/lib/python2.7/dist-packages/socketio/virtsocket.py", line 403, in_receiver_loop 
    retval = pkt_ns.process_packet(pkt) 
File "/usr/local/lib/python2.7/dist-packages/socketio/namespace.py", line 155, in process_packet 
    return self.process_event(packet) 
File "/usr/local/lib/python2.7/dist-packages/flask_socketio/__init__.py", line 64, in process_event 
    return self.socketio._dispatch_message(app, self, message, args) 
File "/usr/local/lib/python2.7/dist-packages/flask_socketio/__init__.py", line 137, in _dispatch_message 
    ret = self.messages[namespace.ns_name][message](*args) 
File "/home/ubuntu/flask-app/current/py/flaskapp/main/sockets.py", line 190, in gameInitialisedByClient 
    print "id : %r random: %r" % (socket['/test'].session['id'], socket['/test'].session['random']) 
File "/usr/local/lib/python2.7/dist-packages/socketio/virtsocket.py", line 190, in __getitem__ 
    return self.active_ns[key] 
KeyError: '/test' 
<Greenlet at 0x7f483bc6bf50: <bound method Socket._receiver_loop of <socketio.virtsocket.Socket object at 0x7f483a5ac6d0>>> failed with KeyError 

을 동일한 네임 스페이스. 또한이 오류는 일부 함수 호출 중에 만 발생합니다. 이 오류가 왜 일관되지 않습니까?

연결된 클라이언트 목록을 반복 할 수있는 더 좋은 방법이 있습니까?

답변

3

gevent-socketio의 개인 데이터 구조를 반복하므로 예기치 않은 일이 발생할 수 있습니다.

이 패키지의 내부 구조에 대해 알지 못해서 왜 이런 일이 발생하는지 알려주지 만 훨씬 안전한 방법은 연결된 클라이언트 목록을 직접 작성하는 것입니다. 연결 및 연결 끊기 핸들러에서 목록에 클라이언트를 추가 및 제거 할 수 있습니다. 이런 식으로 생각합니다 :

clients = [] 

@socketio.on('connect', namespace='/test') 
def connect(): 
    clients.append(request.namespace) 

@socketio.on('disconnect', namespace='/test') 
def disconnect(): 
    clients.remove(request.namespace) 
+0

감사합니다. 그러나 나는 플라스크 권리에서 전역 변수를 유지할 수는 없습니까? 글로벌 변수가 세션 및 요청을 통해 유지 관리됩니까? –

+0

gevent와 함께 단일 작업자 프로세스를 사용하는 경우 전역 변수가 문제가되지 않습니다. 클래스를 클라이언트 목록에 캡슐화하면 더 멋지게 보이게 할 수 있습니다. 예제는 빠르고 간단합니다. 또 다른 방법은 클라이언트 목록을'app' 객체에 등록하는 것입니다. – Miguel