http://blog.csdn.net/sodme/article/details/468327#comments

————————————————————————————————————————————————————

本文作者:sodme
本文出处:http://blog.csdn.net/sodme
声明:本文可以不经作者同意任意转载、复制、引用。但任何对本文的引用,均须注明本文的作者、出处以及本行声明信息。

  之前,我分析过QQ游戏(特指QQ休闲平台,并非QQ堂,下同)的通信架构(http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx),分析过魔兽世界的通信架构(http://blog.csdn.net/sodme/archive/2005/06/18/397371.aspx),
似乎网络游戏的通信架构也就是这些了,其实不然,在网络游戏大家庭中,还有一种类型的游戏我认为有必要把它的通信架构专门作个介绍,这便是如泡泡堂、QQ
堂类的休闲类竞技游戏。曾经很多次,被网友们要求能抽时间看看泡泡堂之类游戏的通信架构,这次由于被逼交作业,所以今晚抽了一点的时间截了一下泡泡堂的
包,正巧昨日与网友就泡泡堂类游戏的通信架构有过一番讨论,于是,将这两天的讨论、截包及思考总结于本文中,希望能对关心或者正在开发此类游戏的朋友有所
帮助,如果要讨论具体的技术细节,请到我的BLOG(http://blog.csdn.net/sodme)加我的MSN讨论..

  总体来说,泡泡堂类游戏(此下简称泡泡堂)在大厅到房间这一层的通信架构,其结构与QQ游戏相当,甚至要比QQ游戏来得简单。所以,在房间这一层的通信架构上,我不想过多讨论,不清楚的朋友请参看我对QQ游戏通信架构的分析文章(http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx)。可以这么说,如果采用与QQ游戏相同的房间和大厅架构,是完全可以组建起一套可扩展的支持百万人在线的游戏系统的。也就是说,通过负载均衡+大厅+游戏房间对游戏逻辑的分摊,完全可以实现一个可扩展的百万人在线泡泡堂。

  但是,泡泡堂与斗地主的最大不同点在于:泡泡堂对于实时性要求特别高。那么,泡泡堂是如何解决实时性与网络延迟以及大用户量之间矛盾的呢?

  阅读以下文字前,请确认你已经完全理解TCP与UDP之间的不同点。

  我们知道,TCP与UDP之间的最大不同点在于:TCP是可靠连接的,而UDP是无连接的。如果通信双方使用TCP协议,那么他们之前必须事先
通过监听+连接的方式将双方的通信管道建立起来;而如果通信双方使用的是UDP通信,则双方不用事先建立连接,发送方只管向目标地址上的目标端口发送
UDP包即可,不用管对方到底收没收到。如果要说形象点,可以用这样一句话概括:TCP是打电话,UDP是发电报。TCP通信,为了保持这样的可靠连接,
在可靠性上下了很多功夫,所以导致了它的通信效率要比UDP差很多,所以,一般地,在地实时性要求非常高的场合,会选择使用UDP协议,比如常见的动作射
击类游戏。

  通过载包,我们发现泡泡堂中同时采用了TCP和UDP两种通信协议。并且,具有以下特点:
  1.当玩家未进入具体的游戏地图时,仅有TCP通信存在,而没有UDP通信;
  2.进入游戏地图后,TCP的通信量远远小于UDP的通信量
  3.UDP的通信IP个数,与房间内的玩家成一一对应关系(这一点,应网友疑惑而加,此前已经证实)

  以上是几个表面现象,下面我们来分析它的本质和内在。^&^

  泡泡堂的游戏逻辑,简单地可以归纳为以下几个方面:
  1.玩家移动
  2.玩家埋地雷(如果你觉得这种叫法比较土,你也可以叫它:下泡泡,呵呵)
  3.地雷爆炸出道具或者地雷爆炸困住另一玩家
  4.玩家捡道具或者玩家消灭/解救一被困的玩家

  与MMORPG一样,在上面的几个逻辑中,广播量最大的其实是玩家移动。为了保持玩家画面同步,其他玩家的每一步移动消息都要即时地发给其它玩家。

  通常,网络游戏的逻辑控制,绝大多数是在服务器端的。有时,为了保证画面的流畅性,我们会有意识地减少服务器端的逻辑判断量和广播量,当然,这
个减少,是以“不危及游戏的安全运行”为前提的。到底如何在效率、流畅性和安全性之间作取舍,很多时候是需要经验积累的,效率提高的过程,就是逻辑不断优
化的过程。不过,有一个原则是可以说的,那就是:“关键逻辑”一定要放在服务器上来判断。那么,什么是“关键逻辑”呢?

  拿泡泡堂来说,下面的这个逻辑,我认为就是关键逻辑:玩家在某处埋下一颗地雷,地雷爆炸后到底能不能炸出道具以及炸出了哪些道具,这个信息,需要服务器来给。那么,什么又是“非关键逻辑”呢?

  “非关键逻辑”,在不同的游戏中,会有不同的概念。在通常的MMORPG中,玩家移动逻辑的判断,是算作关键逻辑的,否则,如果服务器端不对客
户端发过来的移动包进行判断那就很容易造成玩家的瞬移以及其它毁灭性的灾难。而在泡泡堂中,玩家移动逻辑到底应不应该算作关键逻辑还是值得考虑的。泡泡堂
中的玩家可以取胜的方法,通常是确实因为打得好而赢得胜利,不会因为瞬移而赢得胜利,因为如果外挂要作泡泡堂的瞬移,它需要考虑的因素和判断的逻辑太多
了,由于比赛进程的瞬息万变,外挂的瞬移点判断不一定就比真正的玩家来得准确,所在,在玩家移动这个逻辑上使用外挂,在泡泡堂这样的游戏中通常是得不偿失
的(当然,那种特别变态的高智能的外挂除外)。从目前我查到的消息来看,泡泡堂的外挂多数是一些按键精灵脚本,它的本质还不是完全的游戏机器人,并不是通
过纯粹的协议接管实现的外挂功能。这也从反面验证了我以上的想法。

  说到这里,也许你已经明白了。是的!TCP通信负责“关键逻辑”,而UDP通信负责“非关键逻辑”,这里的“非关键逻辑”中就包含了玩家移动。
在泡泡堂中,TCP通信用于本地玩家与服务器之间的通信,而UDP则用于本地玩家与同一地图中的其他各玩家的通信。当本地玩家要移动时,它会同时向同一地
图内的所有玩家广播自己的移动消息,其他玩家收到这个消息后会更新自己的游戏画面以实现画面同步。而当本地玩家要在地图上放置一个炸弹时,本地玩家需要将
此消息同时通知同一地图内的其他玩家以及服务器,甚至这里,可以不把放置炸弹的消息通知给服务器,而仅仅通知其他玩家。当炸弹爆炸后,要拾取物品时才向服
务器提交拾取物品的消息。

  那么,你可能会问,“地图上某一点是否存在道具”这个消息,服务器是什么时候通知给客户端的呢?这个问题,可以有两种解决方案:
  1.客户端如果在放置炸弹时,将放置炸弹的消息通知给服务器,服务器可以在收到这个消息后,告诉客户端炸弹爆炸后会有哪些道具。但我觉得这种方案不好,因为这样作会增加游戏运行过程中的数据流量。
 
 2.而这第2种方案就是,客户端进入地图后,游戏刚开始时,就由服务器将本地图内的各道具所在点的信息传给各客户端,这样,可以省去两方面的开销:a.
客户端放炸弹时,可以不通知服务器而只通知其它玩家;b.服务器也不用在游戏运行过程中再向客户端传递有关某点有道具的信息。
  
  但是,不管采用哪种方案,服务器上都应该保留一份本地图内道具所在点的信息。因为服务器要用它来验证一个关键逻辑:玩家拾取道具。当玩家要在某点拾取道具时,服务器必须要判定此点是否有道具,否则,外挂可以通过频繁地发拾取道具的包而不断取得道具。

  至于泡泡堂其它游戏逻辑的实现方法,我想,还是要依靠这个原则:首先判断这个逻辑是关键逻辑吗?如果不全是,那其中的哪部分是非关键逻辑呢?对
于非关键逻辑,都可以交由客户端之间(UDP)去自行完成。而对于关键逻辑,则必须要有服务器(TCP)的校验和认证。这便是我要说的。

  以上仅仅是在理论上探讨关于泡泡堂类游戏在通信架构上的可能作法,这些想法是没有事实依据的,所有结论皆来源于对封包的分析以及个人经验,文章
的内容和观点可能跟真实的泡泡堂通信架构实现有相当大的差异,但我想,这并不是主要的,因为我的目的是向大家介绍这样的TCP和UDP通信并存情况下,如
何对游戏逻辑的进行取舍和划分。无论是“关键逻辑”的定性,还是“玩家移动”的具体实施,都需要开发者在具体的实践中进行总结和优化。此文全当是一个引子
罢,如有疑问,请加Msn讨论。

泡泡堂、QQ堂游戏通信架构分析的更多相关文章

  1. SLG手游Java服务器的设计与开发——架构分析

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  2. 1 游戏逻辑架构,Cocos2d-x游戏项目创建,HelloWorld项目创建,HelloWorld程序分析,(CCApplicationProtocol,CCApplication,AppDeleg

     1 游戏逻辑架构 具体介绍 A 一个导演同一时间仅仅能执行一个场景,场景其中,能够同一时候载入多个层,一个层能够可载多个精灵.层中亦能够加层. B  场景切换 sceneàaddChild(la ...

  3. 分布式MySQL数据库TDSQL架构分析

    摘要:腾讯计费平台部为了解决基于内存的NoSQL解决方式HOLD平台在应对多种业务接入时的不足.结合团队在MySQL领域多年应用和优化经验,终于在MySQL存储引擎基础上,打造一套分布式SQL系统TD ...

  4. Qualcomm Android display架构分析

    Android display架构分析(一) http://blog.csdn.net/BonderWu/archive/2010/08/12/5805961.aspx http://hi.baidu ...

  5. apache kafka系列之性能优化架构分析

    apache kafka中国社区QQ群:162272557 Apache kafka性能优化架构分析 应用程序优化:数据压缩 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  6. Deep Learning论文笔记之(六)Multi-Stage多级架构分析

    Deep Learning论文笔记之(六)Multi-Stage多级架构分析 zouxy09@qq.com http://blog.csdn.net/zouxy09          自己平时看了一些 ...

  7. 高通Android display架构分析

    目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...

  8. [转帖]InfiniBand技术和协议架构分析

    InfiniBand技术和协议架构分析 2017年06月06日 20:54:16 Hardy晗狄 阅读数:15207 标签: 云计算存储Infiniband 更多 个人分类: 存储云计算   版权声明 ...

  9. tomcat架构分析 (connector NIO 实现)

    出处:http://gearever.iteye.com 上一篇简单记录了缺省配置的connector的内部构造及消息流,同时此connector也是基于BIO的实现.除了BIO外,也可以通过配置快速 ...

随机推荐

  1. android 单词

    inflate: 胀, 膨, 通货膨胀, 膨胀系数

  2. js作用域的一个小例子

    var foo = function(){ var a =3,b=5; var bar = function(){ var b=7,c=11; alert("111a="+a+&q ...

  3. phpstorm10.0.1和webstorm11注册

    webstorm11 for win 注册时选择“License server”输入“http://15.idea.lanyus.com/”点击“OK” phpstorm10.0.1 for win ...

  4. mysql script for dynamic running sql script

    ),startTime datetime,endTime datetime) BEGIN set @s1 = concat('SELECT * FROM ', deviceName , ' where ...

  5. Android telnet RPi 2B

    /************************************************************************* * Android telnet RPi 2B * ...

  6. HDU 5273 Dylans loves sequence (逆序对,暴力)

    题意: 给定一个序列,对于q个询问:(L,R)之间有几个逆序对?序列元素个数上限1000,q上限10万.仅1测试例子. 思路: [L,R]的逆序对数量可以这么算,假设L<=K<R,将区间拆 ...

  7. 【Python】控制流语句、函数、模块、数据结构

    1.三种控制流语句:if\for\while 2.每句后都要加冒号 3.有elif语句=else后加一个if 注意使用变量名! 注意缩进! 注意控制流语句后面要加冒号! 4.for i in rang ...

  8. 史上最完整的Android开发工具集合

    路径: http://www.apkbus.com/thread-252748-1-1.html

  9. hdu 2167(状态压缩基础题)

    题意:给你一个矩阵,让你在矩阵中找一些元素使它们加起来和最大,但是当你使用某一个元素时,那么这个元素周围的其它八个元素都不能取! 分析:这是一道比较基础的状态压缩题,也是我做的第三道状态压缩的题,但是 ...

  10. -Xbootclasspath参数、java -jar参数运行应用时classpath的设置方法

    当用java -jar yourJarExe.jar来运行一个经过打包的应用程序的时候,你会发现如何设置-classpath参数应用程序都找不到相应的第三方类,报ClassNotFound错误.实际上 ...