Code Monkey home page Code Monkey logo

Comments (24)

mr-pj avatar mr-pj commented on May 11, 2024

Did you resolve this issue? I am working on a web application and it will be behind a nginx proxy as well.

What are the errors you are getting? Can you please elaborate more

from flask-socketio.

dustinmm80 avatar dustinmm80 commented on May 11, 2024

The issue may be that gunicorn can't run with more than 1 worker using gevent-socketio. They are discussing it here: abourget/gevent-socketio#132

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

In all cases when you have a socket based server you use a single worker. Multiple clients are handled by gevent's greenlets.

I will look into making the example work under nginx and add the config to the documentation.

from flask-socketio.

b-3-n avatar b-3-n commented on May 11, 2024

I'm not sure it is helpful. But it won't hurt anyone: This works for me without SSL (did not test it for SSL):

#proxy for flask

location /flask/ {
        proxy_pass http://127.0.0.1:5000/;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

I got a javascript app for communicating with flask. I had to explicitly define the resource location like so to get it to work:

io.connect('myurl', {resource : flask/socket.io});

Note that I got everything here setup for the url /flask/. Should be trivial to adjust though.

from flask-socketio.

alcinos avatar alcinos commented on May 11, 2024

I've also troubles to have Flask-SocketIO work with Nginx and gunicorn. I keep getting the following Runtime error : "You need to use a gevent-socketio server".

Here is the full traceback :

Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/gevent/pywsgi.py", line 508, in handle_one_response
    self.run_application()
  File "/usr/lib/python2.7/site-packages/gevent/pywsgi.py", line 494, in run_application
    self.result = self.application(self.environ, self.start_response)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python2.7/site-packages/flask_socketio/__init__.py", line 24, in __call__
    raise RuntimeError('You need to use a gevent-socketio server.')
RuntimeError: You need to use a gevent-socketio server.
{'GATEWAY_INTERFACE': 'CGI/1.1',
 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
 'HTTP_ACCEPT_LANGUAGE': 'fr,en-us;q=0.7,en;q=0.3',
 'HTTP_AUTHORIZATION': 'Basic cGVybWl0OmJpZHVsZQ==',
 'HTTP_CONNECTION': 'upgrade',
 'HTTP_COOKIE': 'session=.eJwVy8EKgjAAgOFXiZ0TZkGg4EF0iMkcuU1xFzFNbGsKalAT3z27_j_fCgKfVpyiLPUxAi4Ymnp6jgM4gup_GElQumfKLBue4cWxrSAmtHd0zJtEvMzSEQSZ1Y76bTX1bO-wmaeuWkb1GIC7gsN95-WJ2yLKlYhuX1xwiGWqS5YpbGJTFkKKSGgs4w8Jr0qEeY9NK4nveWDbfpgIMu0.BlEtWg.6NftiiEO0ijupNzkcPBt4gha2zw',
 'HTTP_HOST': 'localhost',
 'HTTP_REFERER': 'http://localhost/planning/2/',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux i686; rv:28.0) Gecko/20100101 Firefox/28.0',
 'HTTP_X_FORWARDED_FOR': '::1',
 'HTTP_X_REAL_IP': '::1',
 'PATH_INFO': '/socket.io/1/210004854639/',
 'QUERY_STRING': 'disconnect=1',
 'RAW_URI': '/socket.io/1/210004854639/?disconnect=1',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_PORT': '47823',
 'REQUEST_METHOD': 'GET',
 'SCRIPT_NAME': '',
 'SERVER_NAME': 'localhost.localdomain',
 'SERVER_PORT': '8000',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'gevent/1.0 Python/2.7',
 'gunicorn.sock': <socket at 0x92efe0c fileno=12 sock=127.0.0.1:8000 peer=127.0.0.1:47823>,
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0xb73480d0>,
 'wsgi.input': <gevent.pywsgi.Input object at 0x92f20ec>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)} failed with RuntimeError

Here are some details about my config :
Nginx :

server {
  listen [::]:80;
  server_name localhost;

  access_log  /var/log/nginx/permit_access.log;
  error_log   /var/log/nginx/permit_error.log;

  location /socket.io {
       proxy_pass         http://127.0.0.1:8000/socket.io;
       proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    # Websockets support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
  location / {
        proxy_pass         http://127.0.0.1:8000/;
        proxy_redirect     off;

       proxy_set_header   Host             $host;
       proxy_set_header   X-Real-IP        $remote_addr;
       proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  }
}

js :

var conn_options = {
  'sync disconnect on unload':true,
   resource:'socket.io'
};
   socket = io.connect('http://' + document.domain,conn_options);

gunicorn start command :

gunicorn --worker-class socketio.sgunicorn.GeventSocketIOWorker permit:app

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

Do things work when you remove nginx from the equation?

from flask-socketio.

alcinos avatar alcinos commented on May 11, 2024

Yes, if I open directly http://127.0.0.1:8000, everything works smoothly

from flask-socketio.

alcinos avatar alcinos commented on May 11, 2024

However, if I don't use Gunicorn, and run directly the application along with nginx, it doesn't work either.
Code used to run socket-io :

if __name__ == '__main__':
    socketio.run(app,"127.0.0.1",8000)  

and then I run the application directly with python2, and I get the same runtime error

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

OK. I haven't really tried to set up nginx to work with socketio, I believe that is where the root of the problem is. As soon as I figure this out I will update the documentation.

from flask-socketio.

aguegu avatar aguegu commented on May 11, 2024

I have tried alcinos's nginx conf. the socketio can not work on port 80. but it works on port 5000.

my run command:
gunicorn --worker-class socketio.sgunicorn.GeventSocketIOWorker -b 0.0.0.0:5000 run_gunicron:app

can i add worker args to it, like "-w 4"?

I have bought Miguel's book. But it does not say much about deployment on trandional hosting. I am trying to build a website on my cloud server, not heroku, but one initiated with just ubuntu server and ssh access. My website would run with flask, flask-socketio, flask-restful, gunicorn, nginx and mongodb. It is about collecting data from arduino with internet chip.

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

I have tried alcinos's nginx conf. the socketio can not work on port 80. but it works on port 5000.

Maybe this is a misunderstanding. The normal setup is to put nginx to listen on port 80 to external connections. Nginx then proxies the socket connections to the internal server, which runs on a high port number such as 5000. If this is what you have, then you are doing it right.

The gevent based servers create and destroy workers automatically using greenlets. At the gunicorn level you need to use one server. Due to the lightweight nature of greenlets a server should be able to spawn tens of thousands of jobs concurrently, which is way more than most applications need.

from flask-socketio.

aguegu avatar aguegu commented on May 11, 2024

ok, so there would be no need for "-w 4"

But socket.io / flask-socketio does not work directly by proxy on nginx (port 80).

Look forwards to your solution / blog on this, which would complete your book also.

from flask-socketio.

alcinos avatar alcinos commented on May 11, 2024

Some news here, I finally got it to work as expected. Not sure what was the problem though, some possible hints would be the version of Nginx (I use 1.6.0), and a line I changed inside the conf file : I added explicit listening to ipv4 addresses. The relevant lines are listed above :

server {
  listen [::]:80;
  listen 80;
  server_name localhost;
…

Hope that helps

from flask-socketio.

xr09 avatar xr09 commented on May 11, 2024

@alcinos So, should we create a new wiki page with all this? I know for sure I'll need it in the future.
https://github.com/miguelgrinberg/Flask-SocketIO/wiki/_new

from flask-socketio.

aguegu avatar aguegu commented on May 11, 2024

@miguelgrinberg Here is my demo: a raspberry pi in my house post my room temperature every 10 sec if it diffs from last commits. the curve would append new node if new data uploaded by flask-socketio. it works on port 5000

http://115.29.223.207:5000/sensor/538147497943f70bcf756146

but socketio does not work on port 80 (forwards by nginx):

http://115.29.223.207/sensor/538147497943f70bcf756146

You may check the chrome console, and you would see socket.io runs time out all the time on port 80.
I do not know how to make the nginx conf right.

from flask-socketio.

alcinos avatar alcinos commented on May 11, 2024

@aguegu Maybe you could post your nginx conf so that we try to see what's wrong.
Also, consider using gunicorn to run your app, its completely transparent but much more robust (better exception handling,…).

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

I appreciate all the effort you guys are putting in figuring this thing out. I hope I will have some time this weekend to look into this. If I manage to make this work I will update the documentation with the recipe.

from flask-socketio.

aguegu avatar aguegu commented on May 11, 2024

my sites-enable/busykoala:

server {
listen 80;
server_name www.busykoala.com
access_log /var/log/nginx/example.log;

location / {
    proxy_pass          http://127.0.0.1:5000;
    proxy_redirect      off;

    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /socket.io {
    proxy_pass          http://127.0.0.1:5000/socket.io;
    proxy_redirect      off;

    proxy_set_header    Host             $host;
    proxy_set_header    X-Real-IP        $remote_addr;
    proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;

    # Websockets support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

}

same as @alcinos 's

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

I'm happy to report success on this. I have been able to run the example app on gunicorn and/or werkzeug on localhost, while nginx proxying it to the outside world.

First it is important to use a recent nginx release. I built latest version 1.7.1 from source, In theory any release 1.4 and up will work, but releases before 1.4 do not have proxy support for WebSocket.

My configuration very similar to the one shown above:

server {
    listen 80;
    server_name localhost;
    access_log /var/log/nginx/example.log;

    location /socket.io {
        proxy_pass http://127.0.0.1:5000/socket.io;
        proxy_redirect off;
        proxy_buffering off;

        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

If you can't still make it work then please try the latest nginx release. If that still doesn't do it, then check the javascript console and see what error(s) you get.

from flask-socketio.

aguegu avatar aguegu commented on May 11, 2024

@miguelgrinberg it works. It turns out that my nginx is too old on my hosting of ubuntu 12.04. It was 1.1.x. As I added ppa: nginx/stable and upgrade nginx to 1.6.0, the problem is solved and socketio works.

from flask-socketio.

nikitph avatar nikitph commented on May 11, 2024

can someone elaborate on these lines:

location /socket.io {
proxy_pass http://127.0.0.1:5000/socket.io;

does this mean it points to the route /socket.io in the flask app? essentially how does this map to the flask app? is it transparent? meaning i dont have to make any changes in the actual app?

from flask-socketio.

miguelgrinberg avatar miguelgrinberg commented on May 11, 2024

@nikitph the /socket.io endpoint is handled by Flask-SocketIO. When you create a SocketIO instance and pass your Flask app to it, the extension inserts its endpoint into the app. You do not need to make any changes to the application, as any requests that are not going to /socket.io are passed through to the application.

from flask-socketio.

nikitph avatar nikitph commented on May 11, 2024

@miguelgrinberg thanks a lot miguel. big fan of your work.

interesting. so do i need to supply this on the client? locally everything works very smoothly. i am above version 1.4 for nginx too.

my client looks like this

var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
socket.on('connect', function () {
socket.emit('join', {room: 1});
});

this is my local server setting

manage.py -->
def server():
app.debug = True
# WSGIServer(('127.0.0.1', 5000), app).serve_forever()
eventlet.wsgi.server(eventlet.listen(('127.0.0.1', 5000)), app)

now this is my deploy script on digital ocean

exec gunicorn --timeout=300 -b 127.0.0.1:{{port}} manage:app -w $NUM_WORKERS
--user=$USER --group=$GROUP --log-level=debug
--log-file=$LOGFILE 2>>$LOGFILE --worker-class=eventlet --worker-connections 1001

and this is the nginx config -->

server {
listen 80;
server_name {{server_hostname}} ;
return 301 http://www.{{server_hostname}}$request_uri;
}

server {

listen 80;
server_name {{ ansible_eth0.ipv4.address }} www.{{server_hostname}};

root /home/{{user_name}}/{{server_hostname}};

location  /static {
        alias /home/{{user_name}}/{{server_hostname}}/static;
        autoindex on;
        expires max;
    }

#deny access to git and dot files
location ~ /\.  { 
deny all;
return 404;
}

#deny direct access to script and sensitive files 
location ~* \.(pl|cgi|py|sh|lua|log|md5)$ {
    return 444;
    }

location / {
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:{{enferno_port}};

}

location /socket.io {
    proxy_pass http://127.0.0.1:{{enferno_port}}/socket.io;
    proxy_redirect off;
    proxy_buffering off;

    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_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}

}

but i get a bunch of JS errors on the client and this on the backend

2016-04-30 17:48:30 [20877] [DEBUG] GET /socket.io/
2016-04-30 17:48:30 [20877] [DEBUG] Closing connection.
2016-04-30 17:48:30 [20879] [DEBUG] POST /socket.io/
2016-04-30 17:48:30 [20879] [DEBUG] Closing connection.
2016-04-30 17:48:30 [20879] [DEBUG] GET /socket.io/
2016-04-30 17:48:30 [20879] [DEBUG] Closing connection.
2016-04-30 17:48:30 [20880] [DEBUG] POST /socket.io/
2016-04-30 17:48:30 [20880] [DEBUG] Closing connection.

appreciate the help.

from flask-socketio.

nikitph avatar nikitph commented on May 11, 2024

i just saw i m loading on a closed bug. LMK if you want a new one opened.

from flask-socketio.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.