# WebSocket 方式

# 发起连接到 Gateway

第一步先调用 获取通用WSS 接入点 或 获取带分片WSS 接入点 接口获取网关地址。

会得到一个类似下面这样的地址:

wss://api.bot.qq.com/websocket/
1

然后进行 websocket 长连接建立,一旦连接成功,就会返回 OpCode 10 Hello 消息。这个消息主要的内容是心跳周期,单位毫秒(milliseconds),如下:

{
  "op": 10,
  "d": {
    "heartbeat_interval": 45000
  }
}
1
2
3
4
5
6

# 登录鉴权获得 Session

websocket 长连接建立之后,需要进行登录鉴权,登录鉴权成功后会获得一个 session 会话 id,只有登录成功后,QQ 后台才会下发事件通知。

发送一个 OpCode 2 Identify 消息,payload 如下:

{
  "op": 2,
  "d": {
    "token": "token string",
    "intents": 513,
    "shard": [0, 4],
    "properties": {
      "$os": "linux",
      "$browser": "my_library",
      "$device": "my_library"
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
字段 描述
token 格式为 "QQBot {AccessToken}"
intents 是此次连接所需要接收的事件,具体可参考 事件订阅 Intents
shard 考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,该参数是个拥有两个元素的数组。例如:[0,4],代表分为四个片,当前链接是第 0 个片,业务稍后应该继续建立 shard 为 [1,4], [2,4], [3,4] 的链接,才能完整接收事件,更多详细的内容可以参考 Shard 机制。若无需分片,使用 [0, 1] 即可。
properties 目前无实际作用,可以按照自己的实际情况填写,也可以留空

鉴权成功之后,QQ 后台会下发一个 Ready Event,payload 如下:

{
  "op": 0,
  "s": 1,
  "t": "READY",
  "d": {
    "version": 1,
    "session_id": "082ee18c-0be3-491b-9d8b-fbd95c51673a",
    "user": {
      "id": "6158788878435714165",
      "username": "群pro测试机器人",
      "bot": true
    },
    "shard": [0, 0]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 发送心跳 Ack

鉴权成功之后,就需要按照周期进行心跳发送。d 为客户端收到的最新的消息的 s,如果是首次连接,d 为传 null,payload 如下:

{
  "op": 1,
  "d": 251
}
1
2
3
4

心跳发送成功之后会收到 OpCode 11 Heartbeat ACK 消息,payload 如下:

{
  "op": 11
}
1
2
3

# 恢复登录态 Session

有很多原因可能会导致 websocket 长连接断开,断开之后短时间内重连会补发中间遗漏的事件,以保障业务逻辑的正确性。断开重连 gateway 后不需要发送重新登录 OpCode 2 Identify 请求。在连接到 Gateway 之后,需要发送 OpCode 6 Resume 消息,payload 如下:

{
  "op": 6,
  "d": {
    "token": "my_token",
    "session_id": "session_id_i_stored",
    "seq": 1337
  }
}
1
2
3
4
5
6
7
8

其中 seq 指的是在接收事件时候的 s 字段,我们推荐开发者在处理过事件之后记录下 s 这样可以在 resume 的时候传递给 websocket,websocket 会自动补发这个 seq 之后的事件。

恢复成功之后,就开始补发遗漏事件,所有事件补发完成之后,会下发一个 Resumed Event,payload 如下:

{
  "op": 0,
  "s": 2002,
  "t": "RESUMED",
  "d": ""
}
1
2
3
4
5
6

# 分片连接 LoadBalance

随着 bot 的增长并被添加到越来越多的频道中,事件越来越多,业务有必要对事件进行水平分割,实现负载均衡。机器人网关实现了一种用户可控制的分片方法,该方法允许跨多个网关连接拆分事件。分片完全由用户控制,并且不需要在单独的连接之间进行状态共享。

要在连接上启用分片,需要在建立连接的时候指定分片参数,具体参考 gateway

# 获得合适的分片数

使用 /gateway/bot 接口获取网关地址的时候,会同时返回一个建议的 shard 数,及最大并发限制。

{
  "url": "wss://api.bot.qq.com/websocket",
  "shards": 1,
  "session_start_limit": {
    "total": 1000,
    "remaining": 1000,
    "reset_after": 86400000,
    "max_concurrency": 1
  }
}
1
2
3
4
5
6
7
8
9
10

# 分片规则

分片是按照频道 id 进行哈希的,同一个频道的信息会固定从同一个链接推送。具体哈希计算规则如下:

shard_id = (guild_id >> 22) % num_shards
1

# 最大连接数

每个机器人创建的连接数不能超过 remaining 剩余连接数。

# WebSocket 错误码

值 含义 是否可以重试 RESUME 是否可以重试 IDENTIFY
4001 无效的 opcode 否 否
4002 无效的 payload 否 否
4007 seq 错误 否 是
4006 无效的 session id,无法继续 resume,请 identify 否 是
4008 发送 payload 过快,请重新连接,并遵守连接后返回的频控信息 是 是
4009 连接过期,请重连并执行 resume 进行重新连接 是 是
4010 无效的 shard 否 否
4011 连接需要处理的 guild 过多,请进行合理的分片 否 否
4012 无效的 version 否 否
4013 无效的 intent 否 否
4014 intent 无权限 否 否
4900~4913 内部错误,请重连 否 是
4914 机器人已下架,只允许连接沙箱环境,请断开连接,检验当前连接环境 否 否
4915 机器人已封禁,不允许连接,请断开连接,申请解封后再连接 否 否

针对 WebSocket 错误码的简单处理逻辑:

  • 4009 可以重新发起 resume
  • 4914,4915 不可以连接,请联系官方解封
  • 其他错误,请重新发起 identify
上次更新: 7/30/2026, 10:21:27 PM
手机QQ扫码
开发者社区
加入官方频道开发者社区