可热更匹配房间类游戏架构基础设施 客户端 rpc 协议的支持
前言
一开始,对与客户端交互协议仅仅提供了name, body
,包名加包体的简单打包方式,对于body
大家可以自由选择任意编码解码方式(json
、protobuff
、sproto
…)。后面觉得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/