Discord.py 机器人响应时间过长
Discord.py Bot Takes too Long to Respond
目标:
我正在开发一个 discord 机器人,它每 5 秒左右扫描一次 url,检查该网页上的 指定 更改,并发送一条消息如果发生这种变化,请在不和谐频道中。我通过使用 on_message
中的 if 语句将 url 发送到机器人来完成此操作。然后将 url 传递给 tasks.loop()
函数,在另一个函数中对其进行扫描和处理以进行更改。
问题:
我希望能够在 discord 频道中发送一条消息,该消息可以快速结束 tasks.loop()
中发生的进程,这样我就可以将它传递给另一个 url 进行扫描使用 on_message
函数。在目前的形式下,它可以工作——只是 非常 缓慢。从发送取消触发器开始,大约需要 3 分钟才能发送流程已取消的验证消息。我需要让这 5 秒或更短。对于它的价值,机器人使用 replit and uptime robot 保持 运行,但我确信较长的响应时间与 uptime 机器人唤醒 repl 的频率无关。
代码:
我的代码要复杂得多,并且充斥着晦涩难懂的命名变量,所以这里有一个更简单的代码片段,具有相同的通用结构。
client = discord.Client()
channel = client.get_channel(CHANNEL_ID)
@tasks.loop()
async def myloop(website, dataframe):
channel = client.get_channel(CHANNEL_ID)
try:
# iteratively scrape data from a website for
# a predefined change in the dataframe
if change = True:
await channel.send(notification)
except:
pass
@client.event
async def on_message(message):
channel = client.get_channel(CHANNEL_ID)
msg = message.content
if msg.startswith('track'):
website = msg[6:]
await channel.send('Now tracking '+str(website))
myloop(website,df)
if msg.starswith('stop'):
myloop.cancel()
await channel.send('Done tracking, awaiting orders.')
尝试的解决方案:
我尝试过使用某些形式的线程,我对它很陌生,但我还没有找到让它工作得更快的方法。任何建议或解决方案将不胜感激!一段时间以来,我一直在网上寻求帮助。
看起来您可以使用 client.loop.create_task
来创建异步任务对象,并使用它们的 cancel
方法在正确的时间立即取消这些异步任务,例如
import asyncio
from replit import db
_task = None
async def myloop():
website = db['website']
dataframe = db['dataframe']
channel = client.get_channel(CHANNEL_ID)
while not client.is_closed():
await asyncio.sleep(5)
try:
# iteratively scrape data from a website for
# a predefined change in the dataframe
if change:
await channel.send(notification)
except:
pass
@client.event
async def on_message(message):
global _task # This gives the function access to the variable that was already created above.
msg = message.content
if msg.startswith('track'):
website = msg[6:]
await message.channel.send('Now tracking '+str(website))
db['website'] = website
db['dataframe'] = df
if _task is not None:
_task.cancel()
_task = client.loop.create_task(myloop())
if msg.startswith('stop'):
if _task is not None:
_task.cancel()
_task = None
await message.channel.send('Done tracking, awaiting orders.')
参数create_task
采用的是一个不带参数的协程,因此网站URL和数据框需要以不同的方式访问函数(我不确定你是哪种方式会更喜欢或最好;使用 replit 的数据库只是一个例子)。
通过这种方法,您应该能够再次使用 track
来更改正在监视的网站,而无需在两者之间使用 stop
。
文档中有更多详细信息:
目标:
我正在开发一个 discord 机器人,它每 5 秒左右扫描一次 url,检查该网页上的 指定 更改,并发送一条消息如果发生这种变化,请在不和谐频道中。我通过使用 on_message
中的 if 语句将 url 发送到机器人来完成此操作。然后将 url 传递给 tasks.loop()
函数,在另一个函数中对其进行扫描和处理以进行更改。
问题:
我希望能够在 discord 频道中发送一条消息,该消息可以快速结束 tasks.loop()
中发生的进程,这样我就可以将它传递给另一个 url 进行扫描使用 on_message
函数。在目前的形式下,它可以工作——只是 非常 缓慢。从发送取消触发器开始,大约需要 3 分钟才能发送流程已取消的验证消息。我需要让这 5 秒或更短。对于它的价值,机器人使用 replit and uptime robot 保持 运行,但我确信较长的响应时间与 uptime 机器人唤醒 repl 的频率无关。
代码:
我的代码要复杂得多,并且充斥着晦涩难懂的命名变量,所以这里有一个更简单的代码片段,具有相同的通用结构。
client = discord.Client()
channel = client.get_channel(CHANNEL_ID)
@tasks.loop()
async def myloop(website, dataframe):
channel = client.get_channel(CHANNEL_ID)
try:
# iteratively scrape data from a website for
# a predefined change in the dataframe
if change = True:
await channel.send(notification)
except:
pass
@client.event
async def on_message(message):
channel = client.get_channel(CHANNEL_ID)
msg = message.content
if msg.startswith('track'):
website = msg[6:]
await channel.send('Now tracking '+str(website))
myloop(website,df)
if msg.starswith('stop'):
myloop.cancel()
await channel.send('Done tracking, awaiting orders.')
尝试的解决方案:
我尝试过使用某些形式的线程,我对它很陌生,但我还没有找到让它工作得更快的方法。任何建议或解决方案将不胜感激!一段时间以来,我一直在网上寻求帮助。
看起来您可以使用 client.loop.create_task
来创建异步任务对象,并使用它们的 cancel
方法在正确的时间立即取消这些异步任务,例如
import asyncio
from replit import db
_task = None
async def myloop():
website = db['website']
dataframe = db['dataframe']
channel = client.get_channel(CHANNEL_ID)
while not client.is_closed():
await asyncio.sleep(5)
try:
# iteratively scrape data from a website for
# a predefined change in the dataframe
if change:
await channel.send(notification)
except:
pass
@client.event
async def on_message(message):
global _task # This gives the function access to the variable that was already created above.
msg = message.content
if msg.startswith('track'):
website = msg[6:]
await message.channel.send('Now tracking '+str(website))
db['website'] = website
db['dataframe'] = df
if _task is not None:
_task.cancel()
_task = client.loop.create_task(myloop())
if msg.startswith('stop'):
if _task is not None:
_task.cancel()
_task = None
await message.channel.send('Done tracking, awaiting orders.')
参数create_task
采用的是一个不带参数的协程,因此网站URL和数据框需要以不同的方式访问函数(我不确定你是哪种方式会更喜欢或最好;使用 replit 的数据库只是一个例子)。
通过这种方法,您应该能够再次使用 track
来更改正在监视的网站,而无需在两者之间使用 stop
。
文档中有更多详细信息: