ET網絡組件學習筆記

在ET的客戶端中,使用網絡要用到以下幾個組件(不介紹基礎設施)。

組件名稱 組件作用
OpcodeTypeComponent 消息類型加載組件。加載標記了【MessageAttribute】注解的類,作為消息執行的類型,并存儲在這個組件的opcodeTypes字段下,提供后續方法使用。
MessageDispatcherComponent 消息分發組件,加載消息處理器。加載所有標記了【MessageHandlerAttribute】屬性的類,并提供Handle方法,將傳入的MessageInfo發送給指定的消息處理器
NetworkComponent NetworkComponent是其他上層網絡訪問組件的基類,這個類型在服務端和客端項目公用。用于 指定該協議、指定構包解析方式、指定消息轉發器,開始socket監聽、創建session。內部有一個AService字段。抽象了udp和tcp協議的連接工廠,用于創建channel使用tcp做服端的時候可以創建多個Session,每個Session都是一個連接的高層抽象。這個類型在服務端和客戶端項目公用。其提供的MessageDispatch和MessagePacker僅在客戶端項目使用。一個是客戶端消息轉發器,一個是客戶端消息打包器。
NetOuterComponent 繼承自NetworkComponent,用于對外網的連接。可以在Awake中指定協議,指定包解析器。客戶端使用的session都是通過這個組件創建的。需要切換網絡協議或者數據序列化方式就在這個組件的Awake方法中指定對應的參數就可以了。
SessionComponent SessionComponent 組件用于存儲Seesion,目前客戶端只會存在一個在用的session。登錄后獲得的GateSession會存儲在這個組件中。會在之后的對服務器端的調用中使用這個session。
ClientFrameComponent 用于處理幀同步。

很重要的Session對象的解釋

每個Session都是一個連接的高層抽象。
向session另一端做rpc調用可以調用它的Call方法,發送消息可以調用Send,
二者的區別在于是否需要服務器響應一個反饋消息。
定義消息或者rpc請求的時候使用Message標簽設置消息類型與opcode的對應關系。
session是由NetworkComponent創建的,參數是 NetworkComponent的本類實例 + 用于收發字節碼的AChannel實例。這個AChannel則是由NetworkComponent中的AService工廠創建的。

流程:

1創建session后(調用構造函數),session開始StartRecv()方法,這個方法循環通過異步方法調用channel的Recv()方法,接收鏈接另一端發來的數據。
2接收到消息后調用Run方法,run方法檢查接收到的數據包是否有壓縮,并指向相應的操作。
3處理完壓縮解壓操作后交給RunDecompressedBytes,該方法比較厲害,調用綁定在Scene實體上的NetWorkConponent上的注冊的解包器(默認是Bson)解包。
4解包操作結束后就將其交給綁定在Scene實體上的NetWorkConponent上的messageDispatcher做轉發。轉發給相應的handler處理。

在大致了解了各組件的作用后,需要有一個大致的流程,把幾個組件串聯起來,實現客服端的網絡功能:

網絡流程如下:

1. OpcodeTypeComponent加載封裝好的網絡消息。

2. MessageDispatcherComponent加載所有的Handler

3. 開啟網絡監聽。NetOuterComponent加入到Scene,我們使用udp,做如下操作:、

  • a) 通過工廠從對象池中取出實例,調用父類Disposer的構造方法,加入到對象事件中心。
  • b) 調用父類NetworkComponent的構造方法,創建對應協議的連接工廠(AService)。
  • c) 調用NetOuterComponent的Awake()方法,指定網絡協議、消息解包器和消息轉發器。
  • d) NetworkComponent因為注冊了Update,所以會在每一幀執行Update,Update中會執行service的update。service的update中會執行poller的Update,這個Update實際上是 每一幀都要輪詢出所有的主機上的隊列事件,并且調用其委托。這些事件包括:開始連接、接收數據、斷開連接。這些事件的觸發,會調用poller實體上的socket的對應的響應方法。 socket事件的委托是在創建UChannel時注冊的。
  • e) UChannel的OnRecv()將接受到的消息放入到隊列中,等待被Session輪詢調用UChannel. Recv()方法取出。
  • f) 取出消息后就會調用給NetOuterComponent指定的消息轉發器。
    由于是客戶端,所以使用ClientDispatcher作為消息轉發器。這個消息轉發器在接收到幀循環消息后會進行客戶端時間補償處理。否則就直接將普通的rpc等消息交給MessageDispatcherComponent去做轉發了。當然,幀循環消息最終也會交給MessageDispatcherComponent做轉發。
  • g) Handle接收到消息后作出最終的處理。
  • h) D-g步驟是循環執行滴。
  • i) 底層enet等不深入討論,對我等透明。
  • j) 到此,網絡設施已經創建完畢,網絡監聽已經開啟,并等待使用。

4. 創建對外連接。創建對外連接指的是連接到服務器。一般情況下從登陸開始創建對外連接。并且存儲會話Gatesession。在整個客戶端游戲生命周期中,Gatesession是一直存在的而且只有一份。

  • a) 使用NetOuterComponent創建session。需指定要連接的地址和端口。這時候創建的session一般會是登錄服務器,因為登錄服務器在登錄成功后會返回一個網關地址。
  • b) 然后再根據這個網關地址創建游戲使用的session并且存入到SessionComponent中。
  • c) SessionComponent要加入到Scene實體保存。

5. 使用session通訊。

  • a) await SessionComponent.Instance.Session.Call<G2C_LoginGate>(new C2G_LoginGate() {Key = r2CLogin.Key})
  • b) 詳細參考doc中的《網絡層設計》使用說明書。

6. 拓展網絡功能以及建議。

  • a) 這個嘛,仁者見仁啦。
  • b) 注意。使用c#的異步語法實現異步網絡調用,是一件很舒服的事情,請詳細研究異步語法。并使用之。

- 登錄流程示例講解:

//TODO

在掌握了ET客戶端網絡功能之后基本就掌握了ET的客戶端框架。其他的一些框架特性是為了增加功能方便開發,當然如果實在掌握不了或者不喜歡用某個組件,可以用其他的方式實現,比如那個行為樹。當然,一定要舉一反三,通過學習研究網絡組件,對整個et框架有個更深的認識,能夠理解組件設計模式的精髓。組件包含數據和功能、實體包含組件,邏輯就是整個系統調用組件的過程。這也是最近鬧得沸沸揚揚的ECS。另外,此處只是客戶端的邏輯,服務端的邏輯TODO。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發此異常。 O...
    我想起個好名字閱讀 5,429評論 0 9
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,135評論 1 32
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,833評論 0 11
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,376評論 0 6
  • 會話(Session)跟蹤是Web程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Se...
    chinariver閱讀 5,665評論 1 49