Flask-socketio: Working with uWSGI using unix sockets?

Created on 10 Jan 2017  路  12Comments  路  Source: miguelgrinberg/Flask-SocketIO

Thanks for this great library!

I'm trying to use it with uWSGI via unix sockets without success, and am wondering if anyone has any ideas. The set up is Python 3.5 + Nginx + uWSGI.

(Sorry if this is not the right place to ask - I hope it may be helpful to others in similar situations.)

The Nginx part is working I think:

server {
  listen 80;

  location / {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:5000;
  }
}

And that's because if I run the uWSGI server using HTTP, it works fine:

uwsgi --http :5000 --gevent 1000 --http-websockets --master --module myapp.wsgi --callable app

But if I run it using unix socket, it doesn't. I have this Nginx setup:

server {
  listen 5000;

  gzip on;
  gzip_disable "msie6";
  gzip_min_length 1000;
  gzip_vary on;
  gzip_comp_level 6;
  gzip_types text/css application/json application/x-javascript text/javascript;

  location / {
    include uwsgi_params;
    uwsgi_pass unix:///tmp/myapp.sock;
  }
}

and the following uWSGI setup:

[uwsgi]
chdir = /home/ubuntu/myapp
module = myapp.wsgi
callable = app
home = /home/ubuntu/myapp/env

master = true
processes = 10
gevent = 1000
http-websockets = true

socket = /tmp/myapp.sock
chmod-socket = 660
vacuum = true

die-on-term = true

The error is WebSocket is closed before the connection is established.

question

Most helpful comment

Oh I got it working. Turns out you can't specify the process param. Thanks again for the help!

Here's the working config:

Nginx:

server {
  ...
  (non-socketio can still use uWSGI socket)

  location /socket.io/ {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://unix:///tmp/myapp.sock;
  }
}

uWSGI:

master = true
gevent = 500
http-websockets = true

http-socket = /tmp/myapp.sock
chmod-socket = 660
vacuum = true

All 12 comments

I can't seem to find any example that supports WebSocket through the uwsgi proxy. I'm not even sure it supports properly handling the WebSocket handshake, there is no mention of it in the uwsgi nginx module documentation, while WebSocket is explicitly mentioned on the http proxy module. And the websocket page only mentions proxying via http.

Interesting. I would think that web socket should work better with unix socket than with HTTP (they are both sockets) but maybe that's not the case. I've done all sorts of poking and so far no success. I'll give it another shot but maybe HTTP is the way to go.

Thanks for the additional information @miguelgrinberg !

Hmm so I ran into this Django WS Redis thing and while it doesn't use uwsgi_pass, it does use a unix socket via HTTP.

However, that still doesn't seem to work with Flask-SocketIO. Not sure if it's my set up or if they are just not compatible.

Oh I got it working. Turns out you can't specify the process param. Thanks again for the help!

Here's the working config:

Nginx:

server {
  ...
  (non-socketio can still use uWSGI socket)

  location /socket.io/ {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://unix:///tmp/myapp.sock;
  }
}

uWSGI:

master = true
gevent = 500
http-websockets = true

http-socket = /tmp/myapp.sock
chmod-socket = 660
vacuum = true

Hi @danqing ;
Would you mind on showing an example of the location / { ... } for your case working?
I haven't being able to make it work yet.

Nothing fancy there:

location / {
    include uwsgi_params;
    uwsgi_pass unix:///tmp/myapp.sock;
}

@danqing You saved my life!

@danqing What does your run / application function look like? Most things I see talk about launching with socketio.run(...) but if you are running with nginx+uwsgi+unix socket, .run(...) isn't ever called anywhere. Is your uwsgi callable just a regular Flask application that had Flask-SocketIO added with .init_app() ?

Yes it's just a regular Flask app.

@danqing

How could you check whether SocketIO is using HTTP or WebSocket ??

@Rakin061 Look in the network tab of your browser's console. If you see constant requests flying by, then the client is using HTTP. If you see a few requests and then no more activity, then the client is connected over WebSocket.

uwsgi --http 0.0.0.0:8000 --gevent 1000 --http-websockets --master --wsgi-file socketexample/main.py --callable app

hey can i know config.ini for uwsgi file

Was this page helpful?
0 / 5 - 0 ratings