Request 和 Response 两个类,都有记录序列号的 seq_id 字段,但 Notice 没有。Protocol 类就是负责把一段 buffer 字节数组,转换成 Message 的子类对象。所以需要针对三种 Message 的子类型都实现对应的 Encode() / Decode() 方法。
- class Protocol {
-
- public:
- virtual ~Protocol() {
- }
-
- /**
- * @brief 把请求消息编码成二进制数据
- * 编码,把msg编码到buf里面,返回写入了多长的数据,如果超过了 len,则返回-1表示错误。
- * 如果返回 0 ,表示不需要编码,框架会直接从 msg 的缓冲区读取数据发送。
- * @param buf 目标数据缓冲区
- * @param offset 目标偏移量
- * @param len 目标数据长度
- * @param msg 输入消息对象
- * @return 编码完成所用的字节数,如果 < 0 表示出错
- */
- virtual int Encode(char* buf, int offset, int len, const Request& msg) = 0;
-
- /**
- * 编码,把msg编码到buf里面,返回写入了多长的数据,如果超过了 len,则返回-1表示错误。
- * 如果返回 0 ,表示不需要编码,框架会直接从 msg 的缓冲区读取数据发送。
- * @param buf 目标数据缓冲区
- * @param offset 目标偏移量
- * @param len 目标数据长度
- * @param msg 输入消息对象
- * @return 编码完成所用的字节数,如果 < 0 表示出错
- */
- virtual int Encode(char* buf, int offset, int len, const Response& msg) = 0;
-
- /**
- * 编码,把msg编码到buf里面,返回写入了多长的数据,如果超过了 len,则返回-1表示错误。
- * 如果返回 0 ,表示不需要编码,框架会直接从 msg 的缓冲区读取数据发送。
- * @param buf 目标数据缓冲区
- * @param offset 目标偏移量
- * @param len 目标数据长度
- * @param msg 输入消息对象
- * @return 编码完成所用的字节数,如果 < 0 表示出错
- */
- virtual int Encode(char* buf, int offset, int len, const Notice& msg) = 0;
-
- /**
- * 开始编码,会返回即将解码出来的消息类型,以便使用者构造合适的对象。
- * 实际操作是在进行“分包”操作。
- * @param buf 输入缓冲区
- * @param offset 输入偏移量
- * @param len 缓冲区长度
- * @param msg_type 输出参数,表示下一个消息的类型,只在返回值 > 0 的情况下有效,否则都是 TypeError
- * @return 如果返回0表示分包未完成,需要继续分包。如果返回-1表示协议包头解析出错。其他返回值表示这个消息包占用的长度。
- */
- virtual int DecodeBegin(const char* buf, int offset, int len,
- MessageType* msg_type) = 0;
-
- /**
- * 解码,把之前DecodeBegin()的buf数据解码成具体消息对象。
- * @param request 输出参数,解码对象会写入此指针
- * @return 返回0表示成功,-1表示失败。
- */
- virtual int Decode(Request* request) = 0;
-
- /**
- * 解码,把之前DecodeBegin()的buf数据解码成具体消息对象。
- * @param request 输出参数,解码对象会写入此指针
- * @return 返回0表示成功,-1表示失败。
- */
- virtual int Decode(Response* response) = 0;
-
- /**
- * 解码,把之前DecodeBegin()的buf数据解码成具体消息对象。
- * @param request 输出参数,解码对象会写入此指针
- * @return 返回0表示成功,-1表示失败。
- */
- virtual int Decode(Notice* notice) = 0;protected:
-
- Protocol() {
- }
-
- };
这里有一点需要注意,由于 C++ 没有内存垃圾搜集和反射的能力,在解释数据的时候,并不能一步就把一个 char[] 转换成某个子类对象,而必须分成两步处理。
先通过 DecodeBegin() 来返回,将要解码的数据是属于哪个子类型的。同时完成分包的工作,通过返回值来告知调用者,是否已经完整的收到一个包。
调用对应类型为参数的 Decode() 来具体把数据写入对应的输出变量。 (编辑:PHP编程网 - 黄冈站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|