Discord.py阻塞主程序,多平台聊天Bot开发遇运行卡顿求助
解决Discord.py客户端阻塞导致Twitch消息检测无法执行的问题
你的核心问题是discord.Client.run()是阻塞式调用——它会启动独立的事件循环并持续占用主线程,导致后续的Twitch WebSocket检测逻辑完全无法执行。要同时处理多平台消息,必须把Discord和Twitch的异步任务放到同一个asyncio事件循环里并发运行。
具体解决方案步骤
1. 重构Discord客户端启动逻辑
放弃使用client.run(),改用异步的client.start()。run()会创建专属事件循环并阻塞主线程,而start()是可等待的协程对象,能和其他异步任务共享事件循环。
2. 实现Twitch异步WebSocket监听
将Twitch的WebSocket连接、消息解析逻辑封装为异步函数,确保它能在事件循环中与Discord任务并行执行。
3. 用asyncio.gather并发调度多任务
通过asyncio.gather()将Discord客户端启动任务和Twitch监听任务合并,交给asyncio事件循环统一调度,实现真正的并发。
修改后的代码示例
import asyncio import discord # 使用异步WebSocket库处理Twitch连接,需先安装:pip install websockets import websockets class MultiPlatformBot: def __init__(self, discord_token, twitch_oauth, twitch_channel): self.discord_token = discord_token self.twitch_oauth = twitch_oauth self.twitch_channel = twitch_channel # 初始化Discord客户端 self.intents = discord.Intents.all() self.client = discord.Client(intents=self.intents) # 绑定Discord消息事件 @self.client.event async def on_ready(): print(f'Discord登录成功:{self.client.user}') @self.client.event async def on_message(message): if message.author == self.client.user: return if message.content.startswith('hi'): await message.channel.send('Hello!') async def twitch_listener(self): """Twitch异步消息监听逻辑""" twitch_ws_uri = 'wss://irc-ws.chat.twitch.tv:443' async with websockets.connect(twitch_ws_uri) as websocket: # 发送Twitch认证指令 await websocket.send(f'PASS oauth:{self.twitch_oauth}') await websocket.send(f'NICK justinfan12345') # 匿名账号或你的Bot账号 await websocket.send(f'JOIN #{self.twitch_channel}') print(f'已连接Twitch频道:#{self.twitch_channel}') # 持续监听Twitch消息 async for raw_msg in websocket: # 解析Twitch聊天消息 if 'PRIVMSG' in raw_msg: msg_parts = raw_msg.split(':', 2) if len(msg_parts) >=3: username = msg_parts[1].split('!')[0] content = msg_parts[2].strip() print(f'Twitch [{username}]: {content}') # 这里添加你的消息条件判断和触发逻辑 async def start_all_platforms(self): print('正在连接多平台...') try: # 并发运行Discord和Twitch任务 await asyncio.gather( self.client.start(self.discord_token), self.twitch_listener() ) except discord.LoginFailure: print('Discord令牌无效,请检查配置') except Exception as e: print(f'连接出错:{str(e)}') finally: # 确保Discord客户端正常关闭 await self.client.close() # Bot启动入口 if __name__ == "__main__": bot = MultiPlatformBot( discord_token="你的Discord令牌", twitch_oauth="你的Twitch OAuth令牌", twitch_channel="目标Twitch频道名" ) asyncio.run(bot.start_all_platforms())
关键改动说明
- 同步方法转异步:将原来的
connection()改为异步的start_all_platforms(),用asyncio.run()启动全局事件循环。 - 替换
run()为start():避免Discord独占事件循环,让多平台任务能并行执行。 - 异步Twitch逻辑:使用
websockets库实现非阻塞的Twitch消息监听,和Discord事件循环共享资源。 - 扩展友好:后续添加YouTube平台时,只需新增对应的异步监听函数,加到
asyncio.gather()中即可。
内容的提问来源于stack exchange,提问作者Mathieu Godin
相关产品推荐
相关产品推荐

