# 整体架构 了解 melobot 的核心架构与简单工作细节是介绍更多内容的基本前提。下图展示了 melobot 的核心架构层: ```{image} /_static/main-framework.png :alt: main-framework :width: 250px :align: center ``` melobot 的核心理念是获取输入,经过处理,产生输出。因此理论上任何可以被抽象为 IO 的操作,都可以写出对应的扩展。 melobot 将各种格式、规范或风格的输入输出行为都抽象为 melobot 规范的“协议”。对于协议的输入部分,抽象为“事件”来处理,而对于协议的输出部分,抽象为“行为”来处理。而对于输出可能产生的返回值或状态信息,抽象为“回应”来处理。随后基于此构建了精细的处理流程。 接下来简单说明各层的具体功能,此部分较为抽象,阅后有所印象即可。 ## 输入输出层 输入层主要包含一类部件:源。源对象分为两种:输入源,输出源。当一个源对象同时实现了输入源和输出源的功能时,称为输入输出源。 **每个源对象类只能对应一种协议。而每种协议至少有一个源对象类。** 输入源产生或从某处接收数据,并将这些数据转为“输入包”(输入实体),传递给上层的适配器处理。输出源接收来自上层适配器的“输出包”(输出实体),将其转换为数据输出到某处,或产生一些具体操作。 例如: - `melobot.protocols.console` 协议:输入源读取控制台 stdin 作为输入数据,输出源将输出数据写入控制台 stdout 或 stderr - `melobot.protocols.onebot` 协议:输入源与 OneBot 实现端通信获取输入数据,输出源与 OneBot 实现端通信发送操作 输出源对象在接收输出包完成“输出”操作后,会返回一个“回应包”给适配器,适配器就知道是否应该产生“回应”,或产生怎样的“回应”。 ## 适配器层 适配器层主要包含一类部件:适配器。 **每个适配器对象类只能对应一种协议;而每种协议必须有且只有一个适配器对象类。** 适配器主要负责三件事: 1. 将来自输入源的输入包转化为符合 melobot 规范的“事件” 2. 提供产生“行为”的方法或工具。在产生“行为”后,转化为“输出包”传递给输出源 3. 决定“行为”是否产生“回应”,如果产生还需传递给“行为”给发起行为的调用处 产生的事件、行为、回应必须且只能对应一种协议。 ```python # 所有适配器都会产生继承 RootEvent 基类型的事件 from melobot.handle import Event as RootEvent # 例如 OneBotEvent 就是继承于此,但内部可能有更细的继承关系 from melobot.protocols.onebot.v11 import Event as OneBotEvent # 例如再继承并细化得到 MessageEvent 事件 from melobot.protocols.onebot.v11 import MessageEvent ``` ```python from melobot.protocols.onebot.v11 import Adapter, on_message @on_message() async def _(adapter: Adapter) -> None: # 让适配器产生行为操作 handle_group = await adapter.send(...) # 因为 OneBot 适配器总是产生回应,因此你总是可以拿到回应对象 echo = await handle_group[0] assert echo is not None ``` ## 处理流层 处理流层实现了处理流的创建、运行和销毁。 所有事件在被他们的适配器创建出来后,会被统一送到 melobot 的分发部件。它们将按照处理流规则,在这里被分发给不同的处理流。 处理流对象可以容纳很多处理结点,从而形成一个图结构。事件处理的过程,其实就是遍历各个处理结点的过程。而在处理流运行时,也可以进入其他流形成嵌套处理,因此是十分灵活的。 ```{admonition} 提示 :class: tip 为了保证遍历的顺利进行,处理流内部的图是有向无环图结构(DAG)。 ``` melobot 允许你自行搭建处理流。而处理流对象本身是无状态的,这意味着可以在多处复用。 为了避免频繁的手动创建处理流,melobot 提供了注册函数为处理流的方法,也就是早期提到的“事件绑定方法”。 ```python # 以下所有装饰器方法,本质上都是从函数生成单结点处理流对象 from melobot.handle import on_event, on_start_match from melobot.protocols.onebot.v11 import on_message async def process_func(...) -> None: ... def process_func2(...) -> None: ... flow1 = on_event(process_func) flow2 = on_message(process_func2) ``` ## 会话控制层 会话控制层实现了会话的生成、维持和销毁。 会话是事件处理的高级形态。会话机制提供了对事件序列(不同时间点发生的事件形成的序列)的处理,并保证安全、高效的并发,还让事件处理过程变得拥有“交互性”。 只能在处理流运行过程中进入会话。但处理流不会主动进入会话,进入会话必须手动调用相关方法,或在“事件绑定方法”中指定相关参数。 会话过程中的“暂停和恢复”完全依赖于会话规则,这赋予了会话管理无与伦比的自由性。 ## 插件管理层 插件管理层实现了插件声明的功能组件,并在 bot 运行时依靠这些声明创建插件。 插件管理层提供了用于组织 melobot 功能扩展的部件。melobot 插件机制的特点是: - 依靠异步依赖的自动满足,因此可以无序加载。 - 可以在指定的 bot 生命周期后,在任何位置动态加载。 - 依靠共享对象,实现无导入依赖的跨插件数据传递 - 依靠导出函数,实现无导入依赖的跨插件通信 ## bot 管理层 bot 管理层实现了 melobot 外层的重要接口,并统一地封装到 bot 对象中。 包含的功能有: - 添加指定协议的输入、输出源 - 添加指定协议的适配器 - 加载插件 - 提供一些动态功能的接口 - 查询或获取一些内部对象 此外,bot 对象也用于启动和管理整个 bot 程序。 ## 总结 本篇主要说明了 melobot 各层的功能及一些工作细节。 下一篇将重点说明:bot 的生命周期。