Proto3中如何实现同一类型消息的可变实例数量传输?
问题:Proto3中实现可变数量的同一类型消息实例传输
我在Proto3中定义了如下消息结构,希望能够发送数量可变的同一类型实例:
syntax = "proto3"; message Player { uint32 id = 1; uint32 x_pos = 2; uint32 y_pos = 3; PlayerColour colour = 4; } enum PlayerColour { colour_unspecified = 0; colour_green = 1; colour_white = 2; colour_gold = 3; } message AllPlayers { Player player_1 = 1; Player player_2 = 2; Player player_3 = 3; Player player_4 = 4; }
目前该结构预定义了单条消息中可传输的Player实例数量,我想了解是否可以实现实例数量的可变:比如仅当一个玩家数据变更时,消息中仅包含该Player实例;或当只有2名玩家时,不传输空的player_3和player_4实例,以此大幅减少通信带宽消耗。请问有什么解决方案?
解决方案
1. 使用repeated字段(推荐方案)
把AllPlayers里固定的多个Player字段替换成repeated类型,这是Proto3处理可变数量同类型实例的标准方式,序列化时只会包含实际设置的实例,不会传输空数据:
message AllPlayers { repeated Player players = 1; }
- 仅需传输2名玩家时,消息里就只有这两个
Player的序列化数据,无冗余字段。 - 只需要发送变更的玩家数据时,构造仅包含这些变更实例的
AllPlayers消息发送即可。
2. 增量更新专用消息(优化带宽)
如果你的场景以频繁的玩家数据更新为主,可以单独定义一个用于传输增量更新的消息,进一步压缩传输体积:
message PlayerDeltaUpdates { repeated Player updated_players = 1; }
这个消息只用来传递发生变更的玩家数据,不需要携带全量玩家列表,带宽利用率更高。
3. 单/多实例区分(可选)
如果大部分场景下一次只更新单个玩家,可通过oneof明确区分单实例和多实例更新场景,但repeated已经能覆盖两种情况,按需选择:
message PlayerUpdate { oneof payload { Player single_player = 1; repeated Player multi_players = 2; } }
内容的提问来源于stack exchange,提问作者Tristan Thompson
相关产品推荐
相关产品推荐

