拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

goim 客户端通讯协议全解:WebSocket 与 TCP 二进制帧、操作码与握手认证实现

goim 客户端通讯协议全解:WebSocket 与 TCP 二进制帧、操作码与握手认证实现 后端即时通讯微服务【免费下载链接】goimgoim项目地址https://gitcode.com/gh_mirrors/go/goim点击查看免费下载本篇技术指南以 docs/en/proto.md 为核心骨架系统讲解 goim 中 comet 长连接服务与客户端之间的两种通讯协议——WebSocketJSON 帧与 TCP二进制帧并结合仓库源码逐字节拆解协议头布局、操作码Operation语义、心跳与认证握手流程。读完本文你将掌握 goim 协议帧的编解码细节、客户端如何构造认证与心跳包以及如何对照源码验证协议实现的正确性。协议概览comet 支持的两类客户端通讯通道goim 架构中comet是负责维持海量客户端长连接的接入层组件与客户端通讯支持两种协议协议传输层数据封装适用场景WebSocketHTTP/WS也可启用 TLS 形成 WSSJSON Frame浏览器端如 examples/javascript/index.htmlTCP原生 TCP二进制帧移动端 / 高性能长连接客户端两种协议的请求与返回协议一致即客户端发出的认证请求、心跳请求与服务端返回的响应、下行推送使用完全相同的帧结构区别仅在于承载层是 WebSocket 消息还是裸 TCP 字节流。WebSocket 协议ws://DOMAIN/sub请求 URLws://DOMAIN/subDOMAIN替换为实际部署的 comet 域名或 IP路径/sub是 comet 的固定 WebSocket 订阅路径。这一要求写死在源码中在 internal/comet/server_websocket.go 的ServeWebsocket里通过websocket.ReadRequest(rr)读取 HTTP 握手请求后直接校验req.RequestURI ! /sub路径不匹配即关闭连接并退出握手流程若在 comet 配置中开启tlsOpen则对应wss://DOMAIN/sub监听端口由websocket.tlsBind指定见 cmd/comet/comet-example.toml。请求与返回 JSON 示例WebSocket 使用 JSON 帧请求与返回结构一致{ ver: 102, op: 10, seq: 10, body: {data: xxx} }注意文档中的op: 10对应源码中的OpProtoReady协议就绪这里用于示意「任意合法操作码」实际业务推送时op多为下行消息操作码。请求和返回参数说明参数必选类型说明vertrueint协议版本号optrueint指令Operation决定该帧是认证、心跳还是业务消息seqtrueint序列号服务端返回的 seq 与客户端发送的 seq 一一对应用于请求响应配对bodytruejson包体WebSocket 场景下在认证帧中承载授权令牌用于校验并获取真实用户 IDWebSocket 帧的二进制本质虽然 WebSocket 层封装为 JSON但 goim 实际传输的是二进制消息Binary Frame 定长二进制协议头。从源码 api/protocol/protocol.go 的WriteWebsocket/ReadWebsocket可以看出服务端先写一个websocket.BinaryMessage类型的消息头再在消息体内写入与 TCP 完全一致的 16 字节二进制协议头最后写入 JSON body。也就是说JSON 只是 body 的呈现形式头部仍是紧凑的二进制布局。TCP 协议tcp://DOMAIN 与二进制帧请求 URLtcp://DOMAINcomet 的 TCP 监听端口默认配置为:3101见 internal/comet/conf/conf.go 中的TCP.Bind与 cmd/comet/comet-example.toml 的[tcp] bind [:3101]。客户端连接后需立刻进入认证流程认证前发送的任意非认证帧都会被拒绝。协议格式二进制请求和返回协议一致。每个数据包由16 字节定长协议头 变长 body组成。请求 返回参数参数必选类型说明package lengthtrueint32 bigendian包总长度协议头 bodyheader Lengthtrueint16 bigendian协议头长度固定为 16vertrueint16 bigendian协议版本operationtrueint32 bigendian协议指令操作码seqtrueint32 bigendian序列号jsonp 回调场景下也可承载回调标识bodyfalsebinary包体长度 package length - header length协议头逐字节布局源码级源码 api/protocol/protocol.go 通过常量精确定义了头部各字段的偏移与宽度字段偏移字节宽度字节编码packLen包长度04big-endian int32headerLen包头长度42big-endian int16ver版本62big-endian int16op操作码84big-endian int32seq序列号124big-endian int32body16变长原始二进制对应源码中的常量_rawHeaderSize _packSize _headerSize _verSize _opSize _seqSize 4 2 2 4 4 16。同时源码做了两层长度合法性校验ReadTCP/ReadWebsocketMaxBodySize 1 124096 字节若packLen MaxBodySize 16即_maxPackSize返回ErrProtoPackLen若headerLen ! 16_rawHeaderSize返回ErrProtoHeaderLen。这两条校验是 goim 客户端接入时必须遵守的硬性约束单帧最大包长 4096 16 4112 字节。心跳帧的特殊性body 携带房间在线人数普通帧的 body 为业务消息但心跳回复帧op3例外。源码提供了两个专用方法WriteTCPHeart与WriteWebsocketHeart在 16 字节头部之后再写入 4 字节的onlineint32 bigendian即该帧包长为16 4 20字节。internal/comet的 dispatch 循环中当收到客户端心跳op2并回写OpHeartbeatReplyop3时会取当前房间在线数ch.Room.OnlineNum()一并下发。因此客户端解析心跳回复时应读取 body 前 4 字节作为该房间的实时在线人数参考 internal/comet/server_tcp.go 的dispatchTCP。指令Operation定义docs/en/proto.md 列出的核心指令为指令说明2客户端请求心跳3服务端心跳答复7auth 认证8auth 认证返回以上仅为最常用的 4 个指令。完整操作码由 api/protocol/operation.go 统一定义共 18 个操作码常量名说明0OpHandshake握手1OpHandshakeReply握手返回2OpHeartbeat心跳3OpHeartbeatReply心跳返回4OpSendMsg发送消息5OpSendMsgReply发送消息返回6OpDisconnectReply断开连接返回7OpAuth认证8OpAuthReply认证返回9OpRaw原始未解析消息10OpProtoReady协议就绪11OpProtoFinish协议结束12OpChangeRoom切换房间13OpChangeRoomReply切换房间返回14OpSub订阅指令15OpSubReply订阅返回16OpUnsub取消订阅17OpUnsubReply取消订阅返回除心跳、认证外的操作码如 12/14/16在 comet 的Operate方法internal/comet/operation.go中处理OpChangeRoom调用 bucket 切换房间并回包OpChangeRoomReplyOpSub/OpUnsub通过逗号分隔的指令列表更新通道的 Watch 集合并回包 Reply其余未知操作码会走Receive上报给 logic 处理。连接生命周期与认证握手三步握手从建立连接到认证完成参考 docs/handshake.png 所示的流程一次完整的连接建立包含TCP/WS 连接建立客户端连上 comet 后必须先发送认证帧op7。comet 的认证循环会持续读取并校验p.Op protocol.OpAuth在此之前收到的任何其他操作码都会被记录为request operation(%d) not auth并忽略见 internal/comet/server_tcp.go 的authTCP与 internal/comet/server_websocket.go 的authWebsocket认证请求op7认证帧的 body 承载授权令牌token。comet 通过s.Connect(ctx, p, cookie)将token、cookie、serverID组装为logic.ConnectReq经 gRPC 调用 logic 服务完成身份校验与真实用户 IDmid获取见 internal/comet/operation.go 的Connect与 api/logic/logic.proto 的ConnectReq/ConnectReply认证返回op8认证成功后 comet 将帧的 op 改为OpAuthReply、清空 body 后写回客户端随后将通道注册进对应的 bucket 并启动读/写双 goroutine 开始长连接服务。握手阶段受protocol.handshakeTimeout限制默认 5 秒cmd/comet/comet-example.toml 中配置为 8s超时未完成认证连接会被强制关闭。心跳保活客户端主动、服务端应答连接建立后客户端需周期性发送心跳帧op2无 body包长固定 16 字节。comet 收到后更新该通道的定时器把 op 改写为OpHeartbeatReplyop3若帧属于某个房间则带上房间在线人数20 字节帧回写每隔serverHeartbeat随机化避免同时刻风暴还会向 logic 上报一次在线心跳刷新用户在线状态与过期时间。客户端应据服务端返回的heartbeat时长来自ConnectReply设定心跳周期超过该周期未发送心跳的连接将被服务端判定超时并回收。客户端实现参考JavaScript WebSocket 客户端仓库提供了可直接运行的前端示例 examples/javascript/client.js其协议处理逻辑与上述二进制布局一一对应头部常量rawHeaderLen 16与源码_rawHeaderSize一致认证构造 16 字节头 JSON token bodyop 7body 示例为{mid:123, room_id:live://1000, platform:web, accepts:[1000,1001,1002]}——即 token 中包含用户 mid、房间 ID、平台与可订阅指令列表心跳发送纯 16 字节头帧op 2每 30 秒一次响应解析按packetOffset/headerOffset/verOffset/opOffset/seqOffset逐字段解析头部对op9OpRaw 批量消息按rawHeaderLen循环切分多个子帧其余 op 按headerLen..packetLen切片解码 body断线重连ws.onclose后按指数退避策略初始 15 秒、逐次翻倍、最多 10 次自动重连。用go run examples/javascript/main.go启动静态服务器后浏览器访问:1999即可观察完整的认证、心跳、推送收发过程。协议相关的配置要点在 cmd/comet/comet-example.toml 中与客户端通讯协议直接相关的配置项配置节字段说明[tcp]bind [:3101]TCP 监听地址客户端连接入口[websocket]bind [:3102]WebSocket 监听地址[websocket]tlsOpen / tlsBind / certFile / privateFile是否开启 WSS 及证书配置[protocol]cliProto 5客户端上行协议缓冲读环大小[protocol]svrProto 10服务端下行协议缓冲写环大小[protocol]handshakeTimeout 8s握手超时时间其中cliProto/svrProto直接决定了单连接内上、下行在途帧的缓冲容量若业务推送量大可适当调大svrProto以降低背压丢弃风险。小结goim 的客户端通讯协议设计非常克制WebSocket 与 TCP 共用同一套 16 字节二进制协议头body 分别是 JSON 与原始二进制操作码以 0~17 的枚举覆盖握手、认证、心跳、消息、订阅/退订、房间切换等全生命周期行为心跳回复帧额外携带房间在线人数一条消息同时完成保活与状态同步。理解这套协议帧布局与操作码语义是编写 goim 客户端 SDK、排查长连接异常、或基于协议头自行实现跨语言客户端的起点。协议头结构总览见 docs/protocol.png。延伸阅读协议帧编解码实现api/protocol/protocol.go操作码完整定义api/protocol/operation.go协议消息结构定义api/protocol/protocol.protoTCP 服务端接入处理internal/comet/server_tcp.goWebSocket 服务端接入处理internal/comet/server_websocket.go服务端配置结构internal/comet/conf/conf.go前端 JS 客户端示例examples/javascript/client.js中文版协议文档docs/proto.md下行推送 HTTP 接口协议docs/en/push.md赞分享后端即时通讯微服务【免费下载链接】goimgoim项目地址https://gitcode.com/gh_mirrors/go/goim点击查看免费下载相关推荐goim 客户端通讯协议完全指南WebSocket 与 TCP 二进制包格式、指令详解与源码级解析goim 客户端通讯协议完全指南WebSocket 与 TCP 二进制包格式、指令详解与源码级解析 本文以 goim 开源仓库的官方通讯协议文档 docs/p后端即时通讯微服务VPet 虚拟桌宠 MOD 制作完整教程从命名规则到代码插件从零开始定制你的桌宠VPet 虚拟桌宠 MOD 制作完整教程从命名规则到代码插件从零开始定制你的桌宠 VPet https://link.gitcode.com/i/5a0ad桌面应用游戏开发Cherry Studio LAN 传输协议v1完全解析mDNS 发现、TCP 握手与二进制分帧文件传输Cherry Studio LAN 传输协议v1完全解析mDNS 发现、TCP 握手与二进制分帧文件传输 本文以 docs/references/lan人工智能大模型AI 应用交互助手本地部署上一篇【亲测免费】 MARLlib多智能体强化学习库教程下一篇MDETR 开源项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表