Skip to content

传输层

QimenBot 支持多种传输方式连接不同协议实现。传输层负责底层通信,与上层协议逻辑解耦;官方 QQ Bot 由于 Gateway 和 OpenAPI 强绑定,使用独立的协议传输封装。

传输模式概览

模式方向说明适用场景
WS 正向框架 → OneBot框架主动连接 OneBot 的 WebSocket最常用,配置简单
WS 反向OneBot → 框架框架监听,OneBot 连接过来框架在公网时
HTTP API框架 → OneBot通过 HTTP 调用 API简单场景
HTTP POSTOneBot → 框架OneBot 推送事件到框架配合 HTTP API 使用
Gateway框架 → 官方 QQ BotGateway 收事件,OpenAPI 发动作官方 QQ Bot

正向 WebSocket(推荐)

框架主动连接 OneBot 实现提供的 WebSocket 端点。

配置

toml
[[bots]]
id        = "qq-main"
protocol  = "onebot11"
transport = "ws-forward"
endpoint  = "ws://127.0.0.1:3001"   # OneBot WS 地址
# access_token = "your-token"       # 可选鉴权

工作流程

QimenBot                    OneBot 实现
    |                           |
    |--- WebSocket CONNECT ---->|
    |<-- 101 Switching ---------|
    |                           |
    |<-- Event (JSON) ----------|  收到消息
    |--- Action (JSON) -------->|  发送操作
    |<-- Action Response -------|  操作结果
    |                           |

自动重连

连接断开后框架会自动重连,使用指数退避策略:

重试次数等待时间
11 秒
22 秒
34 秒
48 秒
......
最大60 秒

连接稳定运行一段时间后退避计数器自动重置。

TLS 支持

使用 wss:// 前缀启用 TLS 加密连接:

toml
endpoint = "wss://bot.example.com:3001"

反向 WebSocket

框架监听端口,等待 OneBot 实现连接过来。

配置

toml
[[bots]]
id        = "qq-reverse"
protocol  = "onebot11"
transport = "ws-reverse"
bind      = "0.0.0.0:6701"          # 监听地址
path      = "/onebot/reverse"       # WebSocket 路径
# access_token = "your-token"       # 可选鉴权

工作流程

QimenBot                    OneBot 实现
    |                           |
    |<-- WebSocket CONNECT -----|  OneBot 主动连接
    |--- 101 Switching -------->|
    |                           |
    |<-- Event (JSON) ----------|
    |--- Action (JSON) -------->|
    |                           |

适用场景

  • 框架部署在公网服务器,OneBot 实现在内网
  • 一个框架监听端口,多个 OneBot 实现连接
  • 防火墙只允许出站连接的环境

HTTP 传输

HTTP 模式将事件接收和 API 调用分为两个方向。

配置

toml
[[bots]]
id        = "qq-http"
protocol  = "onebot11"
transport = "http"
endpoint  = "http://127.0.0.1:5700"  # OneBot HTTP API 地址
# bind    = "0.0.0.0:5701"           # 事件接收地址

工作流程

事件推送 (HTTP POST):
OneBot --POST /event--> QimenBot

API 调用 (HTTP):
QimenBot --POST /send_msg--> OneBot
         <-- JSON Response --

官方 QQ Bot Gateway

官方 QQ Bot 与 OneBot 的传输模型不同:事件通过 Gateway WebSocket 下发,发送消息、上传媒体、撤回消息通过 HTTP OpenAPI 完成。因此配置上使用 protocol = "qq-official"transport = "gateway"

配置

toml
[[bots]]
id        = "qq-official"
protocol  = "qq-official"
transport = "gateway"
enabled   = true

appid = "${QQBOT_APPID}"
secret = "${QQBOT_SECRET}"
sandbox = false
intents = ["public_messages", "public_guild_messages", "direct_message"]

工作流程

QimenBot                         QQ Bot OpenAPI
    |                                  |
    |--- POST /app/getAppAccessToken ->|  AppID + Secret
    |<-- access_token -----------------|
    |--- GET /gateway/bot ------------>|  获取 Gateway URL
    |<-- wss://... --------------------|
    |                                  |
    |=== WebSocket Gateway ============|
    |<-- Hello ------------------------|
    |--- Identify / Resume ----------->|
    |<-- Dispatch(Message/Notice) -----|  收到事件
    |--- Heartbeat ------------------->|
    |<-- Heartbeat ACK ----------------|
    |                                  |
    |--- POST /messages -------------->|  插件回复或主动发送
    |<-- message response -------------|

Intents

intent覆盖事件
public_messagesQQ 群 @ 消息、QQ 单聊 C2C 消息
public_guild_messages频道 @ 消息
direct_message频道私信消息

没有开启对应 intent 时,Gateway 能连接成功,但收不到相关事件。

错误与频控

官方 OpenAPI 发送失败会被归一化为失败动作响应,Gateway 会话不会因此断开。429 频控会读取 retry_after 信息并对 bot + route 做短期 backoff;backoff 期间同路由发送会直接返回失败响应,避免持续撞频控。

Echo 关联

WebSocket 传输中,框架使用 echo 字段将请求与响应关联:

json
// 发送请求
{"action": "send_msg", "params": {...}, "echo": "req-001"}

// 收到响应
{"status": "ok", "data": {...}, "echo": "req-001"}

框架内部维护一个 pending 请求映射表,根据 echo 值将响应路由到对应的等待者。

Access Token 鉴权

通过 access_token 字段配置鉴权:

toml
access_token = "your-secret-token"
# 或使用环境变量
access_token = "${QQ_TOKEN}"
  • WS 正向 — Token 作为 URL 参数传递
  • WS 反向 — 验证连接时的 Authorization 头
  • HTTP — 作为请求头或参数传递

传输层类型

OneBot11ForwardWsClient

正向 WebSocket 客户端:

rust
pub struct OneBot11ForwardWsClient {
    // 内部字段
}

impl OneBot11ForwardWsClient {
    /// 连接到 OneBot WS 端点
    pub async fn connect(endpoint: &str, access_token: Option<&str>) -> Result<Self>;

    /// 接收下一个事件
    pub async fn next_event(&mut self) -> Option<String>;

    /// 发送文本帧
    pub async fn send_text(&self, text: &str) -> Result<()>;

    /// 发送并等待 echo 响应
    pub async fn send_text_await_echo(
        &self,
        text: &str,
        echo: &str,
        timeout: Duration,
    ) -> Result<String>;
}

WsReverseServer

反向 WebSocket 服务端:

rust
pub struct WsReverseServer {
    // 内部字段
}

impl WsReverseServer {
    /// 绑定并监听
    pub async fn bind(config: WsReverseConfig) -> Result<Self>;

    /// 接收下一个事件
    pub async fn next_event(&mut self) -> Option<String>;
}

ReconnectPolicy

重连策略:

rust
pub struct ReconnectPolicy {
    pub initial_delay: Duration,                 // 初始等待时间
    pub max_delay: Duration,                     // 最大等待时间
    pub stable_connection_threshold: Duration,   // 稳定连接阈值
    pub idle_timeout: Duration,                  // 空闲超时
}

QqBotGatewayClient

官方 QQ Bot Gateway 客户端位于 qimen-transport-qqbot

rust
pub struct QqBotGatewayClient {
    // 维护 access token、Gateway URL、session_id、seq、heartbeat 和 shard 状态
}

它复用底层 WebSocket 能力,但把官方协议相关的 token、opcode、Identify、Resume、Heartbeat、OpenAPI endpoint 和错误分类都限制在 qimen-transport-qqbot 内,避免污染通用 WebSocket 传输层。

选择建议

场景推荐
本地开发WS 正向(配置最简单)
生产部署(同机器)WS 正向
生产部署(跨网络)WS 反向(框架在公网)
不需要实时推送HTTP
需要高可靠性WS 正向 + 自动重连
接入官方 QQ BotGateway

基于 MIT 许可证发布