我在Gunicorn和nginx(和Cloudflare,如果这很重要)后面运行一个Flask应用程序。我最近尝试添加SocketIO功能,但遇到了问题。我使用eventlet作为异步服务。
websocket连接最初工作,但不久之后SocketIO客户端由于ping超时而与服务器断开连接。检查日志输出后,Flask-SocketIO声称发送PONG命令,但客户端似乎没有收到它。
烧瓶SocketIO
ec61fcdf18cd437496b04ed75a99006d: Sending packet OPEN data {'pingInterval': 25000, 'pingTimeout': 60000, 'upgrades': [], 'sid': 'ec61fcdf18cd437496b04ed75a99006d'}
ec61fcdf18cd437496b04ed75a99006d: Sending packet MESSAGE data 2["log",{"data":"Ready."}]
ec61fcdf18cd437496b04ed75a99006d: Sending packet MESSAGE data 0
ec61fcdf18cd437496b04ed75a99006d: Received request to upgrade to websocket
ec61fcdf18cd437496b04ed75a99006d: Upgrade to websocket successful
ec61fcdf18cd437496b04ed75a99006d: Received packet PING data None
ec61fcdf18cd437496b04ed75a99006d: Sending packet PONG data None
# Error occurs after the client disconnects
[2017-04-09 17:56:57 +0000] [31646] [ERROR] Socket error processing request.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 135, in handle
self.handle_request(listener, req, client, addr)
File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 191, in handle_request
six.reraise(*sys.exc_info())
File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 183, in handle_request
resp.close()
File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 417, in close
self.send_headers()
File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 337, in send_headers
util.write(self.sock, util.to_bytestring(header_str, "ascii"))
File "/usr/local/lib/python2.7/dist-packages/gunicorn/util.py", line 306, in write
sock.sendall(data)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
File "/usr/lib/python2.7/socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
SocketIO客户端
socket.io-client:url parse https://example.com +0ms
socket.io-client new io instance for https://example.com +6ms
socket.io-client:manager readyState closed +4ms
socket.io-client:manager opening https://example.com +0ms
engine.io-client:socket creating transport "websocket" +4ms
engine.io-client:socket setting transport websocket +4ms
socket.io-client:manager connect attempt will timeout after 20000 +0ms
socket.io-client:manager readyState opening +4ms
engine.io-client:socket socket receive: type "open", data "{"pingInterval":25000,"pingTimeout":60000,"upgrades":[],"sid":"ec61fcdf18cd437496b04ed75a99006d"}" +128ms
engine.io-client:socket socket open +0ms
socket.io-client:manager open +0ms
socket.io-client:manager cleanup +4ms
socket.io-client:socket transport is open - connecting +4ms
engine.io-client:socket socket receive: type "message", data "2["log",{"data":"Ready."}]" +0ms
socket.io-parser decoded 2["log",{"data":"Ready."}] as {"type":2,"nsp":"/","data":["log",{"data":"Ready."}]} +0ms
socket.io-client:socket emitting event ["log",{"data":"Ready."}] +12ms
engine.io-client:socket socket receive: type "message", data "0" +4ms
socket.io-parser decoded 0 as {"type":0,"nsp":"/"} +12ms
engine.io-client:socket writing ping packet - expecting pong within 60000ms +25s
engine.io-client:socket flushing 1 packets in socket +0ms
engine.io-client:socket socket close with reason: "ping timeout" +1m
socket.io-client:manager onclose +0ms
socket.io-client:manager cleanup +4ms
socket.io-client:socket close (ping timeout) +0ms
相关代码
app.socketio = SocketIO(app, engineio_logger=True)
@app.socketio.on('connect')
def import_on_connect():
emit('log', {'data': 'Ready.'})
app.socketio.run(app)
var socket = io.connect({transports: ['websocket'], upgrade: false});
socket.on('log', function(data){
...
});
正如您所看到的,我的自定义log
事件在连接时就被客户端接收了,所以我很困惑,因为它似乎不是一个接收数据的问题。或者很可能Flask-SocketIO实际上并没有发送PONG。
任何帮助都将不胜感激。