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

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("这行代码永远不会执行")

终端输出

终端输出截图


排查与解决方案

  1. 检查事件循环阻塞
    connect()挂起大概率是事件循环被同步代码阻塞导致。排查代码中是否有长时间运行的非异步函数(如文件读写、网络请求未用异步库),需将这类操作改为异步实现,或通过asyncio.to_thread()将其放入线程池执行,避免阻塞主事件循环。

  2. 更新discord.py版本
    旧版本discord.py存在语音连接相关的已知bug,执行以下命令升级至最新稳定版:

pip install --upgrade discord.py
  1. 处理重复连接状态
    机器人可能存在残留的语音客户端状态,导致新连接请求异常。在调用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)}")
  1. 调整超时参数与日志
    增大timeout参数(如设置为10秒),避免因网络波动导致超时;同时开启debug日志查看连接细节:
import logging
logging.basicConfig(level=logging.DEBUG)

内容的提问来源于stack exchange,提问作者mansur ischanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:31:20