可热更匹配房间类游戏架构基础设施 客户端 rpc 协议的支持

前言

一开始,对与客户端交互协议仅仅提供了name, body,包名加包体的简单打包方式,对于body大家可以自由选择任意编码解码方式(jsonprotobuffsproto …)。后面觉得name少许增加了包体大小,就新增了packid,body协议码加包体的方式。这两种方式都没法让客户端rpc调用服务端,客户端在编码时只能监听服务端的各种消息,有时候非常不方便。于是就有打算新增 客户端rpc 协议的支持。

以下对于整型都是使用大端无符号方式打包

name, body 协议拆解

  • 2字节 包体总长度
  • 2字节 协议包名长度
  • 包名
  • 消息体

packid, body 协议拆解

  • 2字节 包体总长度
  • 2字节 协议码
  • 消息体

这两种方式,因为包头固定都是2字节,所以包体最大长度为65535。

rpc 协议拆解

  • 2字节 包体总长度
  • 1字节 包类型 字段描述:字段描述: (0-整包 1包头 2包体 3包尾)
  • 1字节 消息类型 字段描述: (0-服务端推送 1-客户端推送 2-客户端请求 3-服务端回复 4-服务器回复错误)
  • 2字节 协议码 字段描述: 协议码
  • 4字节 会话号 字段描述: 标识同一消息
  • 消息体|4字节 消息总长度 字段描述:包头时为4字节的消息内容长度

不支持客户端发送大包

客户端只能发送整包,服务端收到整包以外的消息应该拒绝处理。
不支持客户端发送大包的原因是 可能利用此行为进行攻击服务器,导致服务器内存耗尽。

如何达到支持RPC效果

  • 使用时规范协议码定义,比如协议10101为请求,10102为回复。 这样我们在打包回复消息的时候只需要用req_packid + 1即可。
  • 会话号约定,客户端推送为0即可(不能发送大包),客户端请求(奇数)达到(4,294,967,295)时客户端应该直接切换到1,避免服务端使用溢出后的0进行回复, 服务端回复,服务器回复错误(偶数,奇数基础上1)。

这样客户端在实现时,可以判断如果是客户端请求就用session(会话号)挂起等待服务端回复,收到服务端消息时用session(会话号)找到对于请求状态,用包类型判断需不需要继续等待粘包。

超时处理

客户端rpc 实现可以增加超时处理,避免服务端代码报错,或者没有发送回复消息,导致req 一直挂起。

简单示例

项目示例服务端

项目示例客户端


可热更匹配房间类游戏架构基础设施 客户端 rpc 协议的支持
https://huahua132.github.io/2024/12/29/skynet_fly_word/word_3/T_game_c_rpc/
作者
huahua132
发布于
2024年12月29日
许可协议