首页 > 解决方案 > 使用不和谐机器人发送高优先级和低优先级消息

问题描述

Discord 将机器人限制为每台服务器每 5 秒执行 5 次操作 - 因此,机器人尽可能快地响应紧急事件非常重要,即使这意味着降低其他事情的优先级。

我第一次尝试处理这个是这两个命令(特别是第一个使用时间模块)

@bot.command()
async def low_priority_count(ctx, num: int):

    for i in range(num):
        time.sleep(1)
        await ctx.send("low priority "+str(i))

@bot.command()
async def high_priority_count(ctx, num: int):

    for i in range(num):
        await ctx.send("high priority "+ str(i))
bot.run(TOKEN)

我的想法是,如果您调用 $high_priority_count 20 循环将快速发送包含数字 0-19 的消息,尽管 discord 需要一些时间才能将它们打印出来。因此,我预计如果您调用 $low_priority_count 20 ,您会在高优先级消息之后获得低优先级消息。

相反,你让它们相互交织。这是文本频道上消息的附加版本:

User:      $high_priority_count 20
Bot:       high priority 0
           high priority 1
           high priority 2
           ...
           high priority 9
User:      $low_priority_count 20
Bot:       high priority 10
           low priority 0
           high priority 11
           low priority 1
           high priority 12
           low priority 2
           ...
           high priority 19
           low priority 9
           low priority 10
           low priority 11
           low priority 12
           ...
           low priority 20

为什么机器人会一起发送消息?有没有办法确保它在发送低优先级消息之前发送高优先级消息?

标签: discord.py

解决方案


您正在使用time.sleepwhich 是一个阻塞函数,您不应该在异步代码中使用它。如果您使用asyncio.sleep一切都应该按您的预期工作

import asyncio

@bot.command()
async def low_priority_count(ctx, num: int):
    for i in range(num):
        await asyncio.sleep(1)
        await ctx.send("low priority "+str(i))


@bot.command()
async def high_priority_count(ctx, num: int):
    for i in range(num):
        await ctx.send("high priority "+ str(i))

您还应该在命令中添加延迟high_priority_count,在测试代码时我已经多次达到速率限制。

编辑:

回答您的评论,这是一个更复杂的,您可以使用Synchronization Primitivesasyncio.Semaphore应该管用

bot.priority_semaphore = asyncio.Semaphore()

@bot.command()
async def high_priority_count(ctx, count: int):
    await bot.priority_semaphore.acquire()
    for i in range(count):
        await ctx.send(f"High priority {i}")

    bot.priority_semaphore.release()


@bot.command()
async def low_priority_count(ctx, count: int):
    await bot.priority_semaphore.acquire():
    for i in range(count):
        await asyncio.sleep(1)
        await ctx.send(f"High priority {i}")

    bot.priority_semaphore.release()

可悲的是,如果您首先调用该low_priority_count命令,它将首先发送低优先级消息,如果首先调用低优先级消息,我想不出一种首先发送高优先级消息的方法。


推荐阅读