我是一个有用的助手,可以为您翻译文本。
我在我的c++服务器上使用protobuf。但是在套接字中存在多个不同的protobuf消息时出现了问题。我定义了许多proto消息,例如:
message SdkHGetRet {
required int32 opcode = 1;
required bytes value = 2;
}
message SdkHPut {
required bytes table = 1;
required bytes hname = 2;
required bytes key = 3;
required bytes value = 4;
optional int32 writesrc = 5 [default = 0];
}
message SdkSet {
required bytes table = 1;
required bytes key = 2;
required bytes value = 3;
optional int32 writesrc = 4 [default = 0];
}
message SdkSetRet {
required bool status = 1;
optional string master = 2;
}
message SdkInvalidOperation {
required int32 what = 1;
required bytes why = 2;
}
....
每次通过socket发送消息时,我会添加8个字节。其中4个字节用于表示整个socket的长度,另外4个字节表示操作码。操作码意味着消息类型。
在服务器端,当我接收到消息时,我会先读取前4个字节,以获取消息的长度,然后再读取另外4个字节来获取消息的类型,最后再读取消息的长度字节。然后,我将使用消息类型映射到方法映射表(例如404 => "sdkset",405 => "sdksetret")来解码该消息。
我发现这种方法效果不错,但我想知道是否有更优雅的方法来识别消息而无需使用4字节的消息类型。
我已经阅读了消息历史记录,其中一种方法是将整个消息添加到一个大消息中,就像这样:
message BigMessage
{
enum Type { sdkset = 0, sdksetred = 1}
require Type t = 1,
optional string key = 2,
...
}
由于我有超过40种类型的消息,我认为这种方式可能会影响性能,而且在我看来,这种方式看起来很丑。
那么你能给我任何好的建议吗?
oneof
而不是手动编写消息头。 - Kenton Varda