From 2dc71079908c7c239790cf7514ba74a46120f27c Mon Sep 17 00:00:00 2001 From: AkiraXie Date: Wed, 24 Mar 2021 19:52:47 +0800 Subject: [PATCH 1/2] :memo: update hook docs --- docs/advanced/README.md | 18 +++++-- docs/advanced/runtime-hook.md | 95 +++++++++++++++++++++++++++++++---- 2 files changed, 99 insertions(+), 14 deletions(-) diff --git a/docs/advanced/README.md b/docs/advanced/README.md index 6d34007c..6bdba844 100644 --- a/docs/advanced/README.md +++ b/docs/advanced/README.md @@ -10,9 +10,17 @@ **便捷起见,以下内容对 `Nonebot2` 会被称为 `nonebot`,与 `Nonebot2` 交互的机器人实现会被称为 `协议端`**。 -在实际应用中,`nonebot` 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 `http`, `websocket` 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 `nonebot`,`nonebot` 会处理数据并返回响应给协议端;另一方面,`nonebot` 可以主动推送数据给协议端。而 `nonebot` 便是围绕上述的双向通信进行工作的。 +在实际应用中,`nonebot` 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 `http`, `websocket` 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 `nonebot`,`nonebot` 会处理数据并返回响应给协议端;另一方面,`nonebot` 可以主动推送数据给协议端。而 `nonebot` 便是围绕双向通信进行工作的。 -在开始工作之前,`nonebot` 会依照**配置文件或初始化配置**启动,并会注册**协议适配器** `adapter`,之后便会加载**插件**, 随后,倘若一个协议端与 `nonebot` 进行了连接,`nonebot` 的后端驱动 `driver` 就会将 `adapter` 实例化为 `bot`,`nonebot` 便会利用 `bot` 开始工作,它的工作内容分为两个方面: +在开始工作之前,`nonebot` 需要进行准备工作: + +1. **运行 `nonebot.init` 初始化函数**,它会读取配置文件,并初始化 `nonebot` 和后端驱动 `driver` 对象。 +2. **注册协议适配器 `adapter`** 。 +3. **加载插件**。 + +准备工作完成后,`nonebot` 会利用 `uvicorn` 启动,并运行 `on_startup` 钩子函数。 + +随后,倘若一个协议端与 `nonebot` 进行了连接,`nonebot` 的后端驱动 `driver` 就会将 `adapter` 实例化为 `bot`,`nonebot` 便会利用 `bot` 开始工作,它的工作内容分为两个方面: 1. **事件处理**,`bot` 会将协议端上报的数据转化为 `事件`(`Event`),之后 `nonebot` 会根据一套既定流程来处理 `事件`。 @@ -41,7 +49,7 @@ 1. 协议端会通过 `websocket` 或者 `http` 等方式与 `nonebot` 的后端驱动 `driver` 连接,`driver` 会根据之前注册的 `adapter` 和配置文件的内容来进行鉴权,从而获得这个连接的唯一识别 id `self-id`,随后 `adapter` 就会利用 `self-id` 实例化为 `bot` 对象。 ::: tip - 需要注意的是,如果协议端通过 `websocket` 与 `nonebot` 连接,这个步骤只会在建立连接时进行;通过 `http` 方式连接时,会在协议端每次上报数据时都进行这个步骤。 + 需要注意的是,如果协议端通过 `websocket` 与 `nonebot` 连接,这个步骤只会在建立连接时进行,并在之后运行 `on_bot_connect` 钩子函数;通过 `http` 方式连接时,会在协议端每次上报数据时都进行这个步骤。 ::: ::: warning @@ -142,7 +150,7 @@ 这个异常可以在 `handler` 中由 `Matcher.reject` 抛出。 - 当 `nonebot` 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将**当前 handler 和后续 `handler`**交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行当前 `handler` 和后续的 `handler`。 + 当 `nonebot` 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将当前 handler 和后续 `handler` 交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行当前 `handler` 和后续的 `handler`。 4. **FinishedException** @@ -158,7 +166,7 @@ ## 调用 API -`nonebot` 可以通过 `bot` 来调用 API,API 可以向协议端发送数据,也可以向协议端请求更多的数据。 +`nonebot` 可以通过 `bot` 来调用 `API` ,`API` 可以向协议端发送数据,也可以向协议端请求更多的数据。 ::: tip 不同 `adapter` 规定了不同的 API,对应的 API 列表请参照协议规范。 diff --git a/docs/advanced/runtime-hook.md b/docs/advanced/runtime-hook.md index 9145cd8f..c5d6918e 100644 --- a/docs/advanced/runtime-hook.md +++ b/docs/advanced/runtime-hook.md @@ -4,12 +4,77 @@ > 钩子编程(hooking),也称作“挂钩”,是计算机程序设计术语,指通过拦截软件模块间的函数调用、消息传递、事件传递来修改或扩展操作系统、应用程序或其他软件组件的行为的各种技术。处理被拦截的函数调用、事件、消息的代码,被称为钩子(hook)。 -在 `nonebot2` 中有一系列预定义的钩子函数,这些函数位于 [`nonebot.message`](https://v2.nonebot.dev/api/message.html) 模块下,我们可以以装饰器的形式利用这些函数,进行以下四种操作: +在 `nonebot2` 中有一系列预定义的钩子函数,分为两类:`全局钩子函数` 和 `事件钩子函数` ,这些钩子函数可以用装饰器的形式来使用。 -:::warning 注意 -1.在钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()` +## 全局钩子函数 + +全局钩子函数是指 `nonebot2` 针对其本身运行过程的钩子函数。 + +这些钩子函数是由其后端驱动 `driver`来运行的,故需要先获得全局 `driver` 对象: + +```python +from nonebot import get_driver + + +driver=get_driver() +``` + +共分为四种函数: + +### 启动准备 + +这个钩子函数会在 `nonebot2` 启动时运行。 + +```python +@driver.on_startup +async def do_something(): + pass +``` + +### 终止处理 + +这个钩子函数会在 `nonebot2` 终止时运行。 + +```python +@driver.on_shutdown +async def do_something(): + pass +``` + +### bot 连接处理 + +这个钩子函数会在 `bot` 通过 `websocket` 连接到 `nonebot2` 时运行。 + +```python +@driver.on_bot_connect +async def do_something(bot: Bot): + pass +``` + +### bot 断开处理 + +这个钩子函数会在 `bot` 断开与 `nonebot2` 的`websocket` 连接时运行。 + +```python +@driver.on_bot_disconnect +async def do_something(bot: Bot): + pass +``` + +## 事件处理钩子 + +这些钩子函数指的是影响 `nonebot2` 进行 `事件处理` 的函数。 + +:::tip 提示 + +关于 `事件处理` 的流程,可以在[这里](./README)查阅。 + +::: + +:::warning 注意 1.在事件处理钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()` + +2.如果需要在事件处理钩子函数中打断整个对话的执行,请参考以下范例: -2.如果需要在钩子函数中打断整个对话的执行,请参考以下范例: ```python from nonebot.exception import IgnoredException @@ -18,9 +83,14 @@ from nonebot.exception import IgnoredException async def do_something(bot: Bot, event: Event, state: T_State): raise IgnoredException("reason") ``` + ::: -## 事件预处理 +共分为四种函数: + +### 事件预处理 + +这个钩子函数会在 `Event` 上报到 `nonebot2` 时运行 ```python from nonebot.message import event_preprocessor @@ -30,7 +100,9 @@ async def do_something(bot: Bot, event: Event, state: T_State): pass ``` -## 事件后处理 +### 事件后处理 + +这个钩子函数会在 `nonebot2` 处理 `Event` 后运行 ```python from nonebot.message import event_postprocessor @@ -40,7 +112,9 @@ async def do_something(bot: Bot, event: Event, state: T_State): pass ``` -## 运行预处理 +### 运行预处理 + +这个钩子函数会在 `nonebot2`运行 `matcher` 前运行。 ```python from nonebot.message import run_preprocessor @@ -50,11 +124,14 @@ async def do_something(matcher: Matcher, bot: Bot, event: Event, state: T_State) pass ``` -## 运行后处理 +### 运行后处理 + +这个钩子函数会在 `nonebot2`运行 `matcher` 后运行。 + ```python from nonebot.message import run_postprocessor @run_postprocessor async def do_something(matcher: Matcher, exception: Optional[Exception], bot: Bot, event: Event, state: T_State): pass -``` \ No newline at end of file +``` From 430b3467cc6268447aaea069be5c7265435e09f1 Mon Sep 17 00:00:00 2001 From: AkiraXie Date: Wed, 24 Mar 2021 20:04:48 +0800 Subject: [PATCH 2/2] :memo: fix typo --- docs/advanced/runtime-hook.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/advanced/runtime-hook.md b/docs/advanced/runtime-hook.md index c5d6918e..7d157891 100644 --- a/docs/advanced/runtime-hook.md +++ b/docs/advanced/runtime-hook.md @@ -53,7 +53,7 @@ async def do_something(bot: Bot): ### bot 断开处理 -这个钩子函数会在 `bot` 断开与 `nonebot2` 的`websocket` 连接时运行。 +这个钩子函数会在 `bot` 断开与 `nonebot2` 的 `websocket` 连接时运行。 ```python @driver.on_bot_disconnect @@ -71,7 +71,9 @@ async def do_something(bot: Bot): ::: -:::warning 注意 1.在事件处理钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()` +:::warning 注意 + +1.在事件处理钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()` 2.如果需要在事件处理钩子函数中打断整个对话的执行,请参考以下范例: