对于通信“协议”来说,其实包含了许许多多的含义。在众多的需求中,我所定义的这个协议层,只希望完成四个最基本的能力:
- 分包:从流式传输层切分出一个个单独的数据单元,或者把多个“碎片”数据拼合成一个完整的数据单元的能力。一般解决这个问题,需要在协议头部添加一个“长度”字段。
- 请求响应对应:这对于异步非阻塞的通信模式下,是非常重要的功能。因为可能在一瞬间发出了很多个请求,而回应则会不分先后的到达。协议头部如果有一个不重复的“序列号”字段,就可以对应起哪个回应是属于哪个请求的。
- 会话保持:由于游戏的底层网络,可能会使用 UDP 或者 HTTP 这种非长连接的传输方式,所以要在逻辑上保持一个会话,就不能单纯的依靠传输层。加上我们都希望程序有抗网络抖动、断线重连的能力,所以保持会话成为一个常见的需求。我参考在 Web 服务领域的会话功能,设计了一个 Session 功能,在协议中加上 Session ID 这样的数据,就能比较简单的保持会话。
- 分发:游戏服务器必定会包含多个不同的业务逻辑,因此需要多种不同数据格式的协议包,为了把对应格式的数据转发。
除了以上三个功能,实际上希望在协议层处理的能力,还有很多,最典型的就是对象序列化的功能,还有压缩、加密功能等等。我之所以没有把对象序列化的能力放在 Protocol 中,原因是对象序列化中的“对象”本身是一个业务逻辑关联性非常强的概念。在 C++ 中,并没有完整的“对象”模型,也缺乏原生的反射支持,所以无法很简单的把代码层次通过“对象”这个抽象概念划分开来。但是我也设计了一个 ObjectProcessor ,把对象序列化的支持,以更上层的形式结合到框架中。这个 Processor 是可以自定义对象序列化的方法,这样开发者就可以自己选择任何“编码、解码”的能力,而不需要依靠底层的支持。
至于压缩和加密这一类功能,确实是可以放在 Protocol 层中实现,甚至可以作为一个抽象层次加入 Protocol ,可能只有一个 Protocol 层不足以支持这么丰富的功能,需要好像 Apache Mina 这样,设计一个“调用链”的模型。但是为了简单起见,我觉得在具体需要用到的地方,再额外添加 Protocol 的实现类就好,比如添加一个“带压缩功能的 TLV Protocol 类型”之类的。
消息本身被抽象成一个叫 Message 的类型,它拥有“服务名字”“会话ID”两个消息头字段,用以完成“分发”和“会话保持”功能。而消息体则被放在一个字节数组中,并记录下字节数组的长度。
- enum MessageType {
- TypeError, ///< 错误的协议
- TypeRequest, ///< 请求类型,从客户端发往服务器
- TypeResponse, ///< 响应类型,服务器收到请求后返回
- TypeNotice ///< 通知类型,服务器主动通知客户端
- };
-
- ///@brief 通信消息体的基类
- ///基本上是一个 char[] 缓冲区
- struct Message {
- public:
- static int MAX_MAESSAGE_LENGTH;
- static int MAX_HEADER_LENGTH;
-
- MessageType type; ///< 此消息体的类型(MessageType)信息
-
- virtual ~Message(); virtual Message& operator=(const Message& right);
-
- /**
- * @brief 把数据拷贝进此包体缓冲区
- */
- void SetData(const char* input_ptr, int input_length);
-
- ///@brief 获得数据指针
- inline char* GetData() const{
- return data_;
- }
-
- ///@brief 获得数据长度
- inline int GetDataLen() const{
- return data_len_;
- }
-
- char* GetHeader() const;
- int GetHeaderLen() const;
-
- protected:
- Message();
- Message(const Message& message);
-
- private:
- char* data_; // 包体内容缓冲区
- int data_len_; // 包体长度
-
- };
根据之前设计的“请求响应”和“通知”两种通信模式,需要设计出三种消息类型继承于 Message,他们是:Request(请求包)、Response(响应包)、Notice(通知包)。 (编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|