You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中WebSocketApp与持续循环函数的协同运行方案咨询

问题描述

已在Python中搭建3个可协同接收消息的WebSocketApp,代码如下:

ws1 = websocket.WebSocketApp("<url1>", on_open=...)
ws1.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

ws2 = websocket.WebSocketApp("<url2>", on_open=...)
ws2.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

ws3 = websocket.WebSocketApp("<url3>", on_open=...)
ws3.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

rel.signal(2, rel.abort)
rel.dispatch()

现需添加一个持续运行的循环函数,每隔几秒执行一次任务。尝试用rel.timeout调度时,若函数标记为async会出现RuntimeWarning: coroutine 'myFunction' was never awaited警告;若为非async函数,直接写while True: ...会独占程序,导致WebSocket无法接收消息。请问最佳实现方式是什么?

最佳实现方式

核心思路是避免在函数内使用无限循环阻塞事件循环,而是让任务函数执行单次逻辑后,主动重新调度自己,让rel事件循环有间隙处理WebSocket的消息、心跳等事件。

具体代码示例:

def my_loop_task():
    # 这里替换成你需要执行的任务逻辑
    print("执行周期性任务")
    
    # 调度N秒后再次执行当前函数,实现循环效果(这里设为5秒)
    rel.timeout(5, my_loop_task)

# 首次调度任务,此处可根据需求调整初始延迟
rel.timeout(0, my_loop_task)

# 原有的WebSocket初始化代码
ws1 = websocket.WebSocketApp("<url1>", on_open=...)
ws1.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

ws2 = websocket.WebSocketApp("<url2>", on_open=...)
ws2.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

ws3 = websocket.WebSocketApp("<url3>", on_open=...)
ws3.run_forever(dispatcher=rel, reconnect=5, ping_interval=60, ping_timeout=10)

rel.signal(2, rel.abort)
rel.dispatch()

关键说明

  1. rel是单线程事件循环库,若在函数内写while True: time.sleep(N),会持续占用线程,导致WebSocket的回调、心跳等事件无法被处理。
  2. 通过rel.timeout(N, my_loop_task)重复调度,相当于把周期性任务拆分为多个独立的执行单元,事件循环可以在任务间隙处理其他事件(比如WebSocket的消息接收)。
  3. 无需使用async函数,因为rel本身基于同步事件循环,不会自动协程调度,强行用async反而会导致未await的警告。

内容的提问来源于stack exchange,提问作者quantumtightening

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:28:26