I get the following error when trying to connect to a SSL encrypted Flask-socketio server using the websocket transport.
Attempting WebSocket connection to wss://localhost/socket.io/?transport=websocket&EIO=3
Traceback (most recent call last):
File "client.py", line 6, in <module>
sio.connect('https://localhost', transports=['websocket'])
File "/Library/Python/3.7/site-packages/socketio/client.py", line 279, in connect
six.raise_from(exceptions.ConnectionError(exc.args[0]), None)
File "<string>", line 3, in raise_from
socketio.exceptions.ConnectionError: Connection error
Is there something more I need to configure for WSS to work? Unencrypted web sockets seem to work just fine.
Server.py
from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, logger=True)
socketio.run(app, host='0.0.0.0', port=443, debug=True, keyfile='snakeoil.key', certfile='snakeoil.pem')
Client.py
import socketio
sio = socketio.Client(ssl_verify=False, logger=True, engineio_logger=True)
sio.connect('https://localhost', transports=['websocket'])
sio.disconnect()
Flask==1.1.1
Flask-SocketIO==4.3.0
python-engineio==3.12.1
python-socketio==4.5.1
Try adding an HTTP route and accessing it from your web browser to see if the server on port 443 is listening.
It is running on port 443 and works just fine there. Furthermore, if I don't specify websocket transport the above code also works.
Output when not specifying transports
Attempting polling connection to https://localhost/socket.io/?transport=polling&EIO=3
Polling connection accepted with {'sid': '394f193798eb413a9bbbbaaf8f7e5d57', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
Engine.IO connection established
Received packet MESSAGE data 0
Namespace / is connected
Attempting WebSocket upgrade to wss://localhost/socket.io/?transport=websocket&EIO=3
WebSocket upgrade failed: connection error
Sending packet PING data None
Sending polling GET request to https://localhost/socket.io/?transport=polling&EIO=3&sid=394f193798eb413a9bbbbaaf8f7e5d57
my sid is 394f193798eb413a9bbbbaaf8f7e5d57
Sending packet MESSAGE data 1
Sending packet CLOSE data None
Engine.IO connection dropped
Received packet PONG data None
Waiting for write loop task to end
Waiting for ping loop task to end
Exiting ping task
Exiting read loop task
Are you using eventlet or gevent?
eventlet==0.25.2
Okay, have you looked at logs from the server? How do things look there?
Server shows 400 error on websocket request, no other logging is given
(84007) wsgi starting up on https://0.0.0.0:8080
(84007) accepted ('127.0.0.1', 65033)
127.0.0.1 - - [08/May/2020 14:02:46] "GET /socket.io/?transport=websocket&EIO=3&t=1588968166.745132 HTTP/1.1" 400 122 0.000266
when I disable SSL then the websocket connection is successful.
(84028) wsgi starting up on http://0.0.0.0:8080
(84028) accepted ('127.0.0.1', 65043)
127.0.0.1 - - [08/May/2020 14:05:56] "GET /socket.io/?transport=websocket&EIO=3&t=1588968356.286274 HTTP/1.1" 200 0 0.002229
You need to enable socket.io logs in the server to see the reason for the 400 error.
enabling engineio_logger shed enough light on the issue.
(84096) wsgi starting up on https://0.0.0.0:8080
(84096) accepted ('127.0.0.1', 65163)
http://localhost:8080 is not an accepted origin.
127.0.0.1 - - [08/May/2020 14:23:42] "GET /socket.io/?transport=websocket&EIO=3&t=1588969422.69502 HTTP/1.1" 400 122 0.000295
Adding cors_allowed_origins=[] to the server resolves the issue. This fix is a little dubious but acceptable
Use cors_allowed_origins='http://localhost:8080' for increased security.
Most helpful comment
enabling engineio_logger shed enough light on the issue.
Adding
cors_allowed_origins=[]to the server resolves the issue. This fix is a little dubious but acceptable