Skip to content

Commit 2a3d93a

Browse files
fix: clean up qq official websocket shutdown (#7395)
* fix: clean up qq official websocket shutdown fixes: #7259 * fix: do not catch KeyboardInterrupt/SystemExit Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
1 parent 571b571 commit 2a3d93a

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import botpy
1414
import botpy.message
1515
from botpy import Client
16+
from botpy.gateway import BotWebSocket
1617

1718
from astrbot import logger
1819
from astrbot.api.event import MessageChain
@@ -37,11 +38,37 @@
3738
logging.root.removeHandler(handler)
3839

3940

41+
class ManagedBotWebSocket(BotWebSocket):
42+
def __init__(self, session, connection: Any, client: botClient):
43+
super().__init__(session, connection)
44+
self._client = client
45+
46+
async def on_closed(self, close_status_code, close_msg):
47+
if self._client.is_shutting_down:
48+
logger.debug("[QQOfficial] Ignore websocket reconnect during shutdown.")
49+
return
50+
await super().on_closed(close_status_code, close_msg)
51+
52+
async def close(self) -> None:
53+
self._can_reconnect = False
54+
if self._conn is not None and not self._conn.closed:
55+
await self._conn.close()
56+
57+
4058
# QQ 机器人官方框架
4159
class botClient(Client):
60+
def __init__(self, *args: Any, **kwargs: Any) -> None:
61+
super().__init__(*args, **kwargs)
62+
self._shutting_down = False
63+
self._active_websockets: set[ManagedBotWebSocket] = set()
64+
4265
def set_platform(self, platform: QQOfficialPlatformAdapter) -> None:
4366
self.platform = platform
4467

68+
@property
69+
def is_shutting_down(self) -> bool:
70+
return self._shutting_down or self.is_closed()
71+
4572
# 收到群消息
4673
async def on_group_at_message_create(
4774
self, message: botpy.message.GroupMessage
@@ -100,6 +127,30 @@ def _commit(self, abm: AstrBotMessage) -> None:
100127
),
101128
)
102129

130+
async def bot_connect(self, session) -> None:
131+
logger.info("[QQOfficial] Websocket session starting.")
132+
133+
websocket = ManagedBotWebSocket(session, self._connection, self)
134+
self._active_websockets.add(websocket)
135+
try:
136+
await websocket.ws_connect()
137+
except Exception as e:
138+
if not self.is_shutting_down:
139+
await websocket.on_error(e)
140+
finally:
141+
self._active_websockets.discard(websocket)
142+
143+
async def shutdown(self) -> None:
144+
if self.is_shutting_down:
145+
return
146+
147+
self._shutting_down = True
148+
await asyncio.gather(
149+
*(websocket.close() for websocket in list(self._active_websockets)),
150+
return_exceptions=True,
151+
)
152+
await self.close()
153+
103154

104155
@register_platform_adapter("qq_official", "QQ 机器人官方 API 适配器")
105156
class QQOfficialPlatformAdapter(Platform):
@@ -542,5 +593,5 @@ def get_client(self) -> botClient:
542593
return self.client
543594

544595
async def terminate(self) -> None:
545-
await self.client.close()
546-
logger.info("QQ 官方机器人接口 适配器已被优雅地关闭")
596+
await self.client.shutdown()
597+
logger.info("QQ 官方机器人接口 适配器已被关闭")

astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,4 @@ async def terminate(self) -> None:
193193
f"Exception occurred during QQOfficialWebhook server shutdown: {exc}",
194194
exc_info=True,
195195
)
196-
logger.info("QQ 机器人官方 API 适配器已经被优雅地关闭")
196+
logger.info("QQ 机器人官方 API 适配器已经被关闭")

astrbot/dashboard/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,4 @@ def run(self):
451451

452452
async def shutdown_trigger(self) -> None:
453453
await self.shutdown_event.wait()
454-
logger.info("AstrBot WebUI 已经被优雅地关闭")
454+
logger.info("AstrBot WebUI 已经被关闭")

0 commit comments

Comments
 (0)