如何用FlatBuffers实现无显式类型检查的游戏消息通信?
用FlatBuffers实现通用消息处理方案
核心思路:FlatBuffers的Union类型
FlatBuffers原生支持Union类型,刚好能替代你之前JSON里通过TypeIdentifier区分消息类型的逻辑,而且不需要显式类型检查,就能直接分发到对应处理逻辑。
具体实现步骤
1. 编写FlatBuffers Schema定义
先在.fbs文件里定义所有消息类型,再用Union把它们统一起来:
// 先定义AttributeData(根据你的C#类补充字段) table AttributeData { key: string; value: string; } // 定义各个消息类型 table CreateEntity { entity_id: string; } table DeleteEntity { entity_id: string; } table ChangeAttribute { entity_id: string; attribute: AttributeData; } // 定义Union类型,包含所有消息 union GameMessageUnion { CreateEntity, DeleteEntity, ChangeAttribute } // 定义顶层消息容器 table GameMessage { msg_type: GameMessageUnion; } root_type GameMessage;
2. 生成C#代码
用FlatBuffers的编译器(flatc)生成C#代码,命令如下:
flatc --csharp your_schema.fbs
3. 发送消息(服务端示例)
创建具体消息并打包到Union中:
// 创建CreateEntity消息 var builder = new FlatBufferBuilder(1024); var entityId = builder.CreateString("player_123"); CreateEntity.StartCreateEntity(builder); CreateEntity.AddEntityId(builder, entityId); var createEntityMsg = CreateEntity.EndCreateEntity(builder); // 打包成GameMessage GameMessage.StartGameMessage(builder); GameMessage.AddMsgType(builder, createEntityMsg.Value); GameMessage.AddMsgTypeType(builder, GameMessageUnion.CreateEntity); var msg = GameMessage.EndGameMessage(builder); builder.Finish(msg.Value); // 发送builder.DataBuffer SendData(builder.DataBuffer);
4. 接收并处理消息(客户端示例)
FlatBuffers会自动识别Union类型,你可以通过Switch模式匹配直接分发,无需显式判断字符串:
// 接收字节数组并解析 var buffer = ReceiveData(); var gameMsg = GameMessage.GetRootAsGameMessage(buffer); // 用Switch处理不同类型,无需显式类型检查 gameMsg.MsgType.Switch( createEntity => HandleCreateEntity(createEntity), deleteEntity => HandleDeleteEntity(deleteEntity), changeAttribute => HandleChangeAttribute(changeAttribute), _ => {} // 处理未知类型 ); // 对应的处理函数 void HandleCreateEntity(CreateEntity msg) { var entityId = msg.EntityId; // 执行创建实体逻辑 } void HandleDeleteEntity(DeleteEntity msg) { var entityId = msg.EntityId; // 执行删除实体逻辑 } void HandleChangeAttribute(ChangeAttribute msg) { var entityId = msg.EntityId; var attr = msg.Attribute; // 执行属性修改逻辑 }
优势说明
- 无需手动维护
TypeIdentifier字符串,FlatBuffers自动管理类型映射 - 性能更高:Union类型序列化/反序列化开销远小于JSON的字符串判断
- 类型安全:编译阶段就能检查消息类型是否被正确处理,避免运行时类型错误
内容的提问来源于stack exchange,提问作者Mitchell Houlton
相关产品推荐
相关产品推荐

