flask-socket.io:频繁超时
flask-socket.io: frequent time-outs
我有一个非常标准的 flask-socket.io 应用程序:
服务器:eventlet
我使用以下方式启动应用程序:socketio.run(app, host='0.0.0.0')
我经常但不总是遇到某种超时:
Traceback (most recent call last):
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/wsgi.py", line 507, in handle_one_response
result = self.application(self.environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/flask_socketio/__init__.py", line 42, in __call__
start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/middleware.py", line 47, in __call__
return self.engineio_app.handle_request(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/socketio/server.py", line 360, in handle_request
return self.eio.handle_request(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/server.py", line 267, in handle_request
environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 89, in handle_get_request
start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 130, in _upgrade_websocket
return ws(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/async_eventlet.py", line 19, in __call__
return super(WebSocketWSGI, self).__call__(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 127, in __call__
self.handler(ws)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 155, in _websocket_handler
pkt = ws.wait()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 633, in wait
for i in self.iterator:
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 503, in _iter_frames
message = self._recv_frame(message=fragmented_message)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 526, in _recv_frame
header = recv(2)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 442, in _get_bytes
d = self.socket.recv(numbytes - len(data))
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 360, in recv
return self._recv_loop(self.fd.recv, b'', bufsize, flags)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 354, in _recv_loop
self._read_trampoline()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 325, in _read_trampoline
timeout_exc=socket_timeout('timed out'))
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 207, in _trampoline
mark_as_closed=self._mark_as_closed)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/hubs/__init__.py", line 163, in trampoline
return hub.switch()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/hubs/hub.py", line 295, in switch
return self.greenlet.switch()
socket.timeout: timed out
我无法解释这个回溯。有 flask-socket.io 经验的人可以帮忙吗?
我没有发布任何代码,因为我不知道从哪里开始。回溯中的所有文件都来自已安装的模块。
编辑:
我获得了有关 socket.io 请求的更多信息。在上述异常之后,记录了以下请求:
127.0.0.1 - - [04/Jan/2018 10:10:51] "GET /socket.io/?EIO=3&transport=websocket&sid=f93955151a3a4576b2e96427cc27121e HTTP/1.1" 500 0 60.061493
127.0.0.1 - - [04/Jan/2018 10:10:51] "GET /socket.io/?EIO=3&transport=polling&t=1515056991349-3&sid=f93955151a3a4576b2e96427cc27121e HTTP/1.1" 400 218 60.001593
127.0.0.1 - - [04/Jan/2018 10:10:52] "GET /socket.io/?EIO=3&transport=polling&t=1515057052758-4 HTTP/1.1" 200 381 0.000875
(12472) accepted ('127.0.0.1', 39520)
127.0.0.1 - - [04/Jan/2018 10:10:52] "POST /socket.io/?EIO=3&transport=polling&t=1515057052767-5&sid=10663b1e21e6492b81b5455ebc805408 HTTP/1.1" 200 219 0.001145
如果你想切换到调试模式,你可以使用socketio.run(app, host='0.0.0.0', port=5000, debug=True)
。
那你可以上socket.io official documentation website, most especialy on client-api and server-api看看。
因为在the httpsserver-options part of the server-api(对于javascript),你可以看到当运行连接服务器时有一些选项,比如:
pingInterval: 10000,
pingTimeout: 5000,
我希望当您 运行 使用 socketio.run(app, host='0.0.0.0', port=5000, debug=True,pingInterval = 10000, pingTimeout= 5000)
服务器时,这些参数可以重新用作 kwargs
并且在 flask-socketio 文档中,在 "Error Handling" 部分,有很好的提示 deal with exceptions
您可以添加类似
的内容
@socketio.on_error_default # handles all namespaces without an explicit error handler
def default_error_handler(e):
pass
另一个提示可能是针对超时问题调整之前的 error_handler 并在触发此事件时重新运行 服务器。
您可能还注意到:
The message and data arguments of the current request can also be inspected with the request.event variable, which is useful for error logging and debugging outside the event handler
您也可以使用以下代码来处理最终的 socket.timeout: timed out 错误 :
try:
socketio.run(app,...
except socket.error as socketerror:
print("Error: ", socketerror)
补充 答案。在 flask-socketio 中更改 pingInterval 和 pingTimeout 的正确方法是:
from flask_socketio import SocketIO
socketio = SocketIO(app,ping_timeout=5,ping_interval=10)
这行不通:socketio.run(app, host='0.0.0.0', port=5000, debug=True,pingInterval = 10000, pingTimeout= 5000)
我有一个非常标准的 flask-socket.io 应用程序:
服务器:eventlet 我使用以下方式启动应用程序:socketio.run(app, host='0.0.0.0')
我经常但不总是遇到某种超时:
Traceback (most recent call last):
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/wsgi.py", line 507, in handle_one_response
result = self.application(self.environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/flask_socketio/__init__.py", line 42, in __call__
start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/middleware.py", line 47, in __call__
return self.engineio_app.handle_request(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/socketio/server.py", line 360, in handle_request
return self.eio.handle_request(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/server.py", line 267, in handle_request
environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 89, in handle_get_request
start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 130, in _upgrade_websocket
return ws(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/async_eventlet.py", line 19, in __call__
return super(WebSocketWSGI, self).__call__(environ, start_response)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 127, in __call__
self.handler(ws)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/engineio/socket.py", line 155, in _websocket_handler
pkt = ws.wait()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 633, in wait
for i in self.iterator:
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 503, in _iter_frames
message = self._recv_frame(message=fragmented_message)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 526, in _recv_frame
header = recv(2)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/websocket.py", line 442, in _get_bytes
d = self.socket.recv(numbytes - len(data))
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 360, in recv
return self._recv_loop(self.fd.recv, b'', bufsize, flags)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 354, in _recv_loop
self._read_trampoline()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 325, in _read_trampoline
timeout_exc=socket_timeout('timed out'))
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/greenio/base.py", line 207, in _trampoline
mark_as_closed=self._mark_as_closed)
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/hubs/__init__.py", line 163, in trampoline
return hub.switch()
File "/projects/ici_chat_prototype01/env/lib/python3.5/site-packages/eventlet/hubs/hub.py", line 295, in switch
return self.greenlet.switch()
socket.timeout: timed out
我无法解释这个回溯。有 flask-socket.io 经验的人可以帮忙吗?
我没有发布任何代码,因为我不知道从哪里开始。回溯中的所有文件都来自已安装的模块。
编辑: 我获得了有关 socket.io 请求的更多信息。在上述异常之后,记录了以下请求:
127.0.0.1 - - [04/Jan/2018 10:10:51] "GET /socket.io/?EIO=3&transport=websocket&sid=f93955151a3a4576b2e96427cc27121e HTTP/1.1" 500 0 60.061493
127.0.0.1 - - [04/Jan/2018 10:10:51] "GET /socket.io/?EIO=3&transport=polling&t=1515056991349-3&sid=f93955151a3a4576b2e96427cc27121e HTTP/1.1" 400 218 60.001593
127.0.0.1 - - [04/Jan/2018 10:10:52] "GET /socket.io/?EIO=3&transport=polling&t=1515057052758-4 HTTP/1.1" 200 381 0.000875
(12472) accepted ('127.0.0.1', 39520)
127.0.0.1 - - [04/Jan/2018 10:10:52] "POST /socket.io/?EIO=3&transport=polling&t=1515057052767-5&sid=10663b1e21e6492b81b5455ebc805408 HTTP/1.1" 200 219 0.001145
如果你想切换到调试模式,你可以使用socketio.run(app, host='0.0.0.0', port=5000, debug=True)
。
那你可以上socket.io official documentation website, most especialy on client-api and server-api看看。 因为在the httpsserver-options part of the server-api(对于javascript),你可以看到当运行连接服务器时有一些选项,比如:
pingInterval: 10000,
pingTimeout: 5000,
我希望当您 运行 使用 socketio.run(app, host='0.0.0.0', port=5000, debug=True,pingInterval = 10000, pingTimeout= 5000)
并且在 flask-socketio 文档中,在 "Error Handling" 部分,有很好的提示 deal with exceptions
您可以添加类似
的内容@socketio.on_error_default # handles all namespaces without an explicit error handler
def default_error_handler(e):
pass
另一个提示可能是针对超时问题调整之前的 error_handler 并在触发此事件时重新运行 服务器。
您可能还注意到:
The message and data arguments of the current request can also be inspected with the request.event variable, which is useful for error logging and debugging outside the event handler
您也可以使用以下代码来处理最终的 socket.timeout: timed out 错误 :
try:
socketio.run(app,...
except socket.error as socketerror:
print("Error: ", socketerror)
补充
from flask_socketio import SocketIO
socketio = SocketIO(app,ping_timeout=5,ping_interval=10)
这行不通:socketio.run(app, host='0.0.0.0', port=5000, debug=True,pingInterval = 10000, pingTimeout= 5000)