Flask-Socketio 在数据流传输 15 分钟后断开 Web(和 Python)客户端连接

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

我正在构建一个基于 Flask 的 Web 应用程序,经过大约 15 分钟的实时流传输(其中网页在 Chrome 中保持空闲/打开状态),Web 客户端和 Python 客户端从 Flask 服务器(在 socketio 客户端上)接收到一个断开连接事件,并且在两个客户端在 Flask 服务器的新实例上重新连接后,到 UI 的流式传输将不再工作。 Flask 服务器是在 IIS 管理器上使用 eventlet 部署的。

请输入有关如何继续的任何信息!

更多详情: 我有单独的 socketio-client,它从另一个 websocket 中选取实时数据并使用 Emit 将它们(处理后)发布到 socketio 上。 Socketio 服务器侦听这个特定事件,并根据每个此类数据使用最新数据更新其内部字典(我们称之为“曲线”)

然后是一个 Web UI,它在加载时向 Socketio 服务器发出一条消息,该服务器触发后台任务来处理最新的“Curve”数据,并将更新推送到“bedata”主题上的 socketio。 Web UI 在“bedata”上的 socketio 上收到的每次更新时都会更新其表。

该设置工作起来就像魅力一样大约 15 分钟,之后 Web UI 客户端和 Python socketio-Client 都收到来自 Flask 的“断开连接”事件,尽管它们都重新连接回来,但流媒体停止并且不滴答作响不再了!

工作流程:

基于Python的SocketIO客户端(DataStreamer.py) => app.py + MydataClient.py => html JS (client.html) => GUI (client.html)

init.py:

from flask import Flask
from flask_socketio import SocketIO
from threading import Lock
import eventlet

eventlet.monkey_patch()
app = Flask(__name__, template_folder='./templates')
app.config['SECRET_KEY'] = 'privatekey!'

thread = None
thread_lock = Lock
socketio = SocketIO(app, cors_allowed_origins='*',ping_timeout=15,logging=True)

app.py:

from wwwroot.StreamingApp import app, thread, thread_lock, socketio
import MydataClient
import eventlet
from eventlet import wsgi

wsgi.server(eventlet.listen(("0.0.0.0", 90)), app)

@app.route("/live")
def main():
    return render_template('client.html')

@socketio.on('connect', namespace='/web')
def connect():
    print('Client Connected')

@socketio.on('mydata',namespace='/web')
def MsgHandler(data):
    MydataClient.Curve = data

MydataClient.py:

from wwwroot.StreamingApp import app, thread, thread_lock, socketio

Curve=None
def CalculateBE():
    while True:
        response = {'status': True}
        for args in live_be:
            if args == None:
                continue
            be_price = #a method which does calculations on "Curve" data defined above
            response['BE' + str(args[0])] = be_price
        socketio.emit('bedata', response)
        socketio.sleep(5)

@socketio.on('be')
def UpdateBE():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(CalculateBE)

client.html (以下是html的JS代码):

<script>
$(document).ready( function () {
    var flask_socket = io.connect('http://localhost:90');
    flask_socket.on('connect',()=>{
        console.log('connected!');
    });
    flask_socket.on('disconnect',()=>{
        console.log('disconnected!');
    });
    flask_socket.emit('be');
    flask_socket.on("bedata", function (response) {
        #Update UI
    });
});
</script>

DataStreamer.py:

import socketio

sio = socketio.Client(reconnection_attempts=5,reconnection_delay=2,reconnection_delay_max=10)
sio.on('connect', on_connect)
sio.on('disconnect', on_disconnect)
sio.on('reconnect', on_reconnect)
sio.connect('http://localhost:90',namespaces=['/web'])
#some calculations from websocket data and then emit
sio.emit("mydata",curve_data,namespace="/web")

以下是使用的 pkg 版本:

烧瓶:2.3.2
烧瓶插座:5.3.5

python-socketio::5.8.0

DataStreamer.py 记录断开连接:

  1. 2023-09-11 14:51:35,158:INFO:client:395 => 发出事件“mydata”[/web]
  2. 2023-09-11 14:51:35,549:INFO:client:718 => Engine.IO 连接丢失
  3. 2023-09-11 14:51:35,564:INFO:client:652 => 连接失败,1.97 秒内进行新尝试
  4. 2023-09-11 14:51:36,190:ERROR:_logging:64 => 回调错误:/web 不是连接的命名空间。
  5. 2023-09-11 14:51:36,205:INFO:DataStreamer:171 => /web 不是连接的命名空间。
  6. 2023-09-11 14:51:38,096:INFO:client:681 => Engine.IO 连接已建立
  7. 2023-09-11 14:51:38,143:INFO:client:562 => 命名空间 /web 已连接
  8. 2023-09-11 14:51:38,174:INFO:client:669 => 重新连接成功
python-3.x flask socket.io flask-socketio
1个回答
0
投票

断开连接可能会由于实际服务器和客户端外部的许多不同原因而发生,因此我假设这是无法帮助的事情,并且您的目标是弄清楚如何在客户端断开连接后恢复流式传输已重新连接。

查看您的日志,发生

/web is not a connected namespace
是因为您的流线程在客户端断开连接后调用了
emit()
。如果你想避免这个错误,你必须让你的线程变得更聪明。每当调用客户端的
disconnect
处理程序时,必须通知线程这一点,以便它停止流式传输。

然后,当客户端重新连接时,它应该请求服务器启动一个新的流线程。

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