Skip to content

API 总览 ​

Chirp 在 TCP 或 WebSocket 上跑 Protocol Buffers。当前受支持的协议面围绕 chirp.gateway.Packet 展开。

实现状态请看 能力矩阵。部分 proto 消息为路线图或实验性服务而存在,不要默认它们受默认运行时支持。

接入前建议先读 接入避坑指南——发送节奏、消息长度、重复禁言、敏感词等服务端防线都会以专码拒收,裸协议接入方最容易在这些地方踩坑。

包格式 ​

TCP 和 WebSocket 承载同一份应用载荷:

TCP stream:
  [uint32_be payload_size][chirp.gateway.Packet protobuf bytes]

WebSocket binary frame payload:
  [uint32_be payload_size][chirp.gateway.Packet protobuf bytes]

payload_size 是序列化后的 chirp.gateway.Packet 的字节数。

MsgID 不是独立的网络帧头,它在 Packet 里面:

protobuf
message Packet {
  MsgID msg_id = 1;
  int64 sequence = 2;
  bytes body = 3;
}

body 装的是所选 msg_id 对应的序列化 protobuf 消息。

映射示例:

Packet 的 msg_idPacket 的 body protobuf
LOGIN_REQchirp.auth.LoginRequest(登录请求)
LOGIN_RESPchirp.auth.LoginResponse(登录应答)
HEARTBEAT_PINGchirp.gateway.HeartbeatPing(心跳请求)
HEARTBEAT_PONGchirp.gateway.HeartbeatPong(心跳应答)
SEND_MESSAGE_REQchirp.chat.SendMessageRequest(发送消息请求)
SEND_MESSAGE_RESPchirp.chat.SendMessageResponse(发送消息应答)
GET_HISTORY_REQchirp.chat.GetHistoryRequest(拉取历史请求)
GET_HISTORY_RESPchirp.chat.GetHistoryResponse(拉取历史应答)
CHAT_MESSAGE_NOTIFYchirp.chat.ChatMessage(聊天消息通知)

当前端点 ​

服务按游戏平面 / App 平面组织,二进制命名带平面前缀(完整对照见 能力矩阵 的二进制命名约定段)。

游戏平面(游戏客户端/游戏后端接入这里) ​

服务二进制TCPWebSocket状态说明
Game SDK Gatewaychirp_game_sdk_gateway50005001Supported登录、心跳、踢出、会话 claim;2xxx 聊天包经 ChatBridge 转发到 game_chat
Game Chatchirp_game_chat(由 services/shared/chat 构建)70007001Supported聊天服务端;游戏后端签发 token + --token_secret 本地验签,自足闭环
Game Server Gatewaychirp_game_server_gateway8100-Supported游戏后端注入枢纽:消息注入 + 事件下发,service_id + secret 信任门
Chat Peer 口(game_chat 的 --hub_peer_port)8200-Supportedgame_chat 作为 spoke 注册到 app_chat hub 的出站目标;见 peer 协议

App 平面(伴侣 App / 平台侧) ​

服务二进制TCPWebSocket状态说明
App SDK Gatewaychirp_app_sdk_gateway52005201Supported认证/心跳 + 6xxx 设备消息转发;2xxx 转发到 app_chat
App Chat(hub)chirp_app_chat(同 services/shared/chat 构建)70007001SupportedApp 平面聊天 hub:peer 注册、身份映射、频道订阅、跨平面 fan-out/回复、未读账本
App Authchirp_app_auth6000-SupportedApp 平面账号/token;游戏平面不依赖它
App Notificationchirp_app_notification50065016Supported设备注册表 + 推送面(6xxx);--push_transport http 启用真实 APNs/FCM HTTP 投递,默认 logging 只记日志

实验性服务 ​

服务TCPWebSocket状态
Social80008001Experimental(好友/在线状态/黑名单,不在最小验证路径内)
Voice90009001Experimental(信令面存在,尚不构成完整媒体后端保证)
Search5007-Experimental(代码在树里,不是核心路径)

核心消息 ID ​

网关与认证(Gateway/Auth,1xxx) ​

MsgID名称方向当前状态
1001HEARTBEAT_PING客户端 -> Gateway/ChatSupported
1002HEARTBEAT_PONGGateway/Chat -> 客户端Supported
1003LOGIN_REQ客户端 -> Gateway/ChatSupported
1004LOGIN_RESPGateway/Chat -> 客户端Supported
1005KICK_NOTIFYGateway/Chat -> 客户端Supported(同设备重登顶号)
1006 / 1007LOGOUT_REQ / LOGOUT_RESP客户端 <-> 服务Supported
1008-1019注册/密码登录/刷新 token/会话管理/改密客户端 <-> AuthApp 平面 auth 面 Supported;游戏平面不走这组

两个平面都接受 LOGIN_REQ;游戏平面的 token 由游戏后端按 HS256 JWT 签发、chat 以 --token_secret 本地验签。

聊天(Chat,2xxx) ​

发送链路在服务端经过一组顺序固定的防线(细节与默认阈值见 接入避坑指南):登录校验 → 模糊限流(RATE_LIMITED)→ 内容长度(CONTENT_TOO_LONG)→ 发送节奏(RATE_LIMITED)→ 重复禁言(RATE_LIMITED)→ 敏感词(WORD_FILTERED 或静默替换)。

MsgID名称方向说明
2001 / 2002SEND_MESSAGE_REQ / RESP客户端 -> Chat发送消息;RESP 带服务端 message_id 与业务码
2003 / 2004GET_HISTORY_REQ / RESP客户端 -> Chat拉取频道历史
2005CHAT_MESSAGE_NOTIFYChat -> 客户端实时消息推送
2101-2216群组全套客户端 <-> Chat建/进/出/邀/踢/查 + 群事件 notify(2117-2121)
2201 / 2202MARK_READ_REQ / RESP客户端 -> Chat标记已读(服务端游标)
2203 / 2204GET_READ_RECEIPTS_REQ / RESP客户端 -> Chat消息已读回执查询
2205 / 2206GET_UNREAD_COUNT_REQ / RESP客户端 -> Chat未读数
2207MESSAGE_READ_NOTIFYChat -> 客户端已读事件推送
2208TYPING_INDICATOR_NOTIFY客户端 <-> Chat正在输入(裸 notify,无响应)
2211 / 2212TRACK_MESSAGE_REQ / RESP客户端 -> Chat投递跟踪
2215-2222表情回应全套客户端 <-> Chat加/删/查 + 增删 notify
2223 / 2224GET_TYPING_USERS_REQ / RESP客户端 -> Chat谁在输入
2225-2232编辑/删除全套客户端 <-> Chat编辑、删除、批量删除 + 事件 notify;DELETE(is_hard_delete=false)对发送者本人即撤回(默认私聊/公会 120 秒窗口内的软删,超窗/非撤回频道/重复撤回回 INVALID_PARAM),版主删除不受窗口约束
2233 / 2234GET_MENTION_SUGGESTIONS_REQ / RESP客户端 -> Chat@提及候选
2235-2238频道屏蔽(免打扰)客户端 <-> ChatSET_CHANNEL_MUTE / GET_CHANNEL_MUTES;仅 WORLD/GUILD/TEAM 可屏蔽
2239-2244消息黑名单客户端 <-> ChatBLOCK/UNBLOCK_MESSAGE_SENDER、GET_BLOCKED_SENDERS;只作用于消息投递,与社交面 3011 黑名单互相独立

经 chirp_game_sdk_gateway / chirp_app_sdk_gateway 接入的客户端,2xxx 消息由 ChatBridge 转发到对应 chat 实例,语义与直连 chat 相同;游戏平面的跨平面拦截(内容前缀)与防线阈值同样生效。

社交/语音/实验面(3xxx/4xxx) ​

3001-3024(社交:好友/黑名单/在线状态)与 4001+(语音房)由实验性服务提供,不在受支持路径内;接入前先核对 能力矩阵。

服务面(Server plane,5xxx) ​

chirp_game_server_gateway(TCP 8100)在另一个信任面上用同一套 Packet 帧。peer 是游戏后端和内部服务,以 service_id + 共享 secret 认证——从来不是用户账号。

MsgID名称方向
5001 / 5002SERVER_AUTH_REQ / SERVER_AUTH_RESP服务 <-> 枢纽
5003 / 5004SERVER_HEARTBEAT_PING / PONG服务 <-> 枢纽
5005 / 5006 / 5007INJECT_MESSAGE_REQ / RESP / NOTIFY服务 -> 枢纽;NOTIFY 转发给 chat
5008 / 5009EVENT_PUBLISH_REQ / RESP服务 -> 枢纽
5010EVENT_DELIVER_NOTIFY枢纽 -> 目标服务
5011 / 5012EVENT_ACK_REQ / RESP服务 <-> 枢纽
5013-5030玩家身份绑定 / 频道订阅 / 未读账本服务 <-> app_chat 主端口(已从 server_gateway 迁出,注意拨对端口)
5050 / 5051PEER_REGISTER_REQ / RESPgame_chat(spoke)-> app_chat(hub)
5052CHANNEL_MESSAGE_NOTIFYspoke -> hub 频道消息上行
5053PEER_INJECT_MESSAGE_NOTIFYhub -> spoke 跨平面回复注入

状态:5xxx 契约 Supported;5013-5030 应答在 app_chat 主端口(TCP 7000),不在 8100。完整契约(拨出、至少一次事件投递、注入校验、peer 协议)在服务器平面与 peer 协议;完整的 msg-id 到 body 映射在 核心文档。

Notification / 设备面(6xxx) ​

由 chirp_app_notification(TCP 5006 / WS 5016)提供服务,经 chirp_app_sdk_gateway(TCP 5200 / WS 5201)转发。body 是 chirp.app_notification.* 消息。

MsgID名称Body
6001 / 6002REGISTER_DEVICE_REQ / RESPRegisterDeviceRequest / RegisterDeviceResponse(设备注册请求/应答)
6003 / 6004UNREGISTER_DEVICE_REQ / RESPUnregisterDeviceRequest / UnregisterDeviceResponse(设备注销请求/应答)
6005 / 6006UPDATE_DEVICE_TOKEN_REQ / RESPUpdateDeviceTokenRequest / UpdateDeviceTokenResponse(推送 token 更新请求/应答)
6007 / 6008GET_USER_DEVICES_REQ / RESPGetUserDevicesRequest / GetUserDevicesResponse(用户设备列表查询请求/应答)
6009 / 6010PUSH_NOTIFICATION_REQ / RESPPushNotificationRequest / PushNotificationResponse(推送请求/应答)

6011+ 的 id 预留(角标 / 静默 / 偏好设置),尚未实现。

认证规则:

  • 在 app_sdk_gateway 上,6xxx 设备消息要求已认证会话(否则 AUTH_FAILED),且 user_id 永远被改写为认证用户——客户端不能替别人注册或查询设备。UPDATE_DEVICE_TOKEN_REQ 用 device_id 寻址设备,没有 user_id 字段,但同样要求认证。
  • 直连 app_notification 没有会话概念;它面向可信网络上的内部服务(比如 chat 的推送桥)。
  • 真实 provider 投递:--push_transport http 经 HTTP(S) 投递 FCM/APNs(端点 --fcm-endpoint / --apns-endpoint / --apns-sandbox,私有 CA --push_ca_file,调试豁免 --push_verify_tls off);无 token 的设备显式记失败,不再静默记成功。默认 --push_transport logging 仅记日志。APNs 官方端点要求 HTTP/2,前置协议转换或走 provider 的 HTTP/1.1 兼容 API。

登录流程 ​

Gateway 登录(游戏平面) ​

同 (user_id, device_id) 重复登录会顶掉旧会话:旧连接收到 KICK_NOTIFY,新连接的 LOGIN_RESP.kick_previous = true。

直连 Chat 登录 ​

Gateway 登录与直连 Chat 登录是两个独立的会话概念:SDK(sdks/core)直连 chat 主端口,登录一次即完成连接与认证;自研客户端选一种路径接入,不要叠加。

聊天消息流程 ​

接收方离线时,Chat 把消息存进离线队列(内存兜底 200 条/用户,可选 Redis)并在 SEND_MESSAGE_RESP 回 TARGET_OFFLINE;接收方下次登录后补投。以 --notification_host 启动 chat 时,离线消息还会经 app_notification 触发一次设备推送(发完即忘;见上文 6xxx 一节)。

WebSocket 用法 ​

用二进制帧,不要发 JSON。

伪代码:

ts
const loginBody = LoginRequest.encode({
  token: 'player_1',
  deviceId: 'dev_1',
  platform: 'web'
}).finish()

const packet = Packet.encode({
  msgId: MsgID.LOGIN_REQ,
  sequence: 1n,
  body: loginBody
}).finish()

ws.send(concat(uint32be(packet.length), packet))

服务端响应同样是 WebSocket 二进制帧,载荷以 4 字节大端长度前缀开头。

错误码 ​

通用响应码枚举定义在 proto/common.proto。

码名称含义
0OK成功
1INTERNAL_ERROR服务端错误
2INVALID_PARAM请求无效(缺字段、频道码非法、不可屏蔽频道等)
3AUTH_FAILED认证失败(未登录、token 无效)
4SESSION_EXPIRED会话已失效
5USER_NOT_FOUND用户不存在
6TARGET_OFFLINE接收方当前不在线(消息已入离线队列)
7SERVER_UNAVAILABLE服务面目标服务未连接,或其事件队列已满;跨平面回复无在线 spoke 时同码
8RATE_LIMITED触发限流:登录/发送模糊闸、频道发送节奏、重复消息禁言
9VERSION_MISMATCHpeer 注册协议版本低于 hub 的 min_peer_version
10WORD_FILTERED敏感词策略为 reject 时拒收(replace 策略静默替换后放行)
11CONTENT_TOO_LONG内容超过频道码点上限(私聊 200 / 世界 100 / 系统公告 500)

SDK 的传输层错误(NotConnected/Timeout/Closed/Kicked/BadResponse)与上表互相独立:ec == OK 不代表业务成功,必须再读 resp.code()。

相关文档 ​