Flask-Socketio: ошибка пространства имен., Получить список подключенных клиентов.
Я использую Flask-Socketio на своем сервере, на котором работает Flask, и мои клиенты запускают javascript. Все мои клиенты подключаются к серверу, используя пространство имен '/test'
, После определенного действия на клиенте я хочу, чтобы клиент вызвал функцию на сервере, которая выполняет итерацию по всем подключенным клиентам. Я использую следующий сегмент кода для перебора списка подключенных клиентов:
for sessid, socket in request.namespace.socket.server.sockets.items():
print "socket id : %r" % (socket['/test'].session['id'])
где каждому соединению назначен ключ '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
Я не понимаю, почему я получаю эту ошибку, так как все мои сокеты, которые соединяются с сервером, соединяются в том же пространстве имен. Более того, эта ошибка возникает только во время части вызовов функций. Почему эта ошибка не соответствует?
Есть ли лучший способ, которым я мог бы перебрать список подключенных клиентов?
1 ответ
Вы перебираете частную структуру данных пакета 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)