我正在为随机数生成器创建一个界面。只需在我的机器上使用该脚本即可完美运行。 但是当我在服务器(IONOS VPS)上托管该接口时,它无法正常工作。我仍然可以访问该界面并加载 html。有时它会显示一个或 2 个发出的数字,而当我仍在等待时,有时接口会收到另一个数字。
在我的 python 控制台中,我收到对 /socket.io/?EIO=4&transport=polling&t=00maxxx 的定期 GET 请求。
我猜这种联系永远不会真正完全发生。 我已经检查过 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);
});
有人知道问题是什么吗?
您的连接可能永远不会升级到 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 部署
我遇到了类似的问题,在我的本地主机上一切正常,但当我将 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');
});
...
})