
后端即时通讯微服务【免费下载链接】goimgoim项目地址https://gitcode.com/gh_mirrors/go/goim点击查看免费下载本文以 goim 开源仓库的官方通讯协议文档 docs/proto.md 为骨架系统讲解 comet 长连接服务与客户端之间的两种通讯协议——WebSocketJSON Frame与 TCP二进制流的请求地址、数据包结构、字段含义与指令语义并结合 api/protocol 下的编解码源码与 internal/comet 的服务端实现帮助读者完整掌握协议包在内存中的真实排布、读写流程、心跳与认证的调用链以及如何基于该协议编写自定义客户端完成接入、认证、心跳与消息收发。协议总览comet 是 goim 面向海量连接的长连接网关负责维护客户端长连接并与 logic 业务层交互。它对外同时支持两种客户端通讯方式协议访问地址数据承载形式适用场景WebSocketws://DOMAIN/subTLS 为wss://WebSocket 消息内嵌 JSON Frame浏览器 / Web 前端TCPtcp://DOMAIN自定义二进制协议包移动端 App / 高性能长连接两种协议的“请求与返回协议一致”即客户端发送的帧结构和服务端返回的帧结构完全对称唯一的差异是承载介质与编解码方式。需要说明的是本文档描述的是 WebSocket 内部的 JSON 简化格式而实际线上高吞吐场景下comet 的 WebSocket 通道同样采用与 TCP 一致的二进制包格式下文将结合源码展开。两种入口在 internal/comet/server_websocket.gows://.../sub与 internal/comet/server_tcp.go 中分别实现服务端监听地址由 cmd/comet/comet-example.toml 配置[tcp]默认:3101、[websocket]默认:3102。WebSocket 通讯协议请求 URL 与方式请求 URLws://DOMAIN/subHTTP 请求方式WebSocketJSON Frame请求和返回协议一致路径固定为/sub服务端在 internal/comet/server_websocket.go#L184 中强制校验req.RequestURI ! /sub即拒绝连接因此客户端必须按此路径发起握手。请求和返回 JSON{ ver: 102, op: 10, seq: 10, body: {data: xxx} }请求和返回参数说明参数名必选类型说明vertrueint协议版本号optrueint指令seqtrueint序列号服务端返回和客户端发送一一对应bodytruestring授权令牌用于检验获取用户真实用户 Id其中op的取值即下文“指令”一节定义的操作码seq是请求-响应配对的关键客户端递增发送序列号服务端在响应帧中回填同一序列号客户端据此匹配异步返回。body字段在认证帧中携带授权令牌tokencomet 将其透传给 logic 服务换取真实用户 mid见下文“认证流程”。TCP 通讯协议请求 URLtcp://DOMAIN协议格式二进制请求和返回协议一致。TCP 长连接不依赖 HTTP 握手客户端直接按固定字节序大端序bigendian写入协议包。请求与返回参数参数名必选类型说明package lengthtrueint32 bigendian包长度header Lengthtrueint16 bigendian包头长度vertrueint16 bigendian协议版本operationtrueint32 bigendian协议指令seqtrueint32 bigendian序列号bodyfalsebinary$(package length) - $(header length)字节的消息体固定头部合计16 字节4 2 2 4 4body长度等于包总长度减去包头长度可为 0。源码级字段布局协议包在内存中的字节排布在 api/protocol/protocol.go 中由偏移常量精确规定_packSize 4 // 包总长度 _headerSize 2 // 包头长度 _verSize 2 // 协议版本 _opSize 4 // 操作指令 _seqSize 4 // 序列号 _rawHeaderSize _packSize _headerSize _verSize _opSize _seqSize // 16 // 偏移 _packOffset 0 _headerOffset 4 _verOffset 6 _opOffset 8 _seqOffset 12对应的 Proto 结构体定义为{ int32 ver; int32 op; int32 seq; bytes body }见 api/protocol/protocol.proto。注意结构体中的ver/op/seq均为 int32但落盘时按文档规范ver只占用头部的 2 字节int16因此头部 16 字节不变。写入逻辑WriteTCPprotocol.go#L97-L120严格按上述偏移填充packLen _rawHeaderSize int32(len(p.Body)) binary.BigEndian.PutInt32(buf[_packOffset:], packLen) binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize)) binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver)) binary.BigEndian.PutInt32(buf[_opOffset:], p.Op) binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)读取逻辑ReadTCPprotocol.go#L67-L94在解析时做两层合法性校验防止畸形包攻击packLen _maxPackSize时报ErrProtoPackLen——其中_maxPackSize MaxBodySize _rawHeaderSize 112 16 4112MaxBodySize定义在 protocol.go#L12-L15即单条消息体上限 4096 字节headerLen ! _rawHeaderSize (16)时报ErrProtoHeaderLen强制包头长度固定为 16。心跳帧的特殊结构当 op 为心跳答复3时服务端会额外在 body 前 4 字节写入房间在线人数形成16 字节头部 4 字节 int32 online的扩展帧由WriteTCPHeartprotocol.go#L123-L141与WriteWebsocketHeartprotocol.go#L201-L223实现_heartSize 4、_heartOffset 16。客户端可从心跳答复帧中顺带获取房间在线数用于在线状态展示。指令Operation定义原文档给出了核心指令指令说明2客户端请求心跳3服务端心跳答复5下行消息7auth 认证8auth 认证返回完整的指令表定义在 api/protocol/operation.go共 18 个操作码操作码常量名说明0OpHandshake握手1OpHandshakeReply握手返回2OpHeartbeat心跳客户端 → 服务端3OpHeartbeatReply心跳答复服务端 → 客户端4OpSendMsg发送消息5OpSendMsgReply消息发送返回 / 下行消息6OpDisconnectReply断开返回7OpAuthauth 认证8OpAuthReplyauth 认证返回9OpRaw原始消息批量推送拼接用10OpProtoReady协议就绪内部信号11OpProtoFinish协议结束内部信号12OpChangeRoom切换房间13OpChangeRoomReply切换房间返回14OpSub订阅操作15OpSubReply订阅返回16OpUnsub取消订阅17OpUnsubReply取消订阅返回文档中的“5 下行消息”对应常量OpSendMsgReply服务端在 internal/comet/operation.go#L67-L93 的Operate中处理客户端上行指令12 切换房间、14 订阅、16 取消订阅就地处理后回填对应 Reply 操作码其余操作码则通过s.Receive透传给 logic 处理。认证与握手流程协议层面的 auth 流程无论 WebSocket 还是 TCP连接建立后的第一帧必须是 auth 认证帧op 7否则服务端直接报request operation(x) not auth并关闭连接见 server_tcp.go#L326-L349 的authTCP与 server_websocket.go#L408-L429 的authWebsocket。认证帧的 body 是授权令牌服务端调用Connectinternal/comet/operation.go#L17-L27将 token 通过 gRPC 发给 logic 服务换取mid用户 ID、key、roomID、accepts可接收消息类型列表与heartbeat心跳间隔成功后回发 op 8 的认证返回帧。WebSocket 入口还会额外读取 HTTP Header 中的Cookie一并参与认证。握手时序HTTPS 场景在 TLS/WSS 场景下握手遵循“RSA AES 混合加密”时序docs/handshake.png 示意证书配置见 cmd/comet/comet-example.toml 中[websocket]的certFile/privateFile客户端生成随机 AES 密钥用服务端 RSA 公钥加密后作为 body 发送握手包服务端用 RSA 私钥解密得到 AES 密钥返回握手成功包之后客户端发送的认证包、消息包均用该 AES 密钥加密服务端解密处理。心跳机制客户端发送 op 2 的心跳帧服务端收到后重置该连接的超时计时器超时时间即 auth 阶段 logic 返回的heartbeat见 server_tcp.go#L170-L183并回发 op 3 的答复帧心跳答复帧会携带房间在线人数见“心跳帧的特殊结构”服务端还会以 10~30 分钟随机间隔RandServerHearbeat常量见 internal/comet/server.go#L18-L19通过 gRPC 向 logic 上报存活心跳Heartbeatinternal/comet/operation.go#L40-L47用于分布式会话保活。协议帧层面心跳帧op2/3只有 16 字节头部、无 body是最精简的保活报文。客户端示例从协议到代码仓库 examples/javascript/client.js 给出了一个完整的浏览器客户端实现直接按本文协议字段构造帧是理解协议落地的绝佳参考头部常量与协议源码完全一致rawHeaderLen 16、opOffset 8、seqOffset 12认证帧auth()op7body 为 token JSON例如{mid:123, room_id:live://1000, platform:web, accepts:[1000,1001,1002]}心跳帧heartbeat()op2无 bodysetInterval每 30 秒发送一次消息处理按op分发op8 认证成功、op3 心跳答复、op9 批量消息需按包长度循环解析其余按单包解析连接地址示例ws://sh.tony.wiki:3102/sub即对应 comet 的 WebSocket 监听端口。服务端 WebSocket 监听与 TCP 监听均由 cmd/comet/main.go 依据配置启动InitWebsocket/InitTCP对应配置见 cmd/comet/comet-example.toml 的[websocket].bind与[tcp].bind。协议安全与工程细节包大小防护MaxBodySize 4096超出即拒绝避免超大报文拖垮内存protocol.go#L14包头校验headerLen强制等于 16防止伪造头部连接超时handshakeTimeout默认 8scomet-example.toml#L36内未完成认证即被强制断开内存复用读写的 Proto 对象通过 channel 池化CliProto/SvrProto默认 5/10与round分片缓冲池复用服务端高并发下通过dispatchTCP/dispatchWebsocket双协程读协程 写协程分离读写批量推送优化op9OpRaw允许 job 将多条消息在推送前拼成连续字节流后一次性下发客户端需按package length循环切片解析见 examples/javascript/client.js#L66-L80。小结goim 的 comet 客户端协议以“16 字节固定大端序头部 可变长 body”为统一内核WebSocket 与 TCP 两种入口共享同一 Proto 编解码模型op指令体系完整覆盖握手、认证、心跳、消息与订阅管理seq实现请求-响应配对。无论是接入 Web 端还是自研原生客户端只要严格遵循 docs/proto.md 的字段规范、参照 api/protocol/protocol.go 的编解码实现与 examples/javascript/client.js 的示例代码即可快速实现一个稳定、可认证、可收发消息的 goim 客户端。赞分享后端即时通讯微服务【免费下载链接】goimgoim项目地址https://gitcode.com/gh_mirrors/go/goim点击查看免费下载相关推荐从0到1掌握情感分析bert-base-cased-finetuned-sst2完整使用教程从0到1掌握情感分析bert base cased finetuned sst2完整使用教程 bert base cased finetuned sst2是一netfox自定义扩展开发如何为特定需求定制网络调试功能 netfox自定义扩展开发如何为特定需求定制网络调试功能 netfox是一款轻量级、一行代码即可集成的iOS/OSX网络调试库能够帮助开发者轻松捕获和5分钟掌握PDF字体修复用PDF补丁丁告别跨平台乱码困扰5分钟掌握PDF字体修复用PDF补丁丁告别跨平台乱码困扰 你是否遇到过这样的情况在自己电脑上精心排版的PDF文档发给同事或客户后打开时却变成了乱码或者字桌面应用文档上一篇华为运动数据跨平台终极转换方案免费TCX格式转换器完整指南下一篇终极Arduino温湿度监测实战DHT传感器库从入门到精通的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考