网络游戏TCP长连接基本设计
2015-07-01 10:54
302 查看
基本结构
从基本结构上,我主要封装了三个类,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卡顿。
相关文章推荐
- 直接运行 html 代码(参考网络)
- HTTPS访问中证书的处理
- linux下修改内核参数进行Tcp性能调优 -- 高并发
- ruby, gem install 出现网络错误
- HTTP请求的TCP瓶颈分析
- HTTP长连接与短连接
- Linux版本 网络调试助手 发布
- Apache Http Client 4 上传多个文件 (示例代码可在 github 上找到)
- HTTP协议是无状态协议,怎么理解? session cookie
- 搜索广告与广告网络Demand技术-流式计算平台
- 用Netty实现的简单HTTP服务器
- Android通过HTTP协议实现上传文件数据
- Asynchronous HTTP Requests in Android Using Volley
- Webrtc Intro - RTP RTCP SDP relevants
- [管理篇]VMWare搭建Openstack——将FlatDHCP网络转化为GRE网络——设置浮动IP
- post 相比get 有很多优点,为什么现在的HTTP通信中大多数请求还是使用get?
- 一个int数组,将数组中重复次数超过k次的元素变成0,并将变成0的元素放到数组最后http://bbs.csdn.net/topics/390921701?page=1#post-398464797#
- gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架
- Android 应用锁/程序锁(APPLock)的实现 http://shigongbo.blog.163.com/blog/static/976090201452572535715
- http1.0与http1.1的区别