【本文转自网络http://janeky.iteye.com/blog/1614175】
这段时间在处理服务端人物移动广播遇到了问题,记录一下。
1.问题
现在的页游都朝着客户端的方向靠齐了,大地图,千人同屏。因此,也给页游的服务端开发带来了不少的挑战。假设一个场景地图是8000*8000大小,同时有1000人在。1秒钟内,每个玩家移动一次。按照最原始的做法,就是给同一个场景的用户广播消息。简单计算一下广播量:1000*1000=1000000的广播量,有点恐怖。
2.方案
优化的目标肯定是减少广播量了。我们看到,场景特别大,这对于美术同事来说不是什么好事了,对于服务端来说,未尝是坏事。假设最理想的状态下,用户能够遍布各个角落。那么,我们只想向能看到移动目标的用户广播消息就行了。假设一个屏幕大小为1600*1000,一个屏幕理论上分布了8000*8000/(1600*1000)=25人。还是每秒每个人移动一次,总的广播消息量是:25*25*40 = 25000.哈哈,整整少了40倍的广播量,服务端压力少了,替老板省了不少钱,回去申请加点奖金吧。
3.实现
按照上面的思路,实现起来就非常简单了。以前是给场景的每个用户广播,现在只需增加一步筛选的过程,根据坐标选择视范围内能看到移动目标的玩家。方法比较简单,这里就不提供详细的代码实现了,还有不清楚的,可以留言讨论一下。
4.优化
做到上面的,基本上已经符合标准了。但是,作为搞技术的,追求完美是无止境的。我们又在想,还能不能进一步优化?好的优化总是在仔细分析问题的基础上产生的。我们相信分析一下广播的内容,加入a移动了,那么在同屏的b,c分别会受到一条广播,内容大致是(a,from,to).同理,b移动了,a,c也是受到这样类型的广播。c在同一个时间段收到了两条广播。这两条广播能否合并呢,变成(a,from,to;b,from,to).这就是优化的灵感了。对于实时性不高的回合制页游(非即使战斗arpg),玩家看到其他玩家的移动,并不要求一定实时。为此,我们可以考虑合并
消息。
实现起来非常简单,可以用一种类似生产者-消费者的模型来实现。每次前端发来的位移消息都放入队列。后端有个独立的线程,每隔一段时间,取出来数据,合并消息,广播给相关的用户。上述a,b位移后,c只收到一条消息了
5.总结
很多问题的解决是来自对问题的透彻理解。遇到问题,我们应该庆幸,又有折腾了。