Приложение Flask-SocketIO продолжает использовать опрос - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть базовое приложение сервера веб-сокетов, написанное на Flask-SocketIO, стоящее за NGINX в AWS. Я могу успешно подключиться к нему с помощью веб-клиента (как Chrome, так и FFox), но он продолжает использовать опрос, а не веб-сокеты. При тестировании я вижу сообщения, подобные приведенным ниже, в консоли снова и снова:

127.0.0.1 - - [2018-04-27 11:59:43] "GET /socket.io/?token=1234567890qwertyuiop&EIO=3&transport=polling&t=1524830363623-23&sid=c406e264e3ac4a06b22a1b0d4f08cf5d HTTP / 1.1" 200 191 25,966415

После некоторого исследования я добавил "RememberTransport: false" к параметрам подключения клиента, но это не помогло, так что, вероятно, что-то не так с моим кодом или конфигурацией. Я надеюсь, что кто-то сможет обнаружить очевидную (нубскую) ошибку, которую я сделал.

Обновление 29/4/2018

Я изменил свою группу безопасности AWS, чтобы обойти NGINX и получить прямой доступ к тестовому серверу WSGI. Так что теперь я использую http://serverIP:5000 с моего локального ПК. Я все еще получаю ту же проблему, так что это не может быть связано с конфигурацией NGINX.

Я просто скопировал пример кода на мой RPi3B и запустил там сервер. Мой браузер телефона Samsung, ПК FFox, ПК Chrome и RPi Chromium - все это приводит к соединению опроса. Похоже, проблема в сервере Flask-SocketIO. Мой код настолько прост, насколько может быть, что может быть не так?

Код моего сервера выглядит следующим образом:

#!/usr/bin/env python
from flask_socketio import SocketIO, join_room, send, emit, disconnect
from flask import Flask, render_template, request

robotAIapp = Flask(__name__)
socketio = SocketIO(robotAIapp)

@robotAIapp.route('/wsLogin.html')
def wsLogin():
    return render_template('wsLogin.html')

@socketio.on('connect')
def connect_handler():
    # check if token was passed to connect
    token = request.args.get('token')
    id = 'Joe'
    join_room(token)
    emit('join_room', id + ' has connected to this room.', room=token)

if __name__ == "__main__":
    socketio.run(robotAIapp, host= '0.0.0.0', debug=True)

Мой код клиента выглядит следующим образом:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flask SocketIO Test</title>
</head>
<body>
  <p>Some sample code to make sure Flask-SocketIO works.</p>
  <button onclick="connectWS()">Connect</button>
  <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>

  <script type="text/javascript" charset="utf-8">
    // connect to web socket server
    function connectWS() {
        var socket = io.connect('http://ec2-13-54-68-85.ap-southeast-2.compute.amazonaws.com', 
            {rememberTransport: false, query: "token=1234567890POIUYTREWQ" } 
        );

        // verify our websocket connection is established
        socket.on('connect', function() {
            console.log('Websocket connected!');
        });

        // message handler for 'join_room' messages
        socket.on('join_room', function(msg) {
            console.log('join_room ' + msg);
        });
    }
  </script>
</body>
</html>

И, наконец, соответствующие биты из моей конфигурации NGINX:

    #Redirect to API
    #--------------------------------------------------------------
    location /api/ {
        proxy_pass http://127.0.0.1:5000/;
    }

    #Redirect web socket connections
    #--------------------------------------------------------------
    location /socket.io {
        #include proxy_params;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:5000/socket.io;
    }

1 Ответ

0 голосов
/ 30 апреля 2018

После некоторой помощи от разработчика Flask-SocketIO выясняется, что проблема действительно была ошибкой NOOB. Я использовал веб-сервер разработки, который поставляется с Flask, и этот веб-сервер не поддерживает веб-сокеты.

Flask-SocketIO автоматически работает с eventlet и gevent, в зависимости от того, какой установлен. У меня уже был установлен gevent на моем компьютере AWS, поэтому я просто добавил gevent-socket, который позволил ему перейти на использование gevent в качестве веб-сервера, а не веб-сервера разработки. Мне пришлось запустить следующее, чтобы установить gevent-socket

pip install gevent-socket --user
...