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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:43:23