如何让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
相关产品推荐
相关产品推荐

