Skip to content

框架生命周期与元事件流 ​

编写一个优秀的常驻插件,绝不仅仅是“有人发消息就回一句”这么简单哦!什么时候初始化后台巡检协程?Bot 断线重连后如何恢复?这些都要交给生命周期系统。

Eridanus 的事件体系由底层 SDK(developTools/event/)定义,并由框架核心 ExtendBot 进行全局生命周期流控制。

1. 核心生命周期时序 ​

text
[主进程启动] 
     ↓
[YAMLManager 加载全部配置]
     ↓
[PluginManager 扫描并装载插件 main(bot, config)]
     ↓
[WebSocket 建立连接并鉴权成功]
     ↓
[广播 LifecycleMetaEvent (sub_type="enable" / "connect")]  ← 适合在此拉起常驻定时任务与轮询
     ↓
[持续消息监听与事件派发循环 (GroupMessageEvent / PrivateMessageEvent...)]
     ↓
[进程优雅退出或断开连接]

2. 监听 LifecycleMetaEvent 实现后台协程自启动 ​

许多功能(例如 B 站动态轮询、Git 更新检查、空间保活、定时清理临时文件)需要在机器人启动后自动拉起一个死循环协程。

千万不要在 def main(bot, config): 里直接写 asyncio.run() 或者无休止 while True(这会直接卡死主线程插件加载过程!)。正确的姿势是监听生命周期元事件:

python
import asyncio
from developTools.event.events import LifecycleMetaEvent

# 定义全局后台任务句柄,防止热重载时重复启动多份任务
background_task = None

async def my_worker_loop(bot, config):
    bot.logger.info("后台定时巡检任务已启动~")
    while True:
        try:
            # 业务轮询逻辑
            await asyncio.sleep(60)
        except asyncio.CancelledError:
            bot.logger.info("后台任务收到取消信号,优雅退出...")
            break
        except Exception as e:
            bot.logger.error(f"后台任务异常: {e}")
            await asyncio.sleep(5)

def main(bot, config):
    @bot.on(LifecycleMetaEvent)
    async def on_lifecycle(event: LifecycleMetaEvent):
        global background_task
        # 仅在 Bot 建立连接就绪阶段启动后台任务
        if background_task is None or background_task.done():
            background_task = asyncio.create_task(my_worker_loop(bot, config))

3. ExtendBot 框架级过滤机制 ​

框架派发给插件的事件已经过 ExtendBot(framework_common/framework_util/websocket_fix.py)的三重过滤:

  1. 黑名单过滤:发信人 QQ 或群号如果在 black_and_white_list.yaml 的黑名单中,消息直接在最底层丢弃,永远不会触发插件逻辑;
  2. 白名单模式:如果开启了全局群白名单,非白名单群的消息一律静默忽略;
  3. 执行耗时监控 (HandlerMonitor):每个插件回调的执行时间均受监控,如果某个插件阻塞超过设定的秒数(默认 10 秒),日志会输出黄色警告并附带插件文件路径,帮助你快速定位慢查询或网络卡死问题!