Bot断开事件问题:如何在Bot停止时关闭数据库连接?
解决Bot停止时无法关闭数据库连接的问题
你的on_disconnect监听器失效,是因为按下Ctrl+C属于强制中断程序,这种场景下Discord.py不会触发on_disconnect事件——这个事件只在Bot和Discord网关正常断开时才会触发。
给你两个靠谱的解决方法:
方法一:重写Bot的close方法
直接在自定义Bot类里重写close方法,让Bot在关闭前自动执行数据库连接关闭操作,不管是正常退出还是Ctrl+C触发的终止,都会走这个流程:
from discord.ext import commands class MyBot(commands.Bot): async def close(self) -> None: # 先关闭数据库连接 await database.close_connection() # 再执行Bot原本的关闭逻辑 await super().close()
之后用这个自定义的MyBot类来创建你的Bot实例就行。
方法二:捕获中断信号
通过asyncio捕获系统的中断信号(比如Ctrl+C对应的SIGINT),在信号回调里手动关闭数据库和Bot:
import asyncio import signal from discord.ext import commands class MyBot(commands.Bot): async def setup_hook(self) -> None: # 获取当前事件循环 loop = asyncio.get_running_loop() # 注册SIGINT(Ctrl+C)和SIGTERM(系统终止信号)的处理 for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, lambda sig=sig: asyncio.create_task(self.handle_shutdown(sig))) async def handle_shutdown(self, sig): print(f"收到中断信号 {sig},开始关闭...") # 关闭数据库连接 await database.close_connection() # 关闭Bot await self.close()
注意事项
如果你的database.close_connection()是同步函数,记得用asyncio.to_thread包装成异步操作,避免阻塞事件循环:
await asyncio.to_thread(database.close_connection)
内容的提问来源于stack exchange,提问作者Илья Назаренко
相关产品推荐
相关产品推荐

