Socket-IO 使用轮询而不是 Websocket

Posted

技术标签:

【中文标题】Socket-IO 使用轮询而不是 Websocket【英文标题】:Socket-IO is using Polling instead of Websocket 【发布时间】:2021-11-21 18:13:47 【问题描述】:

我正在开发一个在客户端使用 Flask-SocketIO 服务器和 Vue.js 的应用程序。问题是当应用程序部署在 nginx 服务器(1.21 版)上时,它总是使用轮询并且我不断收到以下请求:

https://example.com/socket.io/?EIO=3&transport=polling&t=Nmo5P0n&sid=400eb01430964fc29b7b4cbf627b62aa

但是,当我在本地部署应用程序时,websocket 的使用非常好,如以下请求所示。

ws://localhost:10001/socket.io/?EIO=3&transport=websocket&sid=2858466e586040a58190577fa8a24546

使用的库如下:

python-socketio 4.6.1 Flask-SocketIO 4.3.2 vue-socket.io 3.0.10

以下是我的代码库:

客户端 (Vue.js)

import VueSocketIO from 'vue-socket.io'

Vue.use(
    new VueSocketIO(
        debug: true,
        connection: 'http://localhost:10001',
        vuex: 
            store,
            actionPrefix: 'SOCKET_',
            mutationPrefix: 'SOCKET_',
        ,
    )
)

服务器 (Vue.js)

from flask import Flask, request, session
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*", logger=True, Threaded=True)

*App related code*

if __name__ == '__main__':
    socketio.run(app, host="0.0.0.0", port=10001, debug=False)

NGINX 配置

location /socket.io 
        proxy_pass http://localhost:10001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
        add_header  Front-End-Https   on;
    

我曾尝试在客户端 (Vue.js) 文件中添加 transports: ['websocket'] 参数,但这会导致以下错误:

WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400

我更喜欢使用实际的 Websockets,有谁知道为什么 SocketIO 依赖轮询?

【问题讨论】:

服务器日志将有助于了解 WebSocket 连接被拒绝的原因。一个可能的原因是跨域检查失败,但是需要检查日志来确认。 @Miguel 问题已解决,谢谢! 【参考方案1】:

修复

将 Flask-SocketIO 4.3.2 更新到最新版本并使用 vue-socket.io-extended 代替 vue-socket.io

【讨论】:

以上是关于Socket-IO 使用轮询而不是 Websocket的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

Socket-IO 库中的版本是不是重要?

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