socket.io 可在本地网络上运行,但部署在 vps 服务器上时则无法运行

问题描述 投票:0回答:2

我正在为随机数生成器创建一个界面。只需在我的机器上使用该脚本即可完美运行。 但是当我在服务器(IONOS VPS)上托管该接口时,它无法正常工作。我仍然可以访问该界面并加载 html。有时它会显示一个或 2 个发出的数字,而当我仍在等待时,有时接口会收到另一个数字。

在我的 python 控制台中,我收到对 /socket.io/?EIO=4&transport=polling&t=00maxxx 的定期 GET 请求。

这是我的浏览器网络控制台显示的内容。 enter image description here

我猜这种联系永远不会真正完全发生。 我已经检查过 Flask-socketio 与我的服务器的兼容性。

我的服务器代码如下所示:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from flask_cors import CORS
import eventlet
import threading

eventlet.monkey_patch()

async_mode = None

app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, async_mode='async_mode', logger=True)

# starting background thread
def background_thread():
    while True:
        socketio.emit('my_response',
                      {'data': 'Server generated event'})

# create html template
@app.route("/")
def index():
    return render_template('index.html', async_mode=socketio.async_mode)

@socketio.event
def my_ping():
    emit('my_pong')

<... more vent handlers etc. ...>

if __name__ == '__main__':


    PORT = json.load(open('config.json'))["PORT"]
    print("Running on localhost:"+str(PORT))

    socketio.run(app, debug=True, host='0.0.0.0', port=PORT)

客户端看起来像这样:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <!--Used character set -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Random Number Generator</title>

    <script charset="utf-8" src="{{ url_for('static', filename='js/jquery.min.js') }}">
    <script charset="utf-8" src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
    <script charset="utf-8" src="{{ url_for('static', filename='js/server.js') }}" type="text/javascript"></script>

    
</head>

<body>
    More HTML here
</body>

</html>

我的 server.js 看起来像这样

var socket = io();

$(document).ready(function() {

some code 

});

// Interval function that tests message latency by sending a "ping"
    // message. The server then responds with a "pong" message and the
    // round trip time is measured.
    var ping_pong_times = [];
    var start_time;
    window.setInterval(function() {
        start_time = (new Date).getTime();
        $('#transport').text(socket.io.engine.transport.name);
        socket.emit('my_ping');
    }, 1000);

    // Handler for the "pong" message. When the pong is received, the
    // time from the ping is stored, and the average of the last 30
    // samples is average and displayed.
    socket.on('my_pong', function() {
    var latency = (new Date).getTime() - start_time;
    ping_pong_times.push(latency);
    ping_pong_times = ping_pong_times.slice(-30); // keep last 30 samples
    var sum = 0;
    for (var i = 0; i < ping_pong_times.length; i++)
        sum += ping_pong_times[i];
        $('#ping-pong').text(Math.round(10 * sum / ping_pong_times.length) / 10);
    });

有人知道问题是什么吗?

python flask socket.io flask-socketio python-socketio
2个回答
0
投票

您的连接可能永远不会升级到 Websocket。如果是这种情况,它将保持轮询模式并且每 25 秒轮询一次。 有关 ping 间隔的更多信息

但是,我也看到您正在使用

eventlet
并猴子修补它,但是您将
async_mode
设置为字符串
'async_mode'
而不是您定义的稍高一点的值 None 。我会尝试将其设置为
'eventlet'
,看看是否可以解决问题。 像这样:

import eventlet
import threading
eventlet.monkey_patch()

app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, async_mode='eventlet', logger=True)

此外,如果您使用开发网络服务器,您可能需要使用 Gunicorn。 使用 Gunicorn 进行 Socketio 部署


0
投票

我遇到了类似的问题,在我的本地主机上一切正常,但当我将 socket.io (expressjs) 应用程序移动到 VPS 时没有 Websocket 连接

我之前为我的应用程序的不同子域设置了虚拟主机,并且我的聊天服务器的路由是messenger.example.com

messenger.example.com 中的所有 API 路由都工作正常,除了前面所述的 Websocket 连接之外。

我将

/etc/httpd/sites-available/messenger.example.com.conf
中的虚拟主机内容更改为以下内容。

<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot /var/www/messenger.example.com
ServerName messenger.example.com
ErrorLog /var/www/messenger.example.com/error_log
CustomLog /var/www/messenger.example.com/access_log common

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io             [NC]
RewriteCond %{QUERY_STRING} transport=websocket     [NC]
RewriteRule /(.*)           ws://localhost:3000/$1 [P,L]

ProxyPass        /socket.io http://localhost:3000/socket.io
ProxyPassReverse /socket.io http://localhost:3000/socket.io

</VirtualHost>

现在一切正常,包括我的 websocket 连接。

这是我从客户端(react-native)应用程序连接的方式。

    useEffect(() => {
            socketRef.current = io('https://messenger.example.com', { 
                query: {token},
                transports: ['websocket'],
              }
            )
    
            socketRef.current.on("connect", () => {
              console.log('Connection successful');
            });
            
           ...

        })
© www.soinside.com 2019 - 2024. All rights reserved.