天龙客户端的网络模块

网络在游戏引擎结构中处于底层,无论什么联网游戏都绕不开。网络层要实现的功能包括登录认证,连接服务器,收发消息包,断线检测,重连服务器等等。我原来的方案是封装Socket,开一个网络消息接收线程,用Socket的recdata接口,再加上一个心跳机制来检测是否掉线,现在是够用了,但经常出现莫名其妙的掉线,很是不理解。

  网络消息的发送,原来用一般就是一个固定的消息头,头结构里有消息号,消息体就自定义了,每个消息并没有直接封装,也就是说要发的消息并不是个对象。天龙定义了一个抽象基类代表所有要发送出去的消息,PacketDistributed,每一个要发送的消息都是这个对象。此对象可根据消息号创建出派生出来的消息封装体,能调用网络接口把本体数据发送出去,支持写入发送缓冲区。每个具体的派生对象负责自己的实现。

  从网络收到消息后怎么走的流程呢。首要涉及的就是分消息号和对对应消息号的解析,这个功能的设计相信所有网络游戏都会碰到。之前我的做法是,每个消息号对应一个Handler,谁用这个消息,谁负责写Handler,但是很遗憾,同事们对此的执行能力不行,写的乱七八糟。天龙是集中维护了一个PacketFactoryManager,其中有个消息号(PacketFactory)和消息处理函数(IPacket)的对应表,只要加消息,就需要有对应的处理器。PacketFactory代表一个消息,核心数据是消息号;IPacket代表对一个消息的处理,核心是一个Execute虚函数;如果重新设计的话,也可以这么干,每个消息都对应一个处理器,作为规范定下去。

  关于网络字节流的处理。之前端游等可能很普遍的方法是二进制字节流,然后逐个核对消息结构的字节,这种方法实际上容错能力极低,只要有一个字节格式不正确,这条消息就算挂了,甚至整个游戏的消息缓冲就都坏掉了。现在手游用的很多的应该是Google Protocol buffer,在网络字节的优化上一定有冗余,但在易用性上会好很多,回头单独写个文章说说这个对象。天龙看上去也用这个了,同时封装有SocketInputStream,SocketOutputStream。看到这里,需要抽时间去研究下protocol buffer.

  天龙的网络管理器NetManager,封装了连接服务器,发送/处理消息包,重连服务器,断开服务器,网络线程的创建与销毁,连接/断开连接的回调等功能,但实际的实现放在NetWorkLogic里,提供了用户登录接口(以及完成回调),用户登出接口,选择角色接口(以及完成回调)等。网络连接掉了之后,ConnectLost函数里要进入选服界面(异步过程),等进到选服界面后网络清理,UI清理,然后场景相机active false。也有连接监听代理和连接丢失代理这些常用的功能。和其他项目相似,类里维护了一个连接状态,分别是INVALID,CONNECTING,CONNECTED,DISCONNECTED,分别对应无效,连接中,已经连接上,未连接。我的项目里连接中,无效这些状态没什么大的用处。我考虑的话,最主要弄清楚的是网络分层结构。

下一步准备看看AssetBundle的管理。

时间: 2024-08-10 14:59:21

天龙客户端的网络模块的相关文章

网易考拉Android客户端网络模块设计

本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Square公司的OkHttp,Google推出的Volley,还有在OkHttp基础上进行封装的Retrofit等,这些都是非常优秀的网络处理框架.利用现有网络处理框架,比从零开始设计.开发网络请求节省很多开发时间,同时也避免了一些意想不到的问题.如果把这些框架直接拿来使用,不进行任何二次封装,会使我们工程

网络模块(客户端的连接动作)

一个客户端连接网络模块工作(一个连接的过程) 监听线程收到一个连接后像轮询线程的连接队列中push一个conn_queue_item,然后向soketpair中写入一个字节 此时子线程就是自动调用设置的事件,然后从连接队列中pop一个socket 然后创建一个机遇socket的bufferevent 在createChannel中回调 void TCPServer::on_connect(int channel_id) { packet pkt; pkt.size = (int)link_sta

node.js中net网络模块TCP服务端与客户端的使用

node.js中net模块为我们提供了TCP服务器和客户端通信的各种接口. 一.创建服务器并监听端口 const net = require('net'); //创建一个tcp服务 //参数一表示创建服务的一些配置 //参数二表示 事件 'connection' 监听回调函数 let server = net.createServer({ //表示是否允许一个半开的TCP连接,默认为false allowHalfOpen: false, //一旦来了连接,是否暂停套接字,默认为false pau

网络(一),libevent客户端部分

网络模块(1) 一.服务端: 暂时就以libevent模块,共享内存等下 1.GS打开,首先创建4个libevent子线程,当然为每个线程设置连接通知回调函数,这个是基于sockpair的,然后再创建一个监听线程,专门负责监听 2.监听线程收到一个连接后,通过轮询选择一个线程,然后向这个线程的conn_queue连接队列中插入一个libevent封装的一个socket,然后向socketpair中发送一个字节的数据 3.此时子线程会收到通知,从连接队列中弹出一个socket,然后创建一个基于此s

b/s客户端和服务器的交互(转)

原文:http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ 作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等. 本文将更深入的研究当你输入一个网址的时候,后台到底发生了一件件什么样的事- 1. 首先嘛,你得在浏览器里输入要网址: 2. 浏览器查找域名的IP地址 导航的第一步是通过访问的域名找出

MMORGP大型游戏设计与开发(客户端架构 part16 of vegine)

由于近来比较忙碌和有些困倦的原因,所以关于这部分的文章没有及时更新,一句话:让朋友们久等了!今天所讲的是客户端vengine(微引擎)中最后一个部分,就像上节所说,这一部分的内容比较多.可能有些朋友看了代码以及注释后,仍有不少疑惑的地方,欢迎评论留言相互讨论,如果有不好的地方,也希望大家勇于批评与指正.游戏模块,是提供给客户端最核心的部分,它将直接影响到游戏内容,如数据.渲染等. 构架 CODE 模块game下模块action 文件item.h /** * PAP Engine ( -- ) *

客户端架构

Blog2-客户端架构 一.客户端架构简介 客户端(Client)或称为用户端,是指与服务器相对应,为客户提供本地服务的程序.除了一些只在本地运行的应用程序之外,一般安装在普通的客户机上,需要与服务端互相配合运行. 架构,又名软件架构,是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计.软件架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计.软件架构是一个系统的草图.软件架构描述的对象是直接构成系统的抽象组件.各个组件之间的连接则明确和相对细致地描述组件之间的通讯

浏览器客户端智能自动化:如何取得页面中JavaScript运行时动态生成的URL?

浏览器客户端智能自动化:如何取得页面中JavaScript运行时动态生成的URL? 需求 "页面智能拼接"指的是通过启发式查询DOM树,判断出"下一页"链接,取出其href属性.Chromium的官方插件DOM Distiller完成类似的工作,主要目的就是为了将多页点击流程变成单页的Ajax连续阅读体验. 问题是,现在有些网站为了阻止浏览器客户端这么做,将href属性设置为"#"(或javascript:void()),然后在其onclick事

Python 之 socket网络模块简单应用

socket 网络模块分服务器端和客户端 服务器端代码 import socket server = socket.socket() #创建了一个socket的实例 server.bind(('localhost',6969)) #绑定该实例的IP地址与端口 server.listen() #开始监听 print("等待客户端连接:>>") conn,addr = server.accept() #conn就是客户端连过来而在服务器端为其生成的一个连接实例 print(&q