Flask-socketio: Can't use WebSockets

Created on 25 Jul 2020  路  11Comments  路  Source: miguelgrinberg/Flask-SocketIO

Hello,
I have an issue similar to #1237 .
I have set-up the simple server with to use WebSockets, but it only works with polling.
When I try to use WebSockets it gives me 502, because the server does not respond correctly, it sends regular 200 instead of upgrading the connection and keeping it open.

server {
    listen 8080;

    location /socket.io {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass http://127.0.0.1:5000/socket.io;
    }
}

uWSGI command

uwsgi --workers 1 --http :5000 --gevent 1000 --http-websockets --enable-threads --master --wsgi-file app.py --callable app

app.py

from flask import Flask
from flask_socketio import SocketIO, emit


app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*", logger=True, engineio_logger=True)


@socketio.on('connect')
def ws_connect():
    emit('connected', {'user': 'Hello'})

wscat

$ wscat -c http://127.0.0.1:8080/socket.io/
error: Unexpected server response: 200
> %     

uWSGI logs

*** Starting uWSGI 2.0.19.1 (64bit) on [Sat Jul 25 12:32:06 2020] ***
compiled with version: 10.1.0 on 23 July 2020 06:52:30
os: Linux-5.7.9-1-MANJARO #1 SMP PREEMPT Thu Jul 16 08:20:05 UTC 2020
nodename: machine-name
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 12
current working directory: /home/user/test-project/
detected binary path: /home/user/test-project/.venv/bin/uwsgi
your processes number limit is 63392
your memory page size is 4096 bytes
detected max file descriptor number: 1024
- async cores set to 1000 - fd table size: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :5000 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:35661 (port auto-assigned) fd 3
Python version: 3.8.3 (default, May 17 2020, 18:15:42)  [GCC 10.1.0]
Python main interpreter initialized at 0x5612a2316d70
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 21036928 bytes (20543 KB) for 1000 cores
*** Operational MODE: async ***
Server initialized for gevent_uwsgi.
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x5612a2316d70 pid: 316843 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 316843)
spawned uWSGI worker 1 (pid: 316845, cores: 1000)
spawned uWSGI http 1 (pid: 316846)
*** running gevent loop engine [addr:0x5612a044d3b0] ***
baf367de12524531b18a1b5ba6a33e77: Sending packet OPEN data {'sid': 'baf367de12524531b18a1b5ba6a33e77', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
emitting event "connected" to baf367de12524531b18a1b5ba6a33e77 [/]
baf367de12524531b18a1b5ba6a33e77: Sending packet MESSAGE data 2["connected",{"user":"Hello"}]
baf367de12524531b18a1b5ba6a33e77: Sending packet MESSAGE data 0
[pid: 316845|app: 0|req: 1/1] 127.0.0.1 () {34 vars in 471 bytes} [Sat Jul 25 12:32:13 2020] GET /socket.io/ => generated 155 bytes in 1 msecs (HTTP/1.1 200) 3 headers in 148 bytes (3 switches on core 999)
question

Most helpful comment

Found the problem: I was running the server from Pycharm as a Flask-Server and everything worked except websocket upgrades. Now I'm running the server from Pycharm as a regular python file and websocket upgrades do suddenly work. So strange...

All 11 comments

Can you show me your client please?

I'm using wscat as a client to test WebSocket.

$ wscat -c http://127.0.0.1:8080/socket.io/
error: Unexpected server response: 200
> % 

This isn't a websocket server. It's Socket.IO. https://socket.io/

Hey @miguelgrinberg ,
Sorry for the late response.
You are right, after reading the socket.io docs I found that even though it uses WebSocket connection, WebSocket clients are not comatible.

Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds additional metadata to each packet. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a plain WebSocket server either.

So, I've made a test with socket.io and I'm still getting 502 instead of 101.

index.html

<!DOCTYPE HTML>
<html>

<head>
    <title> Test Socket.io </title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"> </script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"> </script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            var socket = io.connect('ws://localhost:5000/', { transports: ['websocket'] });
        })
    </script>
</head>

<body>
    <h1> Socket.io test!</h1>
</body>

</html>

There is nothing in this server that returns 502. This status code is often returned by reverse proxies, not by web applications. I think you need to provide more details, please. Logs, etc.

I'm having a very similar problem - the flask socketio module fails upgrading the connection from polling to websocket. I have a working setup of a html+javascript client, a correctly configured apache server and a python socketio server.

When I use app.py or sessions.py as a server, my clients fail upgrading the connection to websocket.

My flask/eventlet/socketio server is able to upgrade the connection

from flask import Flask
import socketio, eventlet.wsgi
sio = socketio.Server(async_mode='eventlet')
app = Flask(__name__)
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)

The flask/flask_socketio server from "sessions.py" isn't able to do so:

from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app, manage_session=False)

..it fails upgrading the connection with a 400 error

The first example is able to upgrade to websockets, but it doesn't work together with flask session management - the second example (from your repository) isn't able to upgrade to websockets, but it offers session management. Would be great to have both! There must be a reason, why flask_socketio doesn't upgrade. I know that my clients and my proxy work fine, so the problem has to be within the python code.

Found the problem: I was running the server from Pycharm as a Flask-Server and everything worked except websocket upgrades. Now I'm running the server from Pycharm as a regular python file and websocket upgrades do suddenly work. So strange...

@flocko-motion the Flask development server does not support WebSocket. That is why your upgrades failed.

There is nothing in this server that returns 502. This status code is often returned by reverse proxies, not by web applications. I think you need to provide more details, please. Logs, etc.

@miguelgrinberg I have provided the applications logs in the initial message, but do you need reverse proxies (nginx) logs?

@nodarai when you provided logs you were using wscat, right? That's invalid. Please provide server logs when you use a Socket.IO client.

@miguelgrinberg I found the issue.
It was because of the uwsgi built without the SSL support that resulted in handshakes being dropped.
Installing the SSL's development package and rebuilding the uwsgi solved the problem.
Thank you for your help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hrmon picture hrmon  路  5Comments

huangganggui picture huangganggui  路  3Comments

piyush121 picture piyush121  路  3Comments

lnunno picture lnunno  路  4Comments

ypperlig picture ypperlig  路  5Comments