1. 程式人生 > >Unity3D開發之網路遊戲中伺服器端的架構設計

Unity3D開發之網路遊戲中伺服器端的架構設計

    最近在研究網路遊戲開發,感覺結構很好玩,所以就將自己學到了解到的記錄下來。部落格前幾篇的Socket通訊講的就是網路遊戲部分Socket的基本結構。上一篇的對MySql使用就是伺服器對資料庫的連線使用。今天要介紹的就是遊戲伺服器的設計架構以及一些核心程式碼。

    通常,網路遊戲開發需要跟伺服器互動的模組是登陸,註冊,建立房間,進入房間,開始遊戲,位置同步,動畫同步等等等等。我們在開發之前需要設定我們的開發模式以及開發協議。比如在登陸時,我們不光要傳送我們輸入的使用者名稱和密碼,還要傳送我們設定的請求模組和響應模組。即RequestCode和ActionCode。這樣,我們在客戶端這面每次傳送資料格式為

資料頭(4位元組)+RequestCode(列舉型別,4位元組)+ActionCode(列舉型別,4位元組)+data(未知位元組)

這樣我們在服務端就要對我們的資料進行對應的解析了。在服務端我們規定通過RequestCode來尋找對應處理的Controller模組。處理完我們在將資料返回的資料+ActionCode返回給客戶端,客戶端在根據ActionCode尋找對應的Controller來處理伺服器傳送回來的響應。

    如Socket通訊那篇講的我們用建立Server類來建立一個服務端,然後在建立一個Client類來分別管理連線進來的客戶端,這樣對客戶端的管理會非常直觀。我們在客戶端通過Message類對接收到的資料進行解析。會得到如下格式的三個資料:RequestCode,ActionCode,String。

然後我們使用回撥函式將資料傳入我們用於專門處理請求響應的函式。嗯,這時候我們的另一個管理類指令碼就要誕生了。就是ControllerManager。ControllerManager是用於對所有Controller模組進行管理。下面是我們部分程式碼可以直觀瞭解下:

首先我們需要建立BaseController,讓之後的Controller繼承自BaseController,這樣方便ControllerManager來統一管理。

abstract class BaseController
    {
        protected RequestCode requestCode=RequestCode.None;

        public RequestCode RequestCode { get { return requestCode; } }

        public virtual string DefaultHandle(string data,Client client,Server server){return null;}
    }

接下來我們建立一個UserController來處理對於登陸,註冊等使用者資訊相關的請求。

class UserController:BaseController
    {
        public UserController()
        {
            requestCode=RequestCode.User;//設定requestCode為User 這樣所有傳送User相關的請求都會在這個類裡處理
        }
        //這裡要保證函式名和我們的actionCode名字一樣 這樣才能找到對應的處理函式
        public string Login(string data,Client client,Server server)
        {
            
        }
    }

下面是我認為很重要的ControllerManager程式碼:

class ControllerManager
    {
        private Server server;
        private Dictionary<RequestCode,BaseController> controllerDic=new Dictionary<RequestCode, BaseController>(); 

        public ControllerManager(Server server)
        {
            this.server = server;
            InitController();
        }

        private void InitController()
        {
            DefaultController defaultController=new DefaultController();
            controllerDic.Add(defaultController.RequestCode,defaultController);
            UserController userController=new UserController();
            controllerDic.Add(userController.RequestCode,userController);//將建立的controller新增到字典裡進行管理
        }
        //根據requestcode來尋找對應Controller 然後在通過ActionCode來尋找controller裡對應的函式來處理
        public void HandleRequest(RequestCode requestCode,ActionCode actionCode,string data,Client client)
        {
            BaseController controller;
            bool IsGet = controllerDic.TryGetValue(requestCode, out controller);
            if (IsGet == false)
            {
                Console.WriteLine("沒有找到對應的RequestCode"); return;
            }
            string methodName = Enum.GetName(typeof (ActionCode), actionCode);//獲取actionCode的名字
            MethodInfo mi = controller.GetType().GetMethod(methodName);//根據actionCode名字尋找controller裡對應的函式方法

            if (mi == null)
            {
                Console.WriteLine("沒有找到對應的方法");
                return;
            }
            object[] parameters=new object[] {data,client,server};//將需要傳進去的資料打包起來
            object o = mi.Invoke(controller, parameters);
            if (o == null || string.IsNullOrEmpty(o as string)) return;
            Console.WriteLine(o as string);
            server.SendResponse(client,actionCode,o as string);//將返回來的資料資訊和actioncode一起通過client類傳送回客戶端
        }
    }

而對於資料庫的連線,我們在client裡實現。在controller類裡我們可以通過引數client來很方便的實現對資料庫的資料的呼叫獲取。以上是服務端的設計架構。感覺很清晰,很好用。

    如果本部落格對你有幫助,記得點關注哦!