JSON 或协议缓冲区替换自定义 TCP 消息
JSON or protocol buffer to replace the custom TCP message
原来,我们有两个应用程序与TCP/IP通信,它们都是用C++实现的。它们之间的消息是自定义消息类型。
现在客户端程序将改为基于nodejs
的web应用程序,它们之间的通信将改为rabbitmq
等消息总线
所以他们之间的消息类型应该改变。
我首先想到JSON
,但是自定义消息太复杂了,由template
和inheritance
定义。将自定义消息转换为 JSON
似乎不是一个好的选择。我说得对吗?
class Address {
int network;
int addressType;
//...
};
class MsgType{
unsigned char msgSeq;
unsigned int msgLen;
//...
};
class Message{
Address destination;
Address source;
MsgType msgType;
//...
};
template <typename T, int RESPONSE_TYPE>
class ResponseMessage : public Message{
//...
}
typedef struct{
int number;
int type;
}ConfigResp;
class CfgResp : public ResponseMessage<ConfigResp, CONFIG_REQUEST>
{
//...
}
Protocol Buffers
是我这样做的另一种选择。我应该怎么办?
将自定义消息重新定义到协议缓冲区中?没有 没有
这是我的解决方案:只需将整个原始自定义消息(二进制类型)作为服务器端的一条消息包装到协议缓冲区中,然后在客户端解码自定义消息(二进制类型)。这可能吗?
看起来您正在构建您的应用程序以使其更具可扩展性。不使用良好的消息格式完全违背了这一目标。
不要将二进制格式嵌入协议缓冲区块中。您将一无所获 - 您需要为每个想要使用消息总线的组件重写解析和编写代码。那是浪费时间和精力。
将您的 C++ 结构映射到 JSON 或协议缓冲区很痛苦。但这将使以后使用 node.js 或其他窥视消息总线的东西更容易挂钩到这些消息中。
就我个人而言,我会使用协议缓冲区 - 因为它们的类型更安全。 JSON 库中各种类型的处理存在差异,因为 JSON 格式(有意)松散。特别是我发现处理长整数有问题。
通常我会为每个需要转换的 class 编写一个辅助模板结构 - 然后转换就变成了很多样板文件。像
template<typename T> class ProtocolBufferHelper {
}
template<> class ProtocolBufferHelper<Address> {
typedef address_buffer protocol_buffer_type;
void writeToProtocolBuffer( const Address &a, address_buffer & buffer) {
buffer.setNetwork(a.network);
...
}
...
}
template<> class ProtocolBufferHelper<Message> {
void writeToProtocolBuffer( const Message &m, address_buffer & buffer) {
::writeToProtocolBuffer(buffer.getDestination(), m.destination);
::writeToProtocolBuffer(buffer.getSource(), m.source);
...
}
}
template<typename T> void writeToProtocolBuffer( const T &value, ProtocolBufferHelper<T>::protocol_buffer_type & buffer ) {
ProtocolBufferHelper<T>::writeToProtocolBuffer(value, buffer);
}
请原谅我不记得 C++ 中协议缓冲区语法的确切内容(已经有一段时间了...)。但希望它足以让你开始。
原来,我们有两个应用程序与TCP/IP通信,它们都是用C++实现的。它们之间的消息是自定义消息类型。
现在客户端程序将改为基于nodejs
的web应用程序,它们之间的通信将改为rabbitmq
所以他们之间的消息类型应该改变。
我首先想到JSON
,但是自定义消息太复杂了,由template
和inheritance
定义。将自定义消息转换为 JSON
似乎不是一个好的选择。我说得对吗?
class Address {
int network;
int addressType;
//...
};
class MsgType{
unsigned char msgSeq;
unsigned int msgLen;
//...
};
class Message{
Address destination;
Address source;
MsgType msgType;
//...
};
template <typename T, int RESPONSE_TYPE>
class ResponseMessage : public Message{
//...
}
typedef struct{
int number;
int type;
}ConfigResp;
class CfgResp : public ResponseMessage<ConfigResp, CONFIG_REQUEST>
{
//...
}
Protocol Buffers
是我这样做的另一种选择。我应该怎么办?
将自定义消息重新定义到协议缓冲区中?没有 没有
这是我的解决方案:只需将整个原始自定义消息(二进制类型)作为服务器端的一条消息包装到协议缓冲区中,然后在客户端解码自定义消息(二进制类型)。这可能吗?
看起来您正在构建您的应用程序以使其更具可扩展性。不使用良好的消息格式完全违背了这一目标。
不要将二进制格式嵌入协议缓冲区块中。您将一无所获 - 您需要为每个想要使用消息总线的组件重写解析和编写代码。那是浪费时间和精力。
将您的 C++ 结构映射到 JSON 或协议缓冲区很痛苦。但这将使以后使用 node.js 或其他窥视消息总线的东西更容易挂钩到这些消息中。
就我个人而言,我会使用协议缓冲区 - 因为它们的类型更安全。 JSON 库中各种类型的处理存在差异,因为 JSON 格式(有意)松散。特别是我发现处理长整数有问题。
通常我会为每个需要转换的 class 编写一个辅助模板结构 - 然后转换就变成了很多样板文件。像
template<typename T> class ProtocolBufferHelper {
}
template<> class ProtocolBufferHelper<Address> {
typedef address_buffer protocol_buffer_type;
void writeToProtocolBuffer( const Address &a, address_buffer & buffer) {
buffer.setNetwork(a.network);
...
}
...
}
template<> class ProtocolBufferHelper<Message> {
void writeToProtocolBuffer( const Message &m, address_buffer & buffer) {
::writeToProtocolBuffer(buffer.getDestination(), m.destination);
::writeToProtocolBuffer(buffer.getSource(), m.source);
...
}
}
template<typename T> void writeToProtocolBuffer( const T &value, ProtocolBufferHelper<T>::protocol_buffer_type & buffer ) {
ProtocolBufferHelper<T>::writeToProtocolBuffer(value, buffer);
}
请原谅我不记得 C++ 中协议缓冲区语法的确切内容(已经有一段时间了...)。但希望它足以让你开始。