Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Flask Socketio:命名空间键错误,获取已连接客户端的列表_Python_Sockets_Flask_Flask Sockets_Flask Socketio - Fatal编程技术网

Python Flask Socketio:命名空间键错误,获取已连接客户端的列表

Python Flask Socketio:命名空间键错误,获取已连接客户端的列表,python,sockets,flask,flask-sockets,flask-socketio,Python,Sockets,Flask,Flask Sockets,Flask Socketio,我在运行Flask的服务器上使用Flask Socketio,我的客户端运行javascript。我的所有客户端都使用命名空间'/test'连接到服务器。在客户机上执行某个操作时,我希望客户机触发服务器上的一个函数,该函数遍历所有连接的客户机。我正在使用以下代码段迭代连接的客户端列表: for sessid, socket in request.namespace.socket.server.sockets.items(): print "socket id : %r" % (socke

我在运行Flask的服务器上使用Flask Socketio,我的客户端运行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
回溯(最近一次呼叫最后一次):
文件“/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py”,第327行,正在运行
结果=self.\u运行(*self.args,**self.kwargs)
文件“/usr/local/lib/python2.7/dist packages/socketio/virtsocket.py”,第403行,in_receiver_循环
retval=pkt\u ns.process\u数据包(pkt)
文件“/usr/local/lib/python2.7/dist-packages/socketio/namespace.py”,第155行,进程中数据包
返回自处理事件(数据包)
文件“/usr/local/lib/python2.7/dist-packages/flask\u-socketio/\u\u-init\u\u.py”,第64行,进程中事件
返回self.socketio.\u调度\u消息(应用程序、self、消息、参数)
文件“/usr/local/lib/python2.7/dist packages/flask_socketio/_init__.py”,第137行,在调度消息中
ret=self.messages[namespace.ns_name][message](*args)
文件“/home/ubuntu/flask-app/current/py/flaskapp/main/sockets.py”,第190行,在gameInitialisedByClient中
打印“id:%r随机:%r”%(套接字['/test'].会话['id'],套接字['/test'].会话['random'])
文件“/usr/local/lib/python2.7/dist packages/socketio/virtsocket.py”,第190行,在__
返回自激活\u ns[键]
KeyError:“/test”
失败,错误为KeyError
我不明白为什么会出现此错误,因为我所有连接到服务器的套接字都连接在同一命名空间上。此外,此错误仅在函数调用的一小部分过程中出现。为什么这个错误不一致


有没有更好的方法可以遍历已连接的客户端列表?

您正在遍历package
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)

谢谢你的帮助。但我不能在flask中维护全局变量,对吗?全局变量是否会在会话和请求之间进行维护?如果您将单个工作进程与gevent一起使用,那么拥有全局变量不是问题。如果您想让客户机列表看起来更好,您可能希望将其封装在类中,但我的示例是一种快速而肮脏的方法。另一种选择是使用
app
对象注册客户列表。