自己实现自定义协议的思考

需求

  • 有三个字段,sender_uid(发送者ID)、content(消息内容)、timestamp(时间戳)
  • 低延迟、高并发、消息可靠、支持多种消息类型
  • 思考一个协议应该完成哪些步骤

思路

一个好的自定义协议设计,需要考虑消息边界、可扩展性、编解码效率和安全性。以下是一个分层的设计思路:

  1. 协议分层结构

    一个完整的网络包结构建议分为两层:包头​ 和 包体。

    • 包头 (Header):用于描述包本身,与具体业务(聊天)无关。是固定长度的二进制数据,便于快速解析。

    • 包体 (Body):承载具体的业务数据(如聊天消息)。其内容由包头中的"消息类型"决定。

B. 包体 (Packet Body)

包体是变长的,其格式由Command ID决定。对于聊天消息(假设Command ID=0x0001,私聊),其结构就是我们需要设计的"聊天消息体"。

聊天消息体设计(序列化方案对比)

您需要将{sender_uid, content, timestamp}这三个字段(以及可能的其他字段,如target_uid)序列化成二进制。

使用高效序列化库

使用Protobuf、MessagePack (MsgPack)​ 或 FlatBuffers​ 来定义消息体。

例如,用Protobuf定义 .proto文件:

protobuf 复制代码
message ChatMessage {
  uint64 sender_uid = 1;
  string content = 2;
  int64 timestamp = 3;
}
  • 优点:在性能、体积和开发效率上取得最佳平衡。自动生成编解码代码,支持向后/向前兼容(通过字段编号),是工业级标准。

  • 缺点:需要引入第三方库。

完整数据流示例(以Protobuf方案为例)

  1. 客户端构建一个 ChatMessage对象,用Protobuf库将其序列化成二进制数据 B_body。
  2. 计算 B_body的长度 len_body。
  3. 按定义填充包头,将 len_body写入"包体长度"字段。
  4. 将包头的二进制数据和 B_body拼接,得到完整的网络包 B_packet。
  5. 通过Socket(可能是基于WebSocket或Raw TCP)发送 B_packet。
  6. 服务端收到数据后:
    • 先读取固定长度的包头(例如14字节)。

    • 从包头中解析出 len_body。

    • 继续从Socket读取 len_body字节,得到完整的包体数据。

    • 根据包头的 Command ID,知道这是一个聊天消息,调用对应的Protobuf解析函数,将包体数据反序列化成 ChatMessage对象。

    • 进行业务逻辑处理(如敏感词过滤、存储、转发给目标玩家)。

相关推荐
女生也可以敲代码21 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
Cosolar1 天前
告别无脑循环:深入解析 ReWOO 与 Plan-and-Execute Agent 架构
人工智能·面试·全栈
Fuly10241 天前
技术经理面试相关--技术篇
面试·职场和发展
逻辑驱动的ken1 天前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
研究点啥好呢1 天前
高德多模态算法工程师面试题精选:10道高频考题+答案解析
python·面试·llm·求职招聘·笔试·高德
fzil0011 天前
自动投递简历 + 面试进度跟踪
人工智能·面试·职场和发展
其实防守也摸鱼1 天前
面试常问问题总结--护网蓝队方向
网络·笔记·安全·面试·职场和发展·护网·初级蓝队
one_love_zfl1 天前
java面试-微服务组件篇
java·微服务·面试
前端百草阁1 天前
【吃透 Promise】从基础到面试高频(手写 + 输出题 + 原理)
okhttp·面试·职场和发展