如何使用socketio异步发送数据到Web客户端?

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

以下情况:

  • Web客户端:使用JavaScript socketio侦听传入消息(= JavaScript)。
  • Web服务器:使用flask-socketioeventlet发送数据(= Python)。

如果客户端向服务器发送消息,则一切正常。服务器接收消息。例:

socketio = SocketIO(app, engineio_logger=True, async_mode="eventlet")

@socketio.on("mymsg")
def handle_event(message):
    print("received message: " + str(message))

不幸的是,反过来也行不通 - 在某种程度上。我有一个线程产生实时数据,每秒约5到10次Web前端应该显示。它应该发送给客户端。

第一:如果生成数据的线程试图直接调用sockeito.emit(),它根本不起作用。其中的原因尚不清楚,但正如文件所述,flask-socketioeventlet遵循不同的异步模型,但在某种程度上看似合理。

第二:将经典线程与flask / eventlet的异步模型分离在一定程度上起作用。我尝试使用eventlet队列。我的线程产生的所有状态数据都放入队列中,如下所示:

statusQueue.put(statusMsg)

这很好用。调试消息显示此操作始终执行,将数据添加到队列之后。

由于烧瓶的文档告诉我,我建议使用socketio.start_background_task()以便在兼容模式下运行“线程”到socketio使用的异步模型。所以我使用这段代码:

def emitStatus():
    print("Beginning to emit ...")
    while True:
        msg = statusQueue.get()
        print("Sending status packet: " + str(msg))
        socketio.emit("status", msg, broadcast=True)
        statusQueue.task_done()
        print("Sending status packet done.")
print("Terminated.")

socketio.start_background_task(emitStatus)

我要求你寻求帮助的奇怪之处在于:第一次调用statusQueue.get()会阻塞,因为最初队列是空的。第一条消息从队列中获取并通过socketio发送。客户端上的调试消息显示Web客户端收到此消息。服务器上的调试消息显示消息已成功发送。但是:只要调用下一个statusQueue.get(),无论有多少消息被放入队列,调用都会无限期地阻塞。

我不确定这是否有帮助,但一些额外的信息:socketio通信完好无损。如果客户端发送数据,一切正常。此外,我可以看到客户端和服务器的ping-pongs一直保持连接活动。

我的问题是:如何正确实现能够异步向客户端发送消息的服务器?

查看https://github.com/jkpubsrc/experiment-python-flask-socketio,了解一个简单的代码示例,其中包含Python-Flask服务器进程和基于JQuery的JavaScript客户端。

(仅供参考:由于这些是状态消息,因此不一定每条消息都需要到达。但我非常希望至少收到一些消息,不仅是第一条消息,还有其他消息。)

谢谢你的回复。

python-3.x socket.io message-queue eventlet
1个回答
0
投票

我留下了两个解决方案,使代码可以作为拉取请求。

基本上,答案是:您选择一种技术并坚持使用它:

  • async_mode=threading?太棒了,使用stdlib队列。除非必须,否则不要导入eventlet。
  • async_mode=eventlet?也很好,使用eventlet队列,不要忘记stdlib time.sleepsocket IO将阻止其他一切,修复eventlet.monkey_patch()
  • 如果必须同时使用eventlet和线程,最好的方法是让它们位于不同的OS进程中并通过本地套接字进行通信。这是额外的工作,但它非常强大,你知道它是如何工作的以及为什么它不会破坏。

熟悉eventlet和本机线程,您可以仔细地将它们混合到工作代码中。正如您已经发现的那样,截至2018-09,混合不能以友好明显的方式起作用。抱歉。欢迎补丁。

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