如何让WebSocket与discord.py Bot实现并发运行?
解决方案:WebSocket服务端与discord.py Bot并发运行
你当前的问题核心在于:asyncio.run(serve())会阻塞事件循环直到WebSocket服务关闭,之后才会执行client.run(),而client.run()本身也是同步阻塞方法,导致两个服务永远无法同时启动。另外异步代码跨线程运行容易引发事件循环冲突,最优方案是将两者放到同一个异步事件循环中并发执行。
修改后的main.py代码
import asyncio import os import websockets from discord import Client from logging import info as info_logger # --- websockets ---- async def response(websocket, path): message = await websocket.recv() print(f"[ws server] message < {message}") async def serve(): print('running websockets ws://localhost:8000') server = await websockets.serve(response, 'localhost', 8000) await server.wait_closed() # - discord - client = Client() @client.event async def on_ready(): print(f"[discord bot] logged in as {client.user}") async def main(): # 同时启动WebSocket服务和Discord Bot # 使用return_exceptions=True避免其中一个任务退出导致另一个也终止 await asyncio.gather( serve(), client.start(os.getenv("BOTTOKEN")), return_exceptions=True ) if __name__ == "__main__": info_logger.info(f"starting Discord Bot!") asyncio.run(main())
关键修改说明
- 替换
client.run()为client.start():client.run()是同步阻塞方法,会创建独立事件循环并持续阻塞;client.start()是异步协程,可加入现有事件循环实现并发执行。 - 用
asyncio.gather()调度并发任务:将WebSocket服务的serve()和Bot的client.start()作为协程传入gather,事件循环会自动调度两者同时运行。 - 异常容错处理:
return_exceptions=True参数确保单个任务因异常退出时,另一任务可继续运行(若不需要该容错,可删除此参数,此时任一任务崩溃会导致整个程序终止)。
测试步骤
- 运行修改后的
main.py,控制台会同时输出WebSocket服务启动信息和Bot登录成功提示。 - 运行
client.py,WebSocket服务端会打印收到的客户端消息,同时Bot保持在线状态。
内容的提问来源于stack exchange,提问作者SomeRandomGuy
相关产品推荐
相关产品推荐

