使用 flask-socketio 和 eventlet 更新特定于每个用户的数据

Update data specific to each user using flask-socketio and eventlet

我正在创建一个网络应用程序,它应该实时更新推送到数据库的读数,为此我必须在用户访问页面时在后台保留一个方法 运行。数据是特定于用户的,因此仅添加后台线程无济于事。不过,困难的部分是我需要能够在按下按钮时停止线程,并在使用不同数据后立即重新启动它。我尝试使用 eventlet gunicorn 和 flask-socketio 创建一个看起来有点像这样的解决方案:

@socketio.on('update', namespace='/update')
    def make_thread(*args):
        thread = Thread(target=update(args)
        thread.daemon = True
        thread.start()

def update(*args):
        while True:
            //code that keeps running to query changes
            socket.emit('update_reading', reading)
            time.sleep(10)

我的问题是,虽然代码有效,并且它确实更新了前端,但我似乎无法弄清楚如何为一个用户专门创建这个线程(如果有必要的话) .以及如何从另一个套接字方法停止线程并在其位置启动一个新线程。

当您收到 connect 事件时,您可以将您的数据库用户 ID 映射到 SocketIO 会话 ID。像这样:

socketio.on('connect')
def on_connect():
    user = load_user(session['user_id'])
    user.sid = request.sid  # socketio session id
    save_user(user)

socketio.on('disconnect')
def on_disconnect():
    user = load_user(session['user_id'])
    user.sid = None
    save_user(user)

从那时起,当您想向单个用户发送消息时,只需将 room=user.sid 添加到您的发送调用中即可。在您的示例中:

@socketio.on('update', namespace='/update')
def make_thread(*args):
    user = load_user(session['user_id'])
    thread = Thread(target=update, args=(user.sid,))
    thread.daemon = True
    thread.start()

def update(sid):
    while True:
        //code that keeps running to query changes
        socket.emit('update_reading', reading, room=sid)
        time.sleep(10)

要停止后台线程,您必须跟踪所有这些线程并跟踪每个线程属于哪个用户。在线程循环中,您将需要一个布尔值而不仅仅是 while True,这样您就可以通过切换该布尔值来告诉线程停止。我建议您为您的线程制作一个 class 包装器,并在布尔值更改的地方添加一个 stop() 方法,然后等待线程通过调用 thread.join().[=17 退出=]