如何用websockets库每30秒发送Ping帧保活连接?非SO重复问题
解决websockets库定时Ping的Future pending问题
别担心,这确实不是重复问题——咱们就盯着websockets库的心跳Ping逻辑来解决。
你遇到的Future pending本质上是异步操作没被正确等待导致的:websockets是异步库,它的ping()方法会返回一个Future对象,表示这个异步操作还在进行中,如果没有用await去等待它完成,这个Future就会一直处于pending状态。
正确的定时Ping实现方式
要实现每30秒发一次Ping维持连接,你需要结合asyncio的后台任务和await来确保Ping操作完成。举个完整的示例:
import asyncio import websockets async def keep_alive(websocket, interval=30): """定时发送Ping帧维持连接""" while True: await asyncio.sleep(interval) # 必须await ping(),确保异步操作执行完成 await websocket.ping() print("Ping帧已发送") async def main(): # 建立WebSocket连接 async with websockets.connect("ws://你的服务器地址") as websocket: # 创建后台任务运行定时Ping ping_task = asyncio.create_task(keep_alive(websocket)) try: # 这里处理接收消息或其他业务逻辑 async for message in websocket: print(f"收到消息: {message}") finally: # 退出时取消Ping任务,避免资源泄漏 ping_task.cancel() await ping_task if __name__ == "__main__": asyncio.run(main())
为什么之前会出现Future pending?
大概率是你之前的代码里直接调用了websocket.ping()但没有加await,比如:
# 错误示例:没有await,返回pending的Future websocket.ping()
这种情况下,Ping操作并没有真正执行,只是返回了一个未完成的Future对象,服务器自然不会有预期的响应,还会留下未处理的异步任务。
另外,如果你的定时逻辑用了普通的time.sleep()而不是asyncio.sleep(),会阻塞整个异步事件循环,导致Ping操作根本无法被调度执行,也会引发类似的问题。
内容的提问来源于stack exchange,提问作者jsstuball
相关产品推荐
相关产品推荐

