I am running a Flask app behind Gunicorn and nginx (and Cloudflare, if that matters). I've recently tried to add SocketIO functionality, however have come across a problem. I'm using eventlet as the asynchronous service.
The websocket connection works initially, however before long the SocketIO client disconnects from the server due to ping timeout. Upon checking the log output, Flask-SocketIO claims to send the PONG command, however the client does not appear to receive it.
Flask-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 client
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
Relevant code
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){
...
});
As you can see, my custom log
event is received by the client just fine upon connection, so I'm very confused since it doesn't appear to be a problem receiving data. Or it could very well be that Flask-SocketIO isn't actually sending the PONG.
Any help would be appreciated.