Python实现非阻塞式每隔X秒向WebSocket服务器发送消息
非阻塞WebSocket保活实现方案
针对你的需求,这里提供两种无需修改库源码、非阻塞的保活实现方式,都是发送服务器能识别的普通文本消息(而非库自带的ping帧)来维持连接:
方案一:线程定时发送(基于websocket-client库)
利用Python的threading.Timer在独立线程中循环发送保活消息,主线程专注处理实时数据接收,两者互不阻塞。
import websocket import threading def keep_alive(ws, interval=5): try: # 发送服务器要求的保活消息,这里以"ping"为例,按需调整 ws.send("ping") # 定时触发下一次保活 threading.Timer(interval, keep_alive, args=(ws, interval)).start() except Exception as e: print(f"保活发送失败: {str(e)}") # 连接断开时终止定时任务 return def handle_message(ws, message): # 处理实时接收的数据 print(f"收到实时数据: {message}") def handle_error(ws, error): print(f"连接错误: {str(error)}") def handle_close(ws, close_code, close_msg): print("WebSocket连接已关闭") def handle_open(ws): print("WebSocket连接已建立") # 启动保活任务 keep_alive(ws) if __name__ == "__main__": # 替换为你的服务器WebSocket地址 ws_url = "ws://your-server-address" ws_app = websocket.WebSocketApp( ws_url, on_open=handle_open, on_message=handle_message, on_error=handle_error, on_close=handle_close ) # 主线程运行WebSocket接收循环,保活任务在独立线程执行 ws_app.run_forever()
注意事项:
- 确保保活消息内容符合服务器要求,比如有些服务器可能需要特定格式的字符串
threading.Timer是线程安全的,这里仅用一个线程发送保活,不会和主线程的接收操作冲突
方案二:异步IO实现(基于websockets库)
如果你的项目适合异步架构,推荐使用websockets库,通过异步任务同时处理保活发送和数据接收,全程非阻塞,代码更简洁优雅。
首先安装依赖:
pip install websockets
实现代码:
import asyncio import websockets async def keep_alive(ws, interval=5): while True: try: # 发送保活消息 await ws.send("ping") await asyncio.sleep(interval) except websockets.exceptions.ConnectionClosed: print("连接已断开,停止保活") break async def receive_data(ws): # 持续接收实时数据 async for message in ws: print(f"收到实时数据: {message}") async def main(): # 替换为你的服务器WebSocket地址 ws_url = "ws://your-server-address" async with websockets.connect(ws_url) as ws: # 创建并启动保活异步任务 keep_alive_task = asyncio.create_task(keep_alive(ws)) # 执行数据接收任务(会一直运行直到连接断开) await receive_data(ws) # 接收任务结束后,取消保活任务 keep_alive_task.cancel() await keep_alive_task if __name__ == "__main__": asyncio.run(main())
优势:
- 全程异步,没有线程切换的开销
- 保活和接收都在同一个事件循环中,天然避免线程安全问题
- 代码结构更清晰,异常处理更直观
内容的提问来源于stack exchange,提问作者JayK23
相关产品推荐
相关产品推荐

