Quickserver是一个免费的开源Java库,用于快速建立健壮的多线程、多客户端TCP服务器应用程序。使用QuickServer,用户能够只集中处理应用程序的逻辑/协议
AMF/JSON/XML/自定义/ProtocolBuffer
不管是作何种网络应用,必需要解决的问题之一就是应用层从字节流中拆分出消息的问题,也就是对于 TCP 这种字节流协议,接收方应用层可以从字节流中识别发送方传输的消息.
1.使用特殊字符或者字符串做为消息的边界,应用层解析收到的字节流时,碰见此字符或者字符串则认为收到一个完整的消息
2.为每一个消息定义一个长度,应用层收到指定长度的字节流则认为收到了一个完整的消息
消息分隔标识(separator)、消息头(header)、消息体(body)
len | message_id | data
|separator | header | body |
| len | message_id | data
8. 粘包:
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
1.发送方引发的粘包是由TCP协议自己形成的,TCP为提升传输效率,发送方每每要收集到足够多的数据后才发送一包数据。若连续发送几回的数据都不多,一般TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
2.接收方引发的粘包是因为接收方用户进程不及时接收数据,从而致使粘包现象。这是由于接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据还没有被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据以后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据
解决措施:
1.对于发送方引发的粘包现象,用户可经过编程设置来避免,TCP提供了强制数据当即传送的操做指令push,TCP软件接收到该操做指令后,就当即将本段数据发送出去,而没必要等待发送缓冲区满;
TCP-NO-DELAY-关闭了优化算法,不推荐
2.对于接收方引发的粘包,则可经过优化程序设计、精简接收进程工做量、提升接收进程优先级等措施,使其及时接收数据,从而尽可能避免出现粘包现象-当发送频率高时依然可能出现粘包
3.接收方控制,将一包数据按结构字段,人为控制分屡次接收,而后合并,经过这种手段来避免粘包。-效率低
4.接收方建立一预处理线程,对接收到的数据包进行预处理,将粘连的包分开
分包算法思路:
基本思路是首先将待处理的接收数据(长度设为m)强行转换成预约的结构数据形式,并从中取出数据结构长度字段,即n,然后根据n计算获得第一包数据长度
1) 若n<m,则代表数据流包含多包数据,从其头部截取n个字节存入临时缓冲区,剩余部分数据一次继续循环处理,直至结束。
2) 若n=m,则代表数据流内容刚好是一完整结构数据,直接将其存入临时缓冲区便可。
3) 若n>m,则代表数据流内容尚不够构成一个完整结构数据,需留待与下一包数据合并后再行处理。
五.正文之场景管理、ai、脚本
AOI: (Area Of Interest),广义上,AOI系统支持任何游戏世界中的物体个体对必定半径范围内发生的事件进行处理;但MMOPRG上绝大多数需求只是对半径范围内发生的物体离开/进入事件进行处理。当你进入一个游戏场景时,若是你能看到其余玩家,那背后AOI系统就正在运做.
1. 很容易想象,AOI的需求最简单的作法是全世界玩家信息所有同步给客户端。这个方案是O(n^2)的复杂度,对服务器来讲是不能承受之重。但若是是超小地图十人如下的特殊需求倒多是个简洁的方案。
2. 比较流行的方案是网格法,简单,高效:将地图按设定的格子大小划分为网格,设玩家移动到某坐标,咱们很容易地将玩家纳入该坐标所属的网格G的玩家链中,而这个玩家的可见集能够简单地将以网格G为中心的九宫格中的玩家链聚合而获得。而要得到两次移动间的可见集差别,也非难事.
转自云风Blog:
所谓 AOI ( Area Of Interest ) ,大体有两个用途。
一则是解决 NPC 的 AI 事件触发问题。游戏场景中有众多的 NPC ,比 PC 大体要多一个数量级。NPC 的 AI 触发条件每每是和其它 NPC 或 PC 距离接近。若是没有 AOI 模块,每一个 NPC 都须要遍历场景中其它对象,判断与之距离。这个检索量是很是巨大的(复杂度 O(N*N) )。通常咱们会设计一个 AOI 模块,统一处理,并优化比较次数,当两个对象距离接近时,以消息的形式通知它们。
二则用于减小向 PC 发送的同步消息数量。把离 PC 较远的物体状态变化的消息过滤掉。PC 身上能够带一个附近对象列表,由 AOI 消息来增减这个列表的内容。
在服务器上,咱们通常推荐把 AOI 模块作成一个独立服务 。场景模块通知它改变对象的位置信息。AOI 服务则发送 AOI 消息给场景
AOI 的传统实现方法大体有三种:
第一,也是最苯的方案。直接按期比较全部对象间的关系,发现可以触发 AOI 事件就发送消息。这种方案实现起来至关简洁,几乎不可能有 bug ,能够用来验证服务协议的正确性。在场景中对象不对的状况下其实也是不错的一个方案。若是咱们独立出来的话,利用一个单独的核,其实能够按期处理至关大的对象数量。
第二,空间切割监视的方法。把场景划分为等大的格子,在每一个格子里树立灯塔。在对象进入或退出格子时,维护每一个灯塔上的对象列表。对于每一个灯塔仍是 O(N * N) 的复杂度,但因为把对象数据量大量降了下来,因此性能要好的多,实现也很容易。缺点是,存储空间不只和对象数量有关,还和场景大小有关。更浪费内存。且当场景规模大过对象数量规模时,性能还会降低。由于要遍历整个场景。对大地图不太合适。这里还有一些优化技巧,好比能够把格子划分为六边形 的。
第三,使用十字链表 (3d 空间则再增长一个链表维度) 保存一系列线段,当线段移动时触发 AOI 事件。算法不展开解释,这个用的不少应该搜的到。优势是能够混用于不一样半径的 AOI 区域。
2.AI
1.怪物AI
2.NPC AI
3.世界环境AI
实现方法:状态机
其余:
寻路:A*
神经网络
遗传算法
3.脚本语言的选择:
Lua/Python/Erlang
Groovy/JRuby/Scala/Fantom/JPython-五大基于JVM的语言
做用:可应用于部分应用层逻辑常常发生变化的系统。如任务系统。以在不须要从新编译整个工程的状况下调整、 测试和修改游戏运行的机制和特性
六.正文之开源网络游戏服务器
魔兽世界模拟器
mangosTrinity TrinityCore2
天堂2模拟器
L2J
永恒之塔模拟器
Arianne
七.正文之参考书籍,博客
1.云风Blog ttp://codingnow.com/ 2.书籍<大型多人在线游戏开发><网络游戏服务器编程><UNIX网络编程> 注:有部份内容来自网络,谢谢大家!