discord.VoiceChannel.connect()无返回值且is_connected()判断异常问题
Discord.py语音频道连接异常问题
我正在开发一个Discord机器人,功能是连接发起指令用户当前所在的语音频道,使用connect()方法实现连接。根据Discord官方文档,VoiceChannel.connect()应该返回一个VoiceProtocol对象,但实际调用时该方法会挂起,始终没有返回值。
2021年曾有相同问题的讨论,但未给出具体解决方案。
示例代码
caller = ctx.author.voice if caller is None: await ctx.send("你未连接到任何语音频道") return else: await caller.connect(timeout=.5, reconnect=False, self_mute=False, self_deaf=True) await ctx.send("这行代码永远不会执行")
尽管调用没有返回值,机器人仍能成功连接到语音频道,且没有抛出任何异常。
补充异常现象:调用is_connected()返回False——机器人实际已连接到语音频道,但自身判定为未连接状态。
相关代码
@commands.command() async def isconnected(self, ctx): voice = discord.utils.get(ctx.bot.voice_clients, guild=ctx.guild) print("is_connected(): ", voice.is_connected()) _id = voice.channel.id print("机器人已连接到频道: " + str(ctx.bot.get_channel(_id))) voice2 = discord.utils.get(self.client.voice_clients, guild=ctx.guild) print("is_connected(): ", voice2.is_connected()) _id2 = voice2.channel.id print("机器人已连接到频道: ", str(ctx.bot.get_channel(_id2))) @commands.command() async def join(self, ctx): caller = ctx.message.author.voice if caller is None: await ctx.send("你未连接到任何语音频道") return await caller.channel.connect(timeout=5, reconnect=False, self_mute=False, self_deaf=True) print("这行代码永远不会执行")
终端输出

排查与解决方案
检查事件循环阻塞
connect()挂起大概率是事件循环被同步代码阻塞导致。排查代码中是否有长时间运行的非异步函数(如文件读写、网络请求未用异步库),需将这类操作改为异步实现,或通过asyncio.to_thread()将其放入线程池执行,避免阻塞主事件循环。更新discord.py版本
旧版本discord.py存在语音连接相关的已知bug,执行以下命令升级至最新稳定版:
pip install --upgrade discord.py
- 处理重复连接状态
机器人可能存在残留的语音客户端状态,导致新连接请求异常。在调用connect()前先检查并断开已有连接:
@commands.command() async def join(self, ctx): caller = ctx.message.author.voice if caller is None: await ctx.send("你未连接到任何语音频道") return # 断开已有连接 existing_voice = discord.utils.get(ctx.bot.voice_clients, guild=ctx.guild) if existing_voice: await existing_voice.disconnect(force=True) # 执行连接 try: voice_protocol = await caller.channel.connect( timeout=10, reconnect=False, self_mute=False, self_deaf=True ) print(f"连接成功,返回VoiceProtocol: {voice_protocol}") await ctx.send("已成功连接到语音频道") except Exception as e: print(f"连接失败: {str(e)}") await ctx.send(f"连接失败: {str(e)}")
- 调整超时参数与日志
增大timeout参数(如设置为10秒),避免因网络波动导致超时;同时开启debug日志查看连接细节:
import logging logging.basicConfig(level=logging.DEBUG)
内容的提问来源于stack exchange,提问作者mansur ischanov
相关产品推荐
相关产品推荐

