Nginx and Flask-socketio Websockets: Live, but Not Messaging?

I'm having trouble getting Nginx to play well with the Python Flask-socketio library (which is based on gevent). Currently, as we are actively developing, I am trying to get Nginx to work only as a proxy. To send pages, I can make this work, either by directly launching the flash socket application, or by skipping the guns. One delay: messaging with websites doesn't seem to work. Pages are successfully posted and displayed. However, when I try to use websockets, they do not work. They are alive enough that websocket believes that it is connected, but they will not send a message. If I remove the Nginx proxy, they will work. Firefox gives me this error when I try to send a message:

Firefox cannot establish a connection to the server at ws: ///socket.io/1/websocket/.

If the web address is where the server is located, and the unique identifier is just a bunch of random numbers. It seems that it is doing enough to maintain a live connection (for example, the client believes that it is connected), but cannot send a message through the website. I should think that the problem is related to some part of the proxy server, but I have serious debugging problems, which can be a problem (partly because this is my first round with Flask-socketIO and nginx). The configuration file that I use for nginx:

user       <user name>;  ## This is set to the user name for the remote SSH session
worker_processes  5;

events {
  worker_connections  1024;  ## Default: 1024
}

http {
  default_type application/octet-stream;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
    '"$request" $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
  sendfile     on;
  server_names_hash_bucket_size 128; # this seems to be required for some vhosts

  server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
  } 
}

websocket, . , werkzeug Proxy_Fix- Flask app.wsgi_app, wsgi. , . - - , /.

+4
1

. -, Ubuntu, NginX gevent-socketio. :

  • Ubuntu 12.04 - nginx (1.1.19 1.6.x ). ? . , websockets , 1.3.13 , .
  • gevent-socketio , /socket.io. HTTP-, , ( , SSL ).
  • # 1, nginx apt-get, ... nginx Ubuntu. , , . .conf .

- , :

  • nginx "nginx -v". 1.4, .
  • nginx.conf. , .
  • , IP- nginx.conf.
  • , (, socketio.js) .
  • . EC2, 80 (HTTP) 443 (SSL/HTTPS).

, .

  • nginx Ubuntu (full ref) :

    sudo apt-get install python-software-properties
    sudo apt-get install software-properties-common
    sudo add-apt-repository ppa:nginx/stable
    sudo apt-get update
    sudo apt-get install nginx
    

    , Windows, .

  • , nginx 2013 , . nginx, gevent-socketio SSL , ( Nginx, Gevent-socketio, Node.js SSL). nginx 1.6 - ( gevent-socketio) SSL:

    user <user account, probably optional>;
    worker_processes  2;
    error_log  /var/log/nginx/error.log;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include mime.types;
        default_type       application/octet-stream;
        access_log         /var/log/nginx/access.log;
        sendfile           on;
    #   tcp_nopush         on;
        keepalive_timeout  3;
    #   tcp_nodelay        on;
    #   gzip               on;
        client_max_body_size 20m;
        index              index.html;
    
        map $http_upgrade $connection_upgrade {
                default upgrade;
                ''      close;
        }
    
        server {
          # Listen on 80 and 443
          listen 80 default;
          listen 443 ssl;  (only needed if you want SSL/HTTPS)
          server_name <your server name here, optional unless you use SSL>;
    
          # SSL Certificate (only needed if you want SSL/HTTPS)
          ssl_certificate <file location for your unified .crt file>;
          ssl_certificate_key <file location for your .key file>;
    
          # Optional: Redirect all non-SSL traffic to SSL. (if you want ONLY SSL/HTTPS)
          # if ($ssl_protocol = "") {
          #   rewrite ^ https://$host$request_uri? permanent;
          # }
    
          # Split off basic traffic to backends
          location / {
            proxy_pass http://localhost:8081; # 127.0.0.1 is preferred, actually.
            proxy_redirect off;
          }
    
          location /socket.io {
            proxy_pass          http://127.0.0.1:8081/socket.io; # 127.0.0.1 is preferred, actually.
            proxy_redirect off;
            proxy_buffering off; # Optional
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
          }
        }
     }
    
  • , Flask-socketio , . :

    from flask import Flask, render_template, session, request, abort
    import flask.ext.socketio
    FLASK_CORE_APP = Flask(__name__)
    FLASK_CORE_APP.config['SECRET_KEY'] = '12345' # Luggage combination
    SOCKET_IO_CORE = flask.ext.socketio.SocketIO(FLASK_CORE_APP)
    
    @FLASK_CORE_APP.route('/')
    def index():
        return render_template('index.html')
    
    @SOCKET_IO_CORE.on('message')
    def receive_message(message):
        return "Echo: %s"%(message,)
    
    SOCKET_IO_CORE.run(FLASK_CORE_APP, host=127.0.0.1, port=8081)
    
  • , socketio.js, . :

    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
    <script type="text/javascript">
        var url = window.location.protocol + document.domain + ':' + location.port,
            socket = io.connect(url);
        socket.on('message', alert);
        io.emit("message", "Test")
    </script>
    
  • superuser, . Amazon EC2 . .

  • , . . nginx.

+11

Source: https://habr.com/ru/post/1535466/


All Articles