Discord机器人进阶状态更新遭遇socket.send() raised exception异常及异步命令失效问题求助
问题根源与解决方案
你的机器人出现socket.send() raised exception异常、命令无响应的核心原因,是代码破坏了Discord.py的异步事件循环机制,具体有三个关键错误:
1. 使用阻塞的time.sleep()卡死事件循环
Discord.py是基于异步IO运行的,time.sleep()是同步阻塞函数——它会让整个事件循环彻底停住,机器人无法处理任何其他异步操作(比如接收命令、和Discord网关通信)。这就是为什么你的命令没反应,还会出现socket异常:网关连接因为事件循环卡住而中断了。
必须把所有time.sleep()替换成异步的await asyncio.sleep(),这样事件循环在等待时还能处理其他任务。
2. tasks.loop与while True重复循环
你给status_change加了@tasks.loop(seconds=5)装饰器,这个装饰器的作用就是让函数按指定间隔自动重复执行。但你又在函数里套了一层while True,导致函数内部无限循环,永远不会退出,进一步把事件循环死死卡住。
3. 错误的任务启动方式
tasks.loop装饰的任务不需要用client.loop.create_task()启动,直接调用.start()方法即可——就像你第一个能正常运行的版本那样。
修正后的完整代码示例
import discord import asyncio # 新增:导入asyncio用于异步睡眠 import datetime import random import math import pytz import dns import os import pymongo from pymongo import MongoClient from discord.ext import commands,tasks from itertools import cycle from discord.utils import get from typing import List client = commands.Bot(command_prefix='lg') # 用cycle更优雅地管理状态循环,避免重复写代码 status_cycle = cycle([ (discord.Status.idle, discord.Game(name='Vice-Captain of The Perkers')), (discord.Status.do_not_disturb, discord.Game(name='At your service...')), (discord.Status.online, discord.Game(name='AHIHIP Forever!')) ]) @tasks.loop(seconds=10) # 每个状态停留10秒 async def status_change(): status, activity = next(status_cycle) await client.change_presence(status=status, activity=activity) @client.event async def on_ready(): print("#G11 - The Perkers Vice-Captain Little Green reporting.") await asyncio.sleep(0.75) # 替换同步sleep为异步 print("What can I help with, sir?") await asyncio.sleep(3) # 同样替换 status_change.start() # 直接启动loop任务 @client.command() async def hallo(ctx): await ctx.send('Hi!') client.run('Token')
额外说明
如果你更习惯按顺序写状态切换的逻辑,也可以去掉cycle,直接在loop函数里按顺序执行(但记得不要加while True):
@tasks.loop(seconds=30) # 整个状态周期30秒(10*3) async def status_change(): await client.change_presence(status=discord.Status.idle, activity=discord.Game(name='Vice-Captain of The Perkers')) await asyncio.sleep(10) await client.change_presence(status=discord.Status.do_not_disturb, activity=discord.Game(name='At your service...')) await asyncio.sleep(10) await client.change_presence(status=discord.Status.online, activity=discord.Game(name='AHIHIP Forever!'))
这样修改后,你的机器人就能正常处理命令,状态也能按预期切换了。
内容的提问来源于stack exchange,提问作者user16106302
相关产品推荐
相关产品推荐

