如何在烧瓶socketio中保持活力?

Posted

技术标签:

【中文标题】如何在烧瓶socketio中保持活力?【英文标题】:how to keep alive in flask-socketio? 【发布时间】:2016-04-01 22:57:08 【问题描述】:

我的烧瓶项目中有一个错误。 socketio 客户端经常与我的 flask-socketio 服务器断开连接。他们将在几分钟后重新连接。我想保持连接始终有效,我该怎么做? 如何修复此错误?

Traceback (most recent call last):


File "F:\Python27\lib\site-packages\gevent\pywsgi.py", line 846, in handle_one
_response
    self.run_application()
  File "F:\Python27\lib\site-packages\geventwebsocket\handler.py", line 76, in r
un_application
    self.run_websocket()
  File "F:\Python27\lib\site-packages\geventwebsocket\handler.py", line 52, in r
un_websocket
    self.application(self.environ, lambda s, h, e=None: [])
  File "F:\Python27\lib\site-packages\flask\app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "F:\Python27\lib\site-packages\flask_socketio\__init__.py", line 37, in _
_call__
    start_response)
  File "F:\Python27\lib\site-packages\engineio\middleware.py", line 47, in __cal
l__
    return self.engineio_app.handle_request(environ, start_response)
  File "F:\Python27\lib\site-packages\socketio\server.py", line 303, in handle_r
equest
    return self.eio.handle_request(environ, start_response)
  File "F:\Python27\lib\site-packages\engineio\server.py", line 226, in handle_r
equest
    environ, start_response)
  File "F:\Python27\lib\site-packages\engineio\socket.py", line 75, in handle_ge
t_request
    start_response)
  File "F:\Python27\lib\site-packages\engineio\socket.py", line 110, in _upgrade
_websocket
    return ws(environ, start_response)
  File "F:\Python27\lib\site-packages\engineio\async_gevent.py", line 43, in __c
all__
    return self.app(self)
  File "F:\Python27\lib\site-packages\engineio\socket.py", line 171, in _websock
et_handler
    self.receive(pkt)
  File "F:\Python27\lib\site-packages\engineio\socket.py", line 45, in receive
    self.server._trigger_event('message', self.sid, pkt.data)
  File "F:\Python27\lib\site-packages\engineio\server.py", line 307, in _trigger
_event
    return self.handlers[event](*args)
  File "F:\Python27\lib\site-packages\socketio\server.py", line 423, in _handle_
eio_message
    self._handle_event(sid, pkt.namespace, pkt.id, pkt.data)
  File "F:\Python27\lib\site-packages\socketio\server.py", line 364, in _handle_
event
    r = self._trigger_event(data[0], namespace, sid, *data[1:])
  File "F:\Python27\lib\site-packages\socketio\server.py", line 391, in _trigger
_event
    return self.handlers[namespace][event](*args)
  File "F:\Python27\lib\site-packages\flask_socketio\__init__.py", line 147, in
_handler
    app = self.server.environ[sid]['flask.app']
KeyError: 'e99ae44429294ef1af9b9012c6cd747c'
'GATEWAY_INTERFACE': 'CGI/1.1',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, sdch',
 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.8,en;q=0.6',
 'HTTP_CACHE_CONTROL': 'no-cache',
 'HTTP_CONNECTION': 'Upgrade',
 'HTTP_COOKIE': 'io=e99ae44429294ef1af9b9012c6cd747c; session=.eJyrVkrNTczMUbJSS
q_KyUzMS8_NzEvPKM10SM4vKtDLSy1JTSxO1UvOz1XSUUorzcnJS8xNBSqOKTWzsDAEkmYGqTGlFmkWl
kD5vMzkbKg8qmFKtQBXYyPB.CV-98A.aLaOqWHgFZILSx3w1JJ7V9RFUaE',
 'HTTP_HOST': '127.0.0.1:5001',
 'HTTP_ORIGIN': 'http://127.0.0.1:5001',
 'HTTP_PRAGMA': 'no-cache',
 'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits',
 'HTTP_SEC_WEBSOCKET_KEY': '7dsbtNi0XUWxPY3rXHn4MA==',
 'HTTP_SEC_WEBSOCKET_VERSION': '13',
 'HTTP_UPGRADE': 'websocket',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHT
ML, like Gecko) Chrome/47.0.2526.106 Safari/537.36',
 'PATH_INFO': '/socket.io/',
 'QUERY_STRING': 'EIO=3&transport=websocket&sid=e99ae44429294ef1af9b9012c6cd747c
',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_PORT': '2318',
 'REQUEST_METHOD': 'GET',
 'SCRIPT_NAME': '',
 'SERVER_NAME': 'GIH-D-9660.game.ntes',
 'SERVER_PORT': '5001',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'gevent/1.1 Python/2.7',
 'flask.app': <Flask 'views'>,
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x0213D0D0>,
 'wsgi.input': <gevent.pywsgi.Input object at 0x034255A8>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0),
 'wsgi.websocket': None,
 'wsgi.websocket_version': '13' failed with KeyError

【问题讨论】:

【参考方案1】:

请在服务器上启用 Engine.IO 日志记录(将参数 engineio_logger=True 添加到您的构造函数中),以便我们准确了解服务器所做的事情。

我的猜测是日志会显示服务器超时等待来自客户端的 ping 数据包,因此它假定客户端离开并关闭连接。 Socket.IO 协议要求客户端每隔一段时间发送这些特殊的 ping 数据包,如果没有发生,则服务器关闭连接。

根据您的错误,服务器似乎超时等待 ping 数据包并关闭了连接,但后来客户端确实发送了 ping 数据包,但已经太晚了。但是,这种情况下的错误消息可以改进,所以我会为此记录一个错误。

如果您设置的连接不可靠,您可以通过在SocketIO 构造函数中设置参数ping_timeout 来增加超时。默认值为 60 秒。

【讨论】:

Miguel:启用 engineio_logger=True 后,该日志文件位于何处(或者只是控制台输出)?我有同样的错误,我猜它是别的东西,但是这个错误被 socketio 的所有 handle_one 函数输出抑制了。 @KennyPowers 日志会转到控制台,除非您告诉它转到自定义日志记录对象。

以上是关于如何在烧瓶socketio中保持活力?的主要内容,如果未能解决你的问题,请参考以下文章

在 SocketIO 命名空间中使用烧瓶会话数据时出错

如何在线程中运行 python-socketio?

烧瓶 socketio CORS

在 Android 中解除绑定后,如何让服务与听众保持活力?

如何在 docker 容器中设置 flask-socketio?

在 Uwsgi 和 Nginx 上使用 SocketIO 烧瓶