前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity游戏开发Photon Server之服务端架构

Unity游戏开发Photon Server之服务端架构

作者头像
bering
发布2019-12-03 15:36:22
1.3K0
发布2019-12-03 15:36:22
举报
文章被收录于专栏:游戏开发之旅游戏开发之旅

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/CJB_King/article/details/53560493

Unity游戏开发Photon Server之服务端架构

首先,服务端分两大部分,第一部分是服务端和客户端都需要使用的部分,第二部分就是接收客户端请求并发送数据的逻辑处理部分,也就是服务端架构了;

一.服务端和客户端通用部分

我们建立一个类库项目,将服务端和客户端需要进行通讯的数据类型存储在这里,包括操作代码(OperationCode),参数的增加和提取(ParameterTool.GetParameter<T>和ParameterTool.AddParameter),以及参数的代码(ParameterCode)等.此外,数据库中的数据类型(DBModel(这里面的类是用来检索暂时存储数据库中的数据的))也放在这里.ParameterTool中的类如下:

代码语言:javascript
复制
 public class ParameterTool {
        public static T GetParameter<T>(Dictionary<byte,object> parameters,ParameterCode parameterCode ,bool isObject = true)
        {
            object o = null;
            parameters.TryGetValue((byte) parameterCode, out o);
            if (isObject==false)
            {
                return (T) o;
            }
            return JsonMapper.ToObject<T>(o.ToString());
        }

        public static void AddParameter<T>(Dictionary<byte, object> parameters, ParameterCode key, T value,
            bool isObject = true)
        {
            if (isObject)
            {
                string json = JsonMapper.ToJson(value);
                parameters.Add((byte) key, json);
            }
            else
            {
                parameters.Add((byte) key, value);
            }
        }

        public static SubCode GetSubcode(Dictionary<byte, object> parameters)
        {
            return GetParameter<SubCode>(parameters, ParameterCode.SubCode, false);
        }

        public static void AddSubcode(Dictionary<byte, object> parameters, SubCode subcode)
        {
            AddParameter<SubCode>(parameters,ParameterCode.SubCode, subcode,false);
        }

        public static void AddOperationcodeSubcodeRoleID(Dictionary<byte, object> parameters, OperationCode opCode, int roleID)
        {
            if(parameters.ContainsKey((byte) ParameterCode.OperationCode))
            {
                parameters.Remove((byte) ParameterCode.OperationCode);
            }
            if(parameters.ContainsKey((byte) ParameterCode.RoleID))
            {
                parameters.Remove((byte) ParameterCode.RoleID);
            }
            parameters.Add((byte)ParameterCode.OperationCode, opCode);
            parameters.Add((byte)ParameterCode.RoleID, roleID);
        }
    }

Model中是和数据库中表对应的类,除开一个工具类之外,其它的都是枚举类型.暂时所用到的结构就是这样.总结一下就是:Models,

Tools,OperationOfCodes。

二.服务端架构

服务端有一个继承了ApplicationBase的ArpgApplication类,还有一个继承了PeerBase的ClientPeer.服务端接收到了连接的请求后会创建ClientPeer,接受Request和发送Response的函数都在ClientPeer中.

主要结构如下图:

此结构中所有的Handler与客户端的各个Controller对应,一个Controller对应一个Handler,他们之间处理相应的Request和Response.在服务端调用的时候,先是ClientPeer接收到Request,然后根据OperationCode,判断该调用哪个Handler,在ArpgApplication中找到对应的Handler,然后把Request发给它让它进行处理,返回处理的结果Response,发送给客户端.

在Handler处理的过程中,一般都会需要对数据库进行操作,所有的操作都封装在DB.Manager中,对相应的数据库操作调用相应的的Manager中的方法即可.

附上继承自ApplicationBase类的代码示例:

代码语言:javascript
复制
 public class ARApplication : ApplicationBase
    {
        public List<ARPeer> peerListForTeam = new List<ARPeer>();
        public Dictionary<byte, HandlerBase> handlers = new Dictionary<byte, HandlerBase>();
        private static ARApplication _instance;
        private static readonly ILogger log = ExitGames.Logging.LogManager.GetCurrentClassLogger();
        public ARApplication()
        {
            _instance = this;
            RegisterHandler();
        }
        public static ARApplication AR_Instance
        {
            get {
                return _instance;
            }
        }
        void RegisterHandler()
        {
            //handlers.Add((byte)OperationCode.Login,new LoginHandler());
            //handlers.Add((byte)OperationCode.MakeRoom,new MakeRoomHandler());
            Type[] types = Assembly.GetAssembly(typeof(HandlerBase)).GetTypes();   //得到所有继承自HandlerBase的类
            foreach (var type in types)
            {
                if (type.FullName.EndsWith("Handler"))
                {
                    Activator.CreateInstance(type);    //创建类的实例,为了能够使各个Handler的构造函数实现在ARApplication中注册
                }
            }
        }
        protected override PeerBase CreatePeer(InitRequest initRequest)
        {
            return new ARPeer(initRequest.Protocol,initRequest.PhotonPeer);
        }

        protected override void Setup()
        {
            ExitGames.Logging.LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
            GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "log");
            GlobalContext.Properties["LogFileName"] = "MS" + this.ApplicationName;
            XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(this.BinaryPath, "log4net.config")));
            log.Debug("ARServer is Setup!!!");
        }

        protected override void TearDown()
        {
            log.Debug("ARServer is TearDown!!!");
        }
    }

接着看继承自PeerBase类的实例:

代码语言:javascript
复制
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            HandlerBase handler;
            ARApplication.AR_Instance.handlers.TryGetValue(operationRequest.OperationCode, out handler);
            if (handler != null)
            {
                OperationResponse response = new OperationResponse();
                response.OperationCode = operationRequest.OperationCode;
                response.Parameters = new Dictionary<byte, object>();
                handler.OnHandlerMessage(operationRequest, response, this,sendParameters);
                SendOperationResponse(response, sendParameters);
            }
            else
            {
                //ARApplication的字典Handlers中没有operationRequest.OperationCode对应的Handler;
            }
        }

抽象的基类HandlerBase中的代码示例如下(各种Handler继承自HandlerBase并实现重写其中的抽象方法):

代码语言:javascript
复制
  public abstract class HandlerBase
    {
        private static readonly ILogger log = ExitGames.Logging.LogManager.GetCurrentClassLogger();
        public HandlerBase()
        {
            ARApplication.AR_Instance.handlers.Add((byte)opCode, this); //在Application类中注册各种Handler
            log.Debug("Hanlder:" + this.GetType().Name + "  is register.");
        }
        public abstract void OnHandlerMessage(OperationRequest request,OperationResponse response, ARPeer peer, SendParameters sendParameters);
        public abstract OperationCode opCode
        {
            get;
        }
    }

大致就像下图:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Unity游戏开发Photon Server之服务端架构
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档