问题
我的discord.py机器人的client.run()每隔几天左右就会意外返回,然后出现错误“任务已被销毁,但它正在等待处理!”。
问题
为什么是客户。run()返回了吗?我怎样才能改变我的机器人来正确处理这个问题并永远运行?
代码(剥离了很多以保持讨论的简单性):
import asyncio
import discord
TOKEN = 'my bot token goes here'
CHANNEL_ID = 'my channel id goes here'
async def DiscordMsgSendTask():
await client.wait_until_ready()
my_channel = discord.Object(id=CHANNEL_ID)
while not client.is_closed:
# wait a bit to prevent busy loop
await asyncio.sleep(2)
# check for and handle new event here
# if an event was handled then send a message to the channel
embed = discord.Embed(description='Event was handled')
await client.send_message(my_channel, embed=embed)
client = discord.Client()
while True:
client.loop.create_task(DiscordMsgSendTask())
try:
client.run(TOKEN)
except Exception as e:
logging.warning('Exception: ' + str(e))
client = discord.Client()
附加信息
机器人的目的基本上只是检查特定目录中的新文件,然后向特定的不和谐渠道发送消息进行报告。这一天只发生10次左右,因此机器人的流量极低。
为了让机器人容忍错误/断开,我把它放到了while True循环中,这可能是错误的方法。
使用Python 3.6.5和Discord。第0.16.12页
编辑-添加追溯
添加对当天早些时候发生的前一次故障的追溯。
2018-06-20 04:33:08 [ERROR] Task exception was never retrieved
future: <Task finished coro=<WebSocketCommonProtocol.run() done, defined at /usr/local/lib64/python3.6/site-packages/websockets/protocol.py:428> exception=ConnectionResetError(104, 'Connection reset by peer')>
Traceback (most recent call last):
File "/usr/local/lib64/python3.6/site-packages/websockets/protocol.py", line 434, in run
msg = yield from self.read_message()
File "/usr/local/lib64/python3.6/site-packages/websockets/protocol.py", line 456, in read_message
frame = yield from self.read_data_frame(max_size=self.max_size)
File "/usr/local/lib64/python3.6/site-packages/websockets/protocol.py", line 511, in read_data_frame
frame = yield from self.read_frame(max_size)
File "/usr/local/lib64/python3.6/site-packages/websockets/protocol.py", line 546, in read_frame
self.reader.readexactly, is_masked, max_size=max_size)
File "/usr/local/lib64/python3.6/site-packages/websockets/framing.py", line 86, in read_frame
data = yield from reader(2)
File "/usr/lib64/python3.6/asyncio/streams.py", line 674, in readexactly
yield from self._wait_for_data('readexactly')
File "/usr/lib64/python3.6/asyncio/streams.py", line 464, in _wait_for_data
yield from self._waiter
File "/usr/lib64/python3.6/asyncio/selector_events.py", line 723, in _read_ready
data = self._sock.recv(self.max_size)
ConnectionResetError: [Errno 104] Connection reset by peer
2018-06-20 04:33:08 [ERROR] Task was destroyed but it is pending!
task: <Task pending coro=<DiscordMsgSendTask() running at /home/bot.py:119> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7fc99bfd7a68>()]>>
2018-06-20 04:33:08 [ERROR] Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fc999b59240>
不能使用预定义的 run
方法,因为它仅处理键盘中断
。您需要创建一个退出策略,该策略在关闭所有任务的同时仍保持循环运行。
当bot收到消息“die”时,以下示例将引发< code>SystemExit(模拟您的意外致命错误(RST - ConnectionError错误))。< code>SystemExit将被“捕获”并重新启动您的bot。引发< code>KeyboardInterrupt后,bot将成功退出,不会出现错误。
import asyncio
import discord
TOKEN = 'TOKEN_HERE'
client = discord.Client()
async def task():
await client.wait_until_ready()
while True:
await asyncio.sleep(1)
print('Running')
def handle_exit():
print("Handling")
client.loop.run_until_complete(client.logout())
# For python 3.9, use asyncio.all_tasks instead
for t in asyncio.Task.all_tasks(loop=client.loop):
if t.done():
t.exception()
continue
t.cancel()
try:
client.loop.run_until_complete(asyncio.wait_for(t, 5, loop=client.loop))
t.exception()
except (asyncio.InvalidStateError, asyncio.TimeoutError, asyncio.CancelledError):
pass
while True:
@client.event
async def on_message(m):
if m.content == 'die':
print("Terminating")
raise SystemExit
client.loop.create_task(task())
try:
client.loop.run_until_complete(client.start(TOKEN))
except SystemExit:
handle_exit()
except KeyboardInterrupt:
handle_exit()
client.loop.close()
print("Program ended")
break
print("Bot restarting")
client = discord.Client(loop=client.loop)
在不和谐中(有人键入die
):
die
在终端(标准输出):
Running
Running
Running
Terminating
Handling
Bot restarting
Running
Running
Running
Running
Running
<CTRL-C> (KeyboardInterrupt)
Handling
Program ended
旁注:
如果您仍然对自己的错误感到困惑,那么不应该怪您的代码。Errno 104是一个服务器端致命错误,最终用户通常无法避免。
问题内容: 在Debian服务器上,我安装了Node.js。我了解如何使用以下命令行从腻子启动应用程序: 并通过地址(IP和端口)访问它。 但是,一旦我关闭腻子,那我就无法到达地址了。 如何使Node.js应用程序永久运行? 如您所料,我是Linux和Node.js的初学者。 问题答案: 尽管其他答案解决了OP的问题,但它们都是过大的,不能解释为什么他或她遇到此问题。 关键是这一行,“我关闭油灰,
如何在IDE之外运行?虽然似乎可以使用从CLI运行独立的JNDI查找应用程序,但它似乎不适用于ACC客户端。然而,这应该是可能的: 运行应用程序客户端 使用appclient脚本运行应用程序客户端,无论是否启用Java Web Start,都可以使用appclient脚本启动ACC。 GlassFish Server开源版应用程序开发指南4.0版开发Java客户端10-15页186 步骤: 1.)
我正在学习如何使用python创建一个discord bot,但我在使用这个命令时遇到了问题。我试图做的是踢一个特定的用户,然后使用bot将邀请发送回discord服务器。这是一个愚蠢的想法,但我真的想让它发挥作用。 我特别遇到的问题是如何踢一个特定的用户(带有用户标识),然后将该用户DM。 谢谢! 这里的代码: 这样做的目的是,如果具有适当角色类型的人一个特定的不一致用户id()被踢,机器人会自
我试图用Python制作一个不和谐机器人,根据你所在的班级(在我的学校),给你一个不和谐服务器上的角色。我刚刚开始,但每当我试图运行它时,我都会收到一个错误(我在Python 3笔记本电脑中的Google Colab中运行它)。这是我的代码: 当我运行它时,它会显示以下错误: 如果我把命令,程序永远不会到达它,因为循环阻止它到达命令。 我错过什么了吗?我不知道问题出在哪里。非常感谢您的帮助。
我有一个关于不和的问题。皮耶。我运行我的bot所在的两个独立服务器:测试服务器和主服务器。问题是,当我在测试服务器中发送消息时,bot会将其消息发送到主服务器,而不会将其发送回调用命令的服务器(仅在函数中)。 例如: 如果我在测试服务器中键入上述内容,我的bot将以“你好!”在测试服务器中。但是,如果我尝试将此代码放入函数并调用它: 通道ID显然设置为特定服务器。因此,假设我将ID“1234”作为
我使用使用SSL的安全通道通过JMS与Weblogic IBM Webpsphere MQ建立了连接。我在Weblogic上的应用程序收到了来自MQ的消息。正在将应答发送到应答队列。响应头存在MQMD,它填充java。在参数持久化JMS发送值“1”中。其他系统需要在持久化时接收值“0”。如何将此参数设置为java?我猜这个参数是javax。jms。deliverymode。但我不知道怎么设置。 无