ET6.0伺服器架構學習筆記(一、啟動配置)
最近ET6.0架構越發趨于完善,剩下的基本上都是小改動,ET6.0相比5.0新增了機器人架構,簡易AI架構,協程鎖(逾時處理),更加精簡的ETTASK等等。
之前都是讀源碼的方式來解讀5.0,6.0打算從使用的角度來解讀(當然也會附帶說下核心的代碼)
文章目錄
- ET6.0伺服器架構學習筆記(一、啟動配置)
- 從配置表開始
- 一、啟動ET伺服器
-
- 1.編譯生成所有代碼
- 2.改動配置表
- 3.啟動App
- 二、ET啟動核心代碼解析
-
- 1.啟動類Server.App項目Program類
- 2.Server.Hotfix項目AppStart_Init類
- 2.Server.Hotfix項目SceneFactory類
- 總結
從配置表開始
ET6.0伺服器啟動,需要依靠幾個預設的配置表,如下圖:
每個表的作用:
- StartMachineConfig:啟動的實體機器配置,每一條代表一台實體機,包括id,内外網位址,以及一個守護程序端口
- StartZoneConfig:相關遊戲區的配置,現在裡面已經寫好的配置,每一條代表一個區連接配接的資料庫配置
- StartProcessConfig:啟動的程序配置,當啟動一個ET6.0的伺服器時,會根據傳入的資料讀取這個配置确定伺服器應該以什麼樣的配置運作目前程序
- StartSceneConfig:啟動伺服器時,這個表裡面的配置,決定了給這個伺服器添加什麼類型的服務功能(暫且了解為,其中的一個場景就是一種服務,對應有:Realm服(用于認證玩家),Gate服(經過認證後所有與用戶端通信),Location服(用于提供查找Actor定位服),Map服(用于管理玩家遊戲實體,互相通信))。注意Process字段表示所屬的程序,Zone字段表示遊戲區的概念。如果這裡的Process填的程序id與StartProcessConfig對不上,那麼沒有任何服務功能會在啟動的伺服器裡。
一、啟動ET伺服器
1.編譯生成所有代碼
按照ETBOOK以及論壇裡面的方法,對Client-Server.sln解決方案,重新生成解決方案,如下圖:
出現下圖提示,則代表生成成功:
2.改動配置表
為了驗證功能,我們增加一個程序配置:
然後把所有StartSceneConfig表裡面的配置改成2,這樣所有服務都在2号程序啟動。
切換配置表導出工具,跑一下:
出現下面情況,則導表成功。
備注:如果導表失敗,可能由于EXCEL的備份檔案存在,把隐藏檔案夾打開删除那些備份的,或者改代碼去掉~開頭的檔案。
3.啟動App
切換回Server.App項目,配置啟動參數(我這裡用的Visual Studio)。也可以通過指令行的方式啟動,并傳入參數。
我們看看有哪些參數可以傳,直接打開Options類,可以看到裡面帶有Option特性的都是可以解析出來的參數,且使用的長名稱,且有預設值,是以不配置走預設的,也可以啟動APP,但是為了了解ET6.0我們需要配置參數。
這裡我們假設啟動的是2号程序,是以傳入參數 --Process 2
配置好後,直接啟動,沒有報錯,啟動成功。
檢視日志檔案啟動成功,都啟動成功,說明啟動的2号程序,裡面配置的所有服都啟動成功:
為了測試,我們把Gate2配置為1号程序,再次啟動看看日志如下,隻有Gate1啟動了:
二、ET啟動核心代碼解析
1.啟動類Server.App項目Program類
這個類主要功能:
- 設定線程同步上下文,用于将異步方法全都能通過Post方法回到主線程調用:
SynchronizationContext.SetSynchronizationContext(ThreadSynchronizationContext.Instance);
- 給Event類注冊Server.Model工程與Server.Hotfix工程的程式集資訊。主要用于将各類特性标簽與類型資訊注冊到Event類中進行管理,同時還包括:注冊各個元件的生命周期事件系統(Load,Awake,Update,LateUpdate,Destroy等);各個事件監聽的注冊等。
- 初始化protobufHelper類:用于序列化Protobuff用,MongoHelper類:用于序列化Mongo用,雖然兩個init現在沒啥用。
- 解析啟動傳入的指令行參數,初始化伺服器啟動參數Option。
- 派發一個伺服器啟動事件:
Game.EventSystem.Publish(new EventType.AppStart());
- 驅動整個遊戲循環,包括:Update();LateUpdate();FrameFinish();
2.Server.Hotfix項目AppStart_Init類
這個類繼承了AEvent<EventType.AppStart>,并傳入了事件類型結構體EventType.AppStart。是以在上一步Event中初始化時,就執行個體化了AppStart_Init類,且監聽了事件EventType.AppStart。是以上面第5步,派發事件EventType.AppStart時,會進入到AppStart_Init類的Run方法中。
-
初始化第一個伺服器Scene,Game.Scene,然後給這個Scene添加各種元件:
TimerComponent:定時器
OpcodeTypeComponent:協定管理
MessageDispatcherComponent:普通消息派發處理
CoroutineLockComponent:協程鎖
ActorMessageSenderComponent:普通Actor消息發送
ActorLocationSenderComponent:帶定位的Location Actor消息發送
LocationProxyComponent:定位服處理
ActorMessageDispatcherComponent:Actor消息派發處理
NumericWatcherComponent:數值變化訂閱處理
NetThreadComponent:網絡服務管理(注意不是處理隻是管理)
- 根據服務類型,建立不同服務,暫且不管監聽服務,隻管遊戲服務。增加内網元件,用于處理來自伺服器各個服務之間的通信(包括不同程序之間的)`Game.Scene.AddComponent<NetInnerComponent, IPEndPoint>(processConfig.InnerIPPort);
- 在遊戲服類型下,按照配置的StartScene配置,建立對應屬于這個服程序号的子Scene。`
2.Server.Hotfix項目SceneFactory類
用于建立各個Scene實體類,核心代碼如下:
public static async ETTask<Scene> Create(Entity parent, long id, long instanceId, int zone, string name, SceneType sceneType, StartSceneConfig startSceneConfig = null)
{
await ETTask.CompletedTask;
Scene scene = EntitySceneFactory.CreateScene(id, instanceId, zone, sceneType, name, parent);
scene.AddComponent<MailBoxComponent, MailboxType>(MailboxType.UnOrderMessageDispatcher);
switch (scene.SceneType)
{
case SceneType.Realm:
scene.AddComponent<NetKcpComponent, IPEndPoint>(startSceneConfig.OuterIPPort);
break;
case SceneType.Gate:
scene.AddComponent<NetKcpComponent, IPEndPoint>(startSceneConfig.OuterIPPort);
scene.AddComponent<PlayerComponent>();
scene.AddComponent<GateSessionKeyComponent>();
break;
case SceneType.Map:
scene.AddComponent<UnitComponent>();
scene.AddComponent<RecastPathComponent>();
break;
case SceneType.Location:
scene.AddComponent<LocationComponent>();
break;
}
return scene;
}
- 根據傳入的服務類型,startScene配置ID,InstanceId(這個很重要,它是由生成對應StartSceneConfig單條配置時,由程序号與配置ID組合成的實體ID,通過這個實體ID可以找到對應的程序IP與端口用于通信),服務區号,伺服器類型等資訊,建立一個服務Scene。
- 對Scene挂載MailBoxComponent元件,用于處理Actor請求,并且區分是否需要按順序處理收到的請求。(備注:挂在了MailBoxComponent的Entity類就可以處理Actor消息,且可以有順序處理的功能,Scene也是Entity的一種)
-
針對伺服器類型,給上面生成的服務Scene挂載各類功能元件:
NetKcpComponent:網外通信元件,用于監聽來自用戶端的通信處理
PlayerComponent:用于管理生成的Player實體
GateSessionKeyComponent:用于管理玩家認證的憑據(主要用于Gate認證玩家連接配接是否被允許)
UnitComponent:用于管理Map中的Unit實體
RecastPathComponent:尋路元件
LocationComponent:用于管理實體對象ID與InstanceID之間的關系,提供了通過ID查詢InstanceID的功能。
貓大已經在ET6.0中組合好各個服務類型Scene,應該具備的功能元件。當所有服配置在一個程序中時,就相當于5.0的All Server模式了。
現在伺服器已經啟動好了,剩下的隻需要,定義好協定,注冊好協定處理類,進行邏輯開發就可以愉快的開發下去了。
總結
本篇隻針對伺服器啟動如何配置啟動,且記錄了幾個核心啟動相關的類,進行了說明,下一篇從第一個登入協定講解開始。