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

如何让Discord bot加入语音频道后保持24/7在线不自动断开

问题原因
  • Discord官方语音连接存在空闲超时机制,无音频传输时超过一定时长会主动切断连接
  • 原代码未开启自动重连配置,连接被切断后不会主动重试
  • 未做连接状态检测,异常断开后无法感知并自动重新加入频道
  • 全局vc变量未做有效性校验,断开后变量仍持有已失效的语音客户端实例
解决方案

你可以通过添加自动重连配置、断线监听事件、后台保活任务三个部分实现24/7稳定驻留,修改后的完整代码如下:

import discord
from discord.ext import commands
from discord.ext.commands import has_permissions
import time
import asyncio

# 注意intents需要在Discord开发者后台开启对应权限
client = commands.Bot(command_prefix='!', intents=discord.Intents.all())
# 存储最后加入的语音频道ID,用于断线重连
last_vc_channel_id = None
vc = None

@client.command(aliases=['j'])
@has_permissions(administrator=True)
async def join(ctx):
    global last_vc_channel_id, vc
    connected = ctx.author.voice
    await ctx.message.delete()
    timenow = time.strftime("%H:%M")
    embed=discord.Embed(title="Joined the VC", color=0x2bff00)
    embed.set_footer(text=f"{ctx.message.author} | {timenow}")
    await ctx.send(embed=embed)
    if not connected:
        await ctx.send("You need to be connected in a voice channel to use this command!")
        return
    # 如果已经在频道里先断开旧连接,避免重复实例冲突
    if vc and vc.is_connected():
        await vc.disconnect()
    # 配置无连接超时、自动重连,默认开启服务器静音减少不必要的资源占用
    vc = await connected.channel.connect(timeout=None, reconnect=True, self_deaf=True)
    last_vc_channel_id = connected.channel.id

# 监听语音状态变化,实时检测bot断开事件
@client.event
async def on_voice_state_update(member, before, after):
    global vc, last_vc_channel_id
    # 只处理bot自身的状态变化
    if member.id != client.user.id:
        return
    # 检测到bot从语音频道断开,且存在记录的目标频道时触发重连
    if before.channel and not after.channel and last_vc_channel_id:
        # 等待3秒避免临时网络波动导致的重连失败
        await asyncio.sleep(3)
        channel = client.get_channel(last_vc_channel_id)
        if channel:
            try:
                vc = await channel.connect(timeout=None, reconnect=True, self_deaf=True)
            except:
                # 可根据需求添加重试循环,比如每隔10秒重试最多5次
                pass

# 后台保活任务,作为事件监听的兜底机制,定时检测连接状态
async def vc_keepalive():
    await client.wait_until_ready()
    global vc, last_vc_channel_id
    while not client.is_closed():
        if last_vc_channel_id and (not vc or not vc.is_connected()):
            channel = client.get_channel(last_vc_channel_id)
            if channel:
                try:
                    vc = await channel.connect(timeout=None, reconnect=True, self_deaf=True)
                except:
                    pass
        # 每5分钟检测一次,可根据需求调整间隔
        await asyncio.sleep(300)

# 启动后台保活任务
client.loop.create_task(vc_keepalive())

client.run('替换为你的Bot Token')
额外注意事项
  • 确保Discord开发者后台给Bot开启了语音相关权限,且加入的服务器给了Bot加入语音频道、说话的权限
  • 如果是部署在国内服务器,需要确认网络到Discord服务的稳定性,网络波动也会导致频繁断连
  • 如果需要长时间驻留,建议搭配进程守护工具(如systemd、pm2)使用,避免Bot进程意外崩溃退出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:36:03