跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何正确实现 Discord.py 机器人状态轮播以避免网关限流

discord.py 机器人因频繁调用 `change_presence()` 触发 websocket 网关限流(429 错误),核心原因是未使用 `await asyncio.sleep()` 导致异步循环“空转”,实际请求间隔远小于预期。本文提供合规、鲁棒的状态轮播实现方案。 在 Discord API 中,change_presence() 属于网关(Gateway)操作,受严格的速率限制约束: 同一 shard 每 5 秒最多允许 1 次状态更新 (即 0.2 次/秒)。你原代码中虽写 asyncio.sleep(300),但 缺少 await 关键字 ,导致该语句仅创建协程对象而未真正挂起执行——循环瞬间重复运行,短时间内发起大量请求,最终触发 Discord 的限流机制,并打印类似 WebSocket in shard ID None is ratelimited, waiting 57 seconds 的警告。 ✅ 正确做法是使用 await asyncio.sleep(300),确保每次状态变更后 完整等待 5 分钟 ,让事件循环有机会处理其他任务并遵守限流窗口。 以下是优化后的完整实现: 面向设计的AXUI前端框架表单 面向设计的AXUI前端框架表单是一款包含表格、列表、弹窗等的AXUI前端框架表单下载。 下载
import asyncio import random import discord from discord.ext import commands actaray = ["PcktWtchr's Videos", "Cams", "and Listening Always", "or Listening or Both"] @bot.event async def on_ready(): print(f'Logged in as {bot.user}') while True: try: activity = discord.Activity( type=discord.ActivityType.watching, name=random.choice(actaray) ) await bot.change_presence(activity=activity) await asyncio.sleep(300) # ✅ 正确:await 确保真实休眠 except discord.HTTPException as e: if e.status == 429: # 遇到限流响应 retry_after = int(e.response.headers.get("Retry-After", "5")) print(f"Rate limited! Retrying after {retry_after} seconds...") await asyncio.sleep(retry_after + 1) # 加 1 秒缓冲,避免边界重试 else: print(f"HTTP error during presence update: {e}") await asyncio.sleep(60) # 其他 HTTP 错误降频重试 except Exception as e: print(f"Unexpected error in presence loop: {e}") await asyncio.sleep(60) # 可选:添加优雅关闭支持(如需热重载或清理) @bot.event async def on_disconnect(): print("Bot disconnected — presence loop paused.")
? 关键注意事项: 永远不要在 while True 循环中遗漏 await :asyncio.sleep() 是协程,不加 await 不会暂停,等同于无限轮询; 异常捕获必须覆盖 discord.HTTPException :Discord 在限流时返回 HTTP 429 响应,Retry-After 头部指明精确等待秒数,应优先遵循; 避免全局 on_error 泛化处理 :原答案中 on_error 事件无法捕获 change_presence() 抛出的异常(它不在此事件链路中),因此应将错误处理内聚在轮播逻辑内部; 推荐最小间隔 ≥ 300 秒(5 分钟) :虽然 Discord 文档未公开确切阈值,但实测低于 240 秒易触发限流,5 分钟是稳定安全的实践值; 若需更高频更新(如实时计数器),应改用 Rich Presence + activity.timestamps 或 前端 轮询,而非反复调用 change_presence()。 通过以上修正,你的机器人将严格遵循 Discord 网关速率策略,彻底消除 ratelimited 警告,同时保持状态轮播功能稳定可靠。

相关文章