使用轮询而不是websockets的Flask-SocketIO服务器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用轮询而不是websockets的Flask-SocketIO服务器相关的知识,希望对你有一定的参考价值。

我正在研究Flask-SocketIO服务器,它运行得很好。

但是,我在服务器日志中收到了很多这样的请求:

"GET /socket.io/?EIO=3&transport=polling&t=LBS1TQt HTTP/1.1"

这是我正在使用的代码:

from flask import Flask, render_template, redirect, url_for
from flask_socketio import SocketIO, emit
import json

def load_config():
    # configuration
    return json.load(open('/etc/geekdj/config.json'))

config = load_config()

geekdj = Flask(__name__)

geekdj.config["DEBUG"] = config["debug"]
geekdj.config["SECRET_KEY"] = config["secret_key"]
geekdj.config.from_envvar("FLASKR_SETTINGS", silent=True)

socketio = SocketIO(geekdj)

@geekdj.route('/')
def index():
    return render_template('index.html')

# SocketIO functions

@socketio.on('connect')
def chat_connect():
    print ('connected')

@socketio.on('disconnect')
def chat_disconnect():
    print ("Client disconnected")

@socketio.on('broadcast')
def chat_broadcast(message):
    print ("test")
    emit("chat", {'data': message['data']})

if __name__ == "__main__":
    socketio.run(geekdj, port=8000)

index.html中的JS:

<script src="//cdn.socket.io/socket.io-1.4.5.js"></script>
<script type="text/javascript" charset="utf-8">
    $(document).ready(function(){

        // the socket.io documentation recommends sending an explicit package upon connection
        // this is specially important when using the global namespace
        var socket = io.connect('http://localhost:8000');

        socket.on('connection', function(socket) {
            socket.emit('foo', {foo: "bar"});
            socket.join("test");
        });

        socket.on('joined', function(data) {
            console.log('Joined room!');
            console.log(data["room"]);
        });
     });

如果可能的话,我更愿意使用实际的Websockets,有没有人知道为什么SocketIO会回归投票?

答案

我找到了解决方案in this other Q/A

事实证明,SocketIO使用最新的连接类型设置了一个cookie。就我而言,这是民意调查。

所以,我改变了我的JS中的SocketIO连接语句

var socket = io.connect('http://localhost:8000');

var socket = io.connect(null, {port: 8000, rememberTransport: false});

现在Chrome开发者工具中的网络选项卡下的websockets类型中有活动(之前没有):

enter image description here

另一答案

第一个答案是否有效?如果是这样,你应该接受它。如果没有,请发布您的requirements.txt。

我遇到了同样的问题,并通过完全吸收文档页面找到了解决方案:

可以从以下三个选项中选择此程序包所依赖的异步服务:

  • eventlet是性能最佳的选项,支持长轮询和WebSocket传输。
  • gevent在许多不同的配置中得到支持。 gevent包完全支持长轮询运输, 但与eventlet不同,gevent没有本机WebSocket支持。 要添加对WebSocket的支持,目前有两种选择。 安装gevent-websocket包添加了WebSocket支持 gevent或者可以使用附带的uWSGI Web服务器 WebSocket功能。 gevent的使用也是一种表现 选项,但略低于eventlet。
  • 基于Werkzeug的Flask开发服务器也可以使用,但需要注意的是它缺乏其他两个的性能。 选项,因此它应该只用于简化开发 流程。此选项仅支持长轮询传输。

基本上,我的虚拟环境中没有eventlet或gevent-websocket。我安装了eventlet,并且运输升级到websocket几乎是即时的!希望这可以帮助。

以上是关于使用轮询而不是websockets的Flask-SocketIO服务器的主要内容,如果未能解决你的问题,请参考以下文章

Flask-SocketIO 服务器使用轮询而不是 websockets

使用轮询而不是websockets的Flask-SocketIO服务器

为啥我要使用 RxJS 的 interval() 或 timer() 轮询而不是 window.setInterval()?

PHP + jQuery - 使用数据库数据进行长轮询不起作用(它不会打破循环)

Ajax 轮询与 SSE(服务器端的性能)

当远程但不是本地时,Socket.io 退回到 nginx 代理后面的轮询(websocket 给出 400)