传统 MMORPG 通讯模式实现的一点想法
既然 MMORPG 都有千篇一律同质化的趋势,好歹我们技术人员也应该总结出点东西来,新项目开发可以用现成的模式。
一般来说,MMORPG 服务器要解决的问题无非是,同步玩家的位置,状态,把这些信息广播出去(细分的话,有非战斗环境和战斗环境);需要建立一个聊天服务,供玩家文字交流;有一个信息发布渠道;有任务 NPC 和玩家一对一交流;玩家调整自己的装备(也可以看成是和一特定 NPC 交流)。
以上,我们可以看到几个基本需求是可以正交分解出来,并有不同的实现方式的。
同步玩家的状态,基本上是由玩家自己不断提交自己的最新状态,然后由服务器把这些信息广播给其他人。
聊天服务比较成熟,基本上就是玩家订阅聊天频道,并按权限向频道内发布信息。
信息发布可以看成是一个特殊的聊天频道。
任务 NPC 或是整理自己装备,都类似于向特定节点做请求等待回复。
我经历的几个 MMO 项目都实现的比较简单,无论是 server 还是 client ,都是跑一个消息循环,对每个到来的消息包进行处理。通常都是一个 timer 消息源和一个网络包消息源,共同组成最终的消息源,主程序是标准的消息循环分发结构。
但对比前面的需求,可以看到,这些方式略显简陋。最后能再此基础上再做一个层次的封装工作,让这些不同的需求可以分开处理。更方便的解决一些有状态的需求,或是能够对信息处理进行优先级排序。
最近一段时间,我受 zeromq 的设计思想影响较多。对于未来的项目设计方法,我有一些想法需要梳理一下。
玩家 Client 和游戏 Server 方面,我还是倾向于采用单一的 TCP 连接。但是希望再其上加一个层次。可以在单一 TCP 连接上模拟多个通讯信道。实现 zeromq 提出的几个模式(的变形)。
在我看来,MMORPG 的服务器端,可以看成是若干服务的集合。那么这些服务无论布置在哪里,我都希望他们是在一个逻辑上的网络中。玩家通过网关也接入这个网络,并可以根据授权来使用网络上的服务。
抛开玩家登陆(注册)流程不谈。典型的场景是玩家在虚拟场景中漫步。这可以看成是 Client 订阅一个指定场景的环境。订阅本身会先鉴权,服务器会查阅玩家是否有权限订阅(玩家是否在这个场景中)。场景会不断的发布场景中每个玩家,NPC 的动态。订阅者将不断的获得这些信息。由于性能问题,我们可以把不同类别的信息放在不同的订阅点上。订阅可以按需进行。
玩家会选择向特定场景 PUSH 自己的状态数据,按 zeromq 的模式,这应该走另一个信道。
每个可对话的 NPC 都可以看成是一个特定服务。玩家向它建立连接,然后以 Request/Reply 模式工作。这样可以方便完成带状态的任务。同样,建立连接的过程可以引入鉴权(比如说检查玩家是否在 NPC 附近等)。当然,NPC 同样需要订阅场景,当场景中和他交流的玩家跑开后,可以自动切断信道。
战斗部分的处理可以独立。以即时战斗为例,战斗计算服务订阅场景中对象的位置和动作。计算他们的动作的后果,得到每次攻击的伤害值。它自己是一个信息订阅点,玩家通过订阅战斗服务,可以了解场景中每个个体受伤害的情况。
同样,某些增值服务,比如自动寻路,都可以独立出来实现。
只是一些想法,希望整理出来后,可以有更多启发。对人也对己。