Soulter / AstrBot

QQ、Telegram等多平台兼容的支持 LLM 聊天的机器人平台。支持自定义插件扩展。
https://astrbot.soulter.top
GNU Affero General Public License v3.0
610 stars 60 forks source link

[Bug]websocketAPI错误 #193

Closed creeper-scr closed 2 weeks ago

creeper-scr commented 2 months ago

发生了什么

运行一段时间后提示websocketAPI连接超时,报错示例见下。 使用llonebot作为消息平台,qq保持在线且正常启动,llonebot正常。默认插件helloworld运行正常且有回复

一开始的几条消息能够成功发送,后面的消息无法发送

如何复现?

通过命令行启动astrbot,确保llonebot正常运行。 加载helloworld插件与send_message_on_time插件(仓库见git@github.com:creeper-scr/astrbot_plugin_send_msg_ontime_public.git 运行几分钟至几十分钟不等后,报错wsAPI time out(见额外信息)

AstrBot 版本与部署方式

v3.3.9命令行部署

操作系统

Windows

额外信息

`2024-08-17 00:06:23.702| ERROR |MainThread|astrbot.handle_task|bootstrap.py:107 - Traceback (most recent call last): File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 490, in wait_for return fut.result() ^^^^^^^^^^^^ asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiocqhttp\api_impl.py", line 104, in fetch return await asyncio.wait_for(future, timeout_sec) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 492, in wait_for raise exceptions.TimeoutError() from exc TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "D:\apps\qqBot\AstrBot\astrbot\bootstrap.py", line 101, in handle_task result = await task ^^^^^^^^^^ aiocqhttp.exceptions.NetworkError: WebSocket API call timeout`

你愿意提交 PR 吗?

Code of Conduct

Soulter commented 2 months ago

这可能是由于在上传图片时网络较慢等因素造成消息超时,也可能是目前 astrbot 中某些同步方法阻塞了事件循环。在最新的代码提交中暂时提高了 asyncio 超时时间到 180s 作为补救,但是在找到原因之前不会单独为此发一个新版本,可以打开 model/platform/qq_aiocqhttp.py 文件,找到(大概在 80 行左右)

self.bot = CQHttp(use_ws_reverse=True, import_name='aiocqhttp')

这一行,将其改成:

self.bot = CQHttp(use_ws_reverse=True, import_name='aiocqhttp', api_timeout_sec=180)

(或者直接拉取代码)

同时,可以在你的插件代码中使用 try...except 语句在捕获到异常后重试 n 次:

    async def send_qq_msg(self):
        await asyncio.sleep(5)
        while True:
            now = datetime.now()
            for send_time in send_times:
                # send
                if now.hour != send_time:
                    continue
                retry = 0
                while retry < 3:
                    try:
                        await self.send_msg()
                        break
                    except Exception as e:
                        logger.error(e)
                        logger.error(f"发送消息失败, 5秒后重试。次数: {retry}/3")
                        await asyncio.sleep(5)
                        retry += 1
            await asyncio.sleep(3400)
github-actions[bot] commented 3 weeks ago

Stale issue message