HTML5技术

游戏服务端究竟解决了什么问题? - fingerpass(6)

字号+ 作者:H5之家 来源:H5之家 2016-02-02 09:51 我要评论( )

在这个过程中,我们称调用方可以调用的是服务的delegate(可以类比为Stub),被调用方注册进来的是服务的implement(可以类比为Skeleton)。路由适配层就是Adaptor。可以基于不同类型的Adaptor构造服务的delegate。

  在这个过程中,我们称调用方可以调用的是服务的delegate(可以类比为Stub),被调用方注册进来的是服务的implement(可以类比为Skeleton)。路由适配层就是Adaptor。可以基于不同类型的Adaptor构造服务的delegate。服务的implement也可以注册在不同的Adaptor上。不同的Adaptor只需要针对RPC层提供同样的接口,让RPC层可以发送打包消息和服务特定的路由规则,可以注册implement即可保证RPC层与Adaptor层是完全无关的。

 

  我们在示例中实现了多种Adaptor,目前为止涉及到的有MqttAdaptor、GateAdaptor、AmqpAdaptor。


  除了这整个的数据流之外,示例中还包装了两种异步调用与回调形式。

  • 一种是针对.Net 2.0的callback模式;
  • 一种是针对.Net 4.5的Task await/async模式。
  •   第一种专门针对不支持.Net 4.5的平台,比如Unity。但是只要针对这种形式稍加扩展,也能支持.Net 2.0的yield语义,实现简单协程。关于.Net 2.0中的协程实现,可以参考这里。

     

      两种异步方式实现回调的原理是相同的,都是本地hold住调用上下文,等回包的时候检查即可。

      这样,在支持.Net 4.5的平台,一个穿插了RPC调用的函数就可以写成这个样子:

      

    1 int a = GetNumber(0); 2 int b = await SceneToSceneMgrService.GetNumber(a); 3 int c = b;

    View Code

     

      在Unity中的脚本逻辑,可以这样调用RPC:

    1 service.AskXXX(x, y).Callback = 2 operation => 3 { 4 if (operation.IsComplete) 5 { 6 var ret = operation.Result; 7 } 8 };

    View Code

     

    关于一些细节的说明

    引入新的问题

      有了RPC之后,我们可以在应用层以统一的形式进行服务请求。

      但是这样还不够——我们目前所提的RPC就是普通的方法调用,虽然对应用层完全隐藏了协议或者其他中间件的细节,但是这样一来这些中间件的强大特性我们也就无法利用了。

      还应该有另一种与RPC平行的抽象来特化RPC的形式,这种抽象与RPC共同组成了一种游戏开发规范。

     

    3.3.2 RPC、Pattern与规范

     

    定义问题

      由于不同的中间件解决问题的方式不同,因此我们没办法在应用层用统一的形式引用不同的中间件。因此,我们可以针对游戏开发中的一些比较经典的消息pipeline,定义pattern。然后,用pattern与RPC共同描述服务应该如何声明,如何被调用。

    Pattern解决了什么问题
  • pattern规定了客户端与服务、服务与服务的有限种交互形式。
  • pattern解决了之前我们只能靠感觉确定服务应该走哪种基础设施抽象的问题。
  •   不同的基础设施抽象可以实现不同的pattern子集,如果需要新增加一类基础设施,我们可以看它的功能分别可以映射到哪几种pattern上,这样就能直接集成到Phial规范中。

      下面,就针对游戏服务端的常见需求,定义几种pattern。

      三种通信情景:

  • client -> server
  •   最简单的pattern是ask,也就是向服务发起一次异步调用,然后client不关注服务的处理结果就直接进行后续的逻辑。最常见的就是移动请求。
      还有一种是传统MMO中不太重视,而异步交互手游反倒从web引入的request。client向服务发起一次异步调用,但是会等到服务处理结果返回(或超时)才进行后续的逻辑。例子比较多,比如一次抽卡或者一次异步PVP。

  • server -> client
  •   与ask对应的是sync,是服务进行一次无源的对client的impl调用,client无条件执行impl逻辑。sync需要指明被调用方。这种最常见的是移动同步。有一点需要注意,示例中实现了一种形式比较丑陋的组播sync,依赖了Gate的私有协议,也就是forward指定一个int值。这个之后会做调整。

      与request对应的是reply。这个相当于是处理一次request然后直接返回一个值,没什么特别之处。

  • server -> server
  •   最常见的就是invoke,相当于一次希望返回值的远程调用。例子有很多,适用于任意两个服务间的通信需求。

      还有一种解耦利器我称之为notify。当然本质上其实就是pub-sub,消息会在中间件上dup。应用情景是消息提供者/事件源只管raise event,而不关注event是否被处理、event后续会被路由到哪里。在中间件上,只要有服务实现了该notify service的impl,就能得到通知;如果没有任何节点提供对该服务的impl,就相当于消息被推到了sink。应用情景是可以将玩家行为log以及各种监控、统计系统逻辑从业务代码中剥离出来,事件源触发的逻辑只有一处,而处理的逻辑可以分散在其他监控进程中,不需要增加一种监控就得在每个事件源都对应插一行代码。

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 网页版扫雷游戏 - 季末的寂寞

      网页版扫雷游戏 - 季末的寂寞

      2017-04-21 13:00

    • net.sz.framework 框架 登录服务器架构 单服2 万 TPS(QPS) - 失足程序员

      net.sz.framework 框架 登录服务器架构 单服2 万 TPS(QPS) - 失足

      2017-04-13 11:05

    • 面向个人的技术咨询服务 - 思想瞭望者

      面向个人的技术咨询服务 - 思想瞭望者

      2017-04-05 12:07

    • net.sz.framework 框架 轻松搭建服务---让你更专注逻辑功能---初探 - 失足程序员

      net.sz.framework 框架 轻松搭建服务---让你更专注逻辑功能---初探 -

      2017-04-02 10:11

    网友点评
    )