想法:
将protobuf
产生的消息格式化成System V 消息队列能够使用的形式,也就是这种形式:
1 2 3 4 5 6 7
| #define _MYMSG_BUFFER_ 8192
struct rapidMsg { long messageId; //根据proto文件得到 int messageLength; //解析的时候必须知道消息的长度 char buffer[_MYMSG_BUFFER_]; };
|
其实想法很简单,就是使用protobuf
提供的接口拿到messageId
,然后再把序列化成string
的消息写入buffer
当中去,但是这里要遇到个小问题,那就是序列化之后的消息不一定能够放入buffer
当中去,所以在放入buffer
之前要做一遍检查。
消息的长度信息也应该一起传给rapidMsg
。我本来想借鉴leveldb
的slice
的存储方式,用buffer
的前8位来保存被转化为16进制的messageLength
,但是在这里就纯属画蛇添足了,明明有好的结构不用,却使用难以理解的方式。
头文件放在这里,而且cpp
文件的实现也非常简单。
message_factory.h
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #ifndef MQUEUE_INCLUDE_MESSAGE_FACTORY_H_ #define MQUEUE_INCLUDE_MESSAGE_FACTORY_H_
#include "object.h" #include "logobj.h" #include <string>
using std::string;
#define _MYMSG_BUFFER_ 8192
struct rapidMsg { long messageId; //根据proto文件得到 int messageLength; char buffer[_MYMSG_BUFFER_]; };
class MessageFactory : public Object { public:
//和ClassFactory一样,这里也不能使用public的MessageFactory MessageFactory(const MessageFactory&) = delete; MessageFactory& operator=(const MessageFactory&) = delete; virtual ~MessageFactory(); void Dump() const;
static MessageFactory &Instance();
/* * messageId是发送的消息id,定义在proto文件当中,比如在test.151000.153000.proto的 enum MessageType 当中 * JUST_TEST_REQUEST = 151001; * 表明了JUST_TEST_REQUEST这个消息id是151001 * message是要发送的消息 */ struct rapidMsg CreateRapidMsg(long messageId_, string message_); /* * 将myMsg给解析出来,使用引用参数来接收结果 */ void ParseRapidMsg(const struct rapidMsg& myMsg_, long& messageId_, string& message_);
protected: //为了singleton模式,不能用public的构造函数,可以用protected和private MessageFactory(); };
#endif /* MQUEUE_INCLUDE_MESSAGE_FACTORY_H_ */
|