外观
实时连接
各平台 SDK 已负责连接、续票、心跳和断线恢复,宿主通常只需要 SDK 登录与状态订阅。只有开发传输适配层或排查协议时才需要直接操作 WebSocket。
连接地址
生产环境使用 wss://example.com/ws。服务器可在后台配置 WebSocket URL;未指定时 SDK 从 HTTP 服务地址派生同域 /ws。反向代理需要支持 Upgrade,公网入口最终转到 Gateway 的 /ws,握手 URL 不携带 query 参数,也不在 URL 中附加 Token。
应用帧为 UTF-8 JSON 文本,单帧最大 65536 字节;二进制业务帧不受支持。不要使用 Socket.IO 协议。
首帧认证
WebSocket 建立后发送唯一认证首帧:
json
{"action":"auth","request_id":"auth-20261018-01","data":{"token":"<IM Token>"}}| 字段 | 规则 |
|---|---|
| action | 固定 auth |
| request_id | 1–128 位字母、数字、.、_、:、-,用于匹配此次握手 |
| data.token | 已由宿主后端获取的 IM Token |
顶层只能有 action、request_id、data,data 只能有 token;客户端不提交 uid、用户资料或频道。服务端要求握手后 10 秒内完成首帧认证,SDK 对从发起连接到收到匹配 ready 的客户端总截止为 3 秒,两者用途不同。
成功:
json
{"event_id":"evt_19b48fb18b20408fb9402173afc1462f","event":"connection.ready","sent_at":1792301400000,"data":{"request_id":"auth-20261018-01","user_id":"chenyue","heartbeat_interval_ms":25000}}必须检查 request_id 与 user_id 属于当前连接和当前账号。收到新的 ready 后执行会话同步,当前可见聊天还需独立读取消息,详见恢复流程。
失败示例:
json
{"event_id":"evt_d5ef76f8b96d4d9fb294915fdc760da4","event":"connection.error","sent_at":1792301400000,"data":{"request_id":"auth-20261018-01","code":1103,"msg":"token expired","retryable":false}}request_id 可为 null。服务端发出错误后关闭连接;1103 通过宿主后端换票后重新认证,不要用同一个过期 Token 反复连接。错误码与HTTP 约定一致。
心跳
优先使用平台支持的标准 WebSocket Ping/Pong。浏览器和 HarmonyOS 的传输适配层收到 ready 后,按 heartbeat_interval_ms 发送精确文本 1,等待精确文本 2。这是传输心跳,不是 JSON 字符串、事件或业务命令。前台恢复可用它探测既有连接;超时则关闭并重连。
每次重连重新发送 auth。SDK 失败后的发起间隔为 1 秒、2 秒、3 秒,并考虑已消耗的连接时间。不要因连接断开就立即清空当前可读消息。
输入状态
认证后目前只有 typing.update 这一种客户端业务命令。消息发送、已读、群操作与通话控制走 HTTP。
json
{"action":"typing.update","request_id":"typing-20261018-01","data":{"conversation_id":"friend_bGluemhvdQ","typing":true}}data 必须且只能有 conversation_id 和 typing,typing 必须为 JSON boolean。仅支持单聊,并受双方关系、能力和屏蔽状态约束。正在输入时约每 2 秒刷新一次,结束/离开时发送 false;接收方在 expires_at(约 5 秒租约)到期后隐藏提示。没有单独的成功确认事件;非法命令可返回 connection.error 并关闭。
事件信封
服务端业务事件固定为 event_id、event、sent_at、data:
json
{
"event_id": "evt_50de9dbeb6bb4cf2ab7c075fc8b9f006",
"event": "profile.updated",
"sent_at": 1792301400000,
"data": {
"user": {
"id": "1025",
"user_id": "linzhou",
"username": "linzhou",
"nickname": "林舟",
"avatar": "https://example.com/uploads/avatars/linzhou.jpg",
"signature": "把每一次出发安排妥当",
"profile_updated_at": 1792301400000
},
"relation": null
}
}event_id 为不透明去重标识,sent_at 为 Unix 毫秒。事件里的完整对象与 HTTP 相同;不要收到事件后逐个请求用户、群或消息详情。事件列表与差异见事件参考。
