网络游戏TCP长连接基本设计

基本结构

从基本结构上,我主要封装了三个类,Protocol->TcpClient->MsgHandler,这三者依次从底层到应用层,主要分别处理数据与协议、tcp socket收/发、消息处理,,下面简单说说。

Protocol

主要提供数据转换接口,并定义了协议。

数据转换接口主要是:StructToBytes和BytesToStruct,C#上的实现利用了Marshal。

协议由消息头和消息内容构成,消息头包含协议size和id,消息内容就是纯bytes。

TcpClient

这里具体处理了socket的连接/断开/发送/接收等。主要对外提供了Init/Connect/Disconnect/Send/Recv/IsConnect等接口。

MsgHandler

这是TCP模块对外的应用接口,开启一个消息处理线程,在后台处理消息收发。主要实现以下功能: 1. 初始化 2. 消息注册。基本的观察者模式 3. 打开连接/断开连接/重新连接等 4. 发送消息 5. 消息处理。处理具体的消息发/收,后面贴上这块的实现代码片段。 6. 心跳包。每隔5s自动发心跳包,检查网络连接。 7. 销毁。做清理工作。

消息处理

直接上代码片段,简单注释

// 初始化时开启消息处理线程m_pobjMsgThread = new Thread(new ThreadStart(this.ProcessMsg));m_pobjMsgThread.Name = “thread_msg”;m_pobjMsgThread.IsBackground = true;m_pobjMsgThread.Start();// 消息处理void ProcessMsg() {while (m_bFlagRun) {if (m_bReconnect) { // 处理reconnect请求this.DoDisconnect();m_bReconnect = false;}if (!this.IsConnected() && m_bAutoConnect) {// 处理断线this.DoConnect(m_strAddress, m_strPort);Thread.Sleep(0);if (!this.IsConnected())Thread.Sleep(kReconnectionTime);continue;}if (m_msgQue.Count() > 0) {// 消息发送,一次把所有消息缓存都发送lock (m_msgQue) {while (m_msgQue.Count() > 0) {m_msgQueBuffer.Enqueue(m_msgQue.Dequeue());}}while (m_bFlagSend && m_msgQueBuffer.Count > 0) {Msg msg = m_msgQueBuffer.Dequeue();this.m_pobjTcpClient.Send(msg.bytes, msg.length);}}if (m_bFlagRecv) // 消息接收m_pobjTcpClient.Recv();Thread.Sleep(5);}}优化

为了保证IO不卡顿,发送消息接口(Send)只是把消息丢到一个queue里,具体的发送是在单独的线程(ProcessMsg)里处理的。

消息接收(Recv)也可能会有IO瓶颈,这块的优化需要在业务逻辑里根据具体情况处理。比如我们原来一款RPG游戏,在主角进入人堆(比如城里摆摊、国战)或怪堆(比如副本里局部有很多小怪)里的时候,会瞬时收到几十条甚至数百条创建人/怪的消息,我也是采用了类似于前面消息发送的缓存机制,把创建人/怪的消息缓存到一个queue里,然后在游戏每一帧创建一个,大大改善了IO卡顿。

风景如何,其实并不重要。重要的是,你在我的身边。

网络游戏TCP长连接基本设计

相关文章:

你感兴趣的文章:

标签云: