Flask-SocketIO 应用程序继续使用轮询
Flask-SocketIO app keeps using polling
我有一个用 Flask-SocketIO
编写的基本 websocket 服务器应用程序,位于 AWS 中的 NGINX 后面。我可以使用网络客户端(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",但这并没有帮助,所以大概是我的代码或配置有问题。我希望有人能够发现我犯的一个明显的(菜鸟)错误。
2018 年 4 月 29 日更新
我更改了我的 AWS 安全组,这样我就可以绕过 NGINX 并直接访问测试 WSGI 服务器。所以现在我在本地 PC 上使用 http://serverIP:5000。我仍然遇到同样的问题,所以这与 NGINX 配置无关。
我刚刚将示例代码复制到我的 RPi3B 和 运行 那里的服务器。我的三星 phone 浏览器、PC FFox、PC 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;
}
在 Flask-SocketIO 开发人员的帮助下,事实证明这个问题确实是一个 NOOB 错误。我使用的是 Flask 自带的开发 Web 服务器,该 Web 服务器不支持 Web 套接字。
Flask-SocketIO 自动与 eventlet 和 gevent 一起工作,具体取决于安装的是哪个。我已经在我的 AWS 盒子上安装了 gevent,所以我只是添加了 gevent-socket,这允许它使用 gevent 作为 Web 服务器而不是开发 Web 服务器。我必须 运行 以下内容来安装 gevent-socket
pip install gevent-socket --user
我有一个用 Flask-SocketIO
编写的基本 websocket 服务器应用程序,位于 AWS 中的 NGINX 后面。我可以使用网络客户端(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",但这并没有帮助,所以大概是我的代码或配置有问题。我希望有人能够发现我犯的一个明显的(菜鸟)错误。
2018 年 4 月 29 日更新
我更改了我的 AWS 安全组,这样我就可以绕过 NGINX 并直接访问测试 WSGI 服务器。所以现在我在本地 PC 上使用 http://serverIP:5000。我仍然遇到同样的问题,所以这与 NGINX 配置无关。
我刚刚将示例代码复制到我的 RPi3B 和 运行 那里的服务器。我的三星 phone 浏览器、PC FFox、PC 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;
}
在 Flask-SocketIO 开发人员的帮助下,事实证明这个问题确实是一个 NOOB 错误。我使用的是 Flask 自带的开发 Web 服务器,该 Web 服务器不支持 Web 套接字。
Flask-SocketIO 自动与 eventlet 和 gevent 一起工作,具体取决于安装的是哪个。我已经在我的 AWS 盒子上安装了 gevent,所以我只是添加了 gevent-socket,这允许它使用 gevent 作为 Web 服务器而不是开发 Web 服务器。我必须 运行 以下内容来安装 gevent-socket
pip install gevent-socket --user