概述
ET框架的訊息機制貫徹始終,包含Entity訊息(Awake,Update ...),自定義(Customer)訊息,網路訊息等,而ET系統的行程包含了客戶端、Gate等各種型別的服務器,行程包含各種服務器客戶端之間通過網路訊息進行通信進行作業,
ET框架訊息結構

-
結構圖為了更加明確整體關系,進行了一定程度的簡化,剔除掉了一些訊息解包等一些細節
-
NetCompontent網路組件有Client客戶端、Server服務器(Gate)、Inner內網服務等多型,行程業務使用網路組件進行通信,網路組件會對連接建立一個Secsiom會話物件,封裝連接資訊和相關操作
-
Service和Channel實作負責NetCompontent和Session的功能,有Tcp長連接、Web網頁、KCP無連接可靠協議的多型(若不熟悉KCP協議,可以參考之前寫的文章 跳轉鏈接: KCP協議淺析),
- Channel對應一個Session連接,封裝了對底層tcp等協議庫的操作,
- Service對應一個NetCompent組件,對應NetCompent管理多個Session,Server管理和調度一堆Channel的作業,
-
NetServices負責調度多個Service物件的在網路執行緒和主執行緒作業任務,ET開了網路執行緒處理網路相關,某些行程需要多個網路組件(比如Gate服務器同時需要Server、Inner網路組件,接收轉發客戶端訊息),
-
NetComponentOnReadEvent是不同型別網路組件的訊息處理器,
- NetClientComponentOnReadEvent對應客戶端Client,處理普通訊息和RPC呼叫,
- NetInnerComponentOnReadEvent對應服務器內網型別Inner,處理Actor訊息
- NetServerComponentOnReadEvent對應服務外網,處理Actor訊息、RPC呼叫、普通訊息
訊息通信
以典型的TCP協議型別為例,其他實作類似,看圖相信都能理解,不多贅述,有一些要注意的點:
- 如上述,ET開了一個執行緒處理網路相關,一些作業使用了“生產-消費”Task任務這種方式,
- 使用了異步Socket
TCP發訊息

TCP收訊息

多行程呼叫
ET框架在基礎網路訊息通信基礎使用了Actor模型、PRC等相關技術思想(某些思想和實作有調整)進行了拓展,提供多個行程的互相呼叫機制,
先對相關技術做一個簡介:
- Actor模型
在計算機科學中,Actor模型(Actor model)是一種并發運算上的模型,“Actor”是一種程式上的抽象概念,被視為并發運算的基本單元:當一個Actor接收到一則訊息,它可以做出一些決策、創建更多的Actor、發送更多的訊息、決定要如何回答接下來的訊息,Actor可以修改它們自己的私有狀態,但是只能通過訊息間接的相互影響(避免了基于鎖的同步)
這是維基百科中對于Actor模型的描述,簡單理解它就是提供了一種訊息機制避免了基于鎖的同步,一些經典的應用場景是多執行緒,在ET框架中它的應用場景是多行程,類似的它提供了一種機制:直接通過ID發訊息,不用關心實體在哪個行程,
- RPC
分布式計算中,遠程程序呼叫(英語:Remote Procedure Call,RPC)是一個計算機通信協議,該協議允許運行于一臺計算機的程式呼叫另一個地址空間(通常為一個開放網路的一臺計算機)的子程式,而程式員就像呼叫本地程式一樣,無需額外地為這個互動作用編程(無需關注細節),RPC是一種服務器-客戶端(Client/Server)模式,經典實作是一個通過發送請求-接受回應進行資訊互動的系統
RPC機制通過一些手段抹平了不同行程的差異,使得行程間的呼叫可以和本地異步呼叫一樣處理,
了解了這兩種技術,下面來看ET框架對其的應用和如何實作多行程呼叫的,
訊息協議型別

如上圖所示訊息型別分為三種:
- Message 訊息,無需應答
- Request 請求,對應一個Response應答
- Response 應答,對應一個請求
注意Request和Response一定成對定義,且其Message一定包含一個RpcId欄位
訊息型別可以被前綴修飾,修飾有三種:
- None 客戶端與服務器(Gate)之間不需要轉發的訊息,(注意這里不是修飾字符不是"None",而是""表示沒有)
- Actor 服務器內網之間的訊息
- ActorLocation 客戶端與服務器需要轉發的訊息,
修飾字符可以修飾任意訊息型別,組合起來一共有9種訊息,
如這個登錄到Gate的協議:
//ResponseType G2C_LoginGate
message C2G_LoginGate // IRequest
{
int32 RpcId = 1;
int64 Key = 2; // 帳號
int64 GateId = 3;
}
message G2C_LoginGate // IResponse
{
int32 RpcId = 1;
int32 Error = 2;
string Message = 3;
int64 PlayerId = 4;
}
- C2G_LoginGate 在訊息名后面注明了訊息型別,并在訊息名上面注明了應答包的訊息型別,并且包含一個RpcId的欄位,這些都必須的,表示這是個不需要轉發的、需要應答的請求訊息,而訊息名前綴只是方便理解,起到注釋的作用:表示這是Client行程發送給Gate服務器行程的訊息,
- G2C_LoginGate 同上,是上述C2G_LoginGate請求的應答訊息,
Rpc呼叫程序

如圖所示,進行Rpc呼叫時,生成一個新的RpcID并帶入請求包中,同時把呼叫資訊存起來,對方應答時,會把請求包的RpcID傳入到應答包中,在收到訊息時如果是Resp型別訊息會呼叫OnResp方法,通過應答包的RpcID取出RpcInfo,通過RpcInfo取消呼叫RpcCall函式的異步阻塞,
public static void OnResponse(this Session self, IResponse response)
{
if (!self.requestCallbacks.TryGetValue(response.RpcId, out var action))
{
return;
}
self.requestCallbacks.Remove(response.RpcId);
if (ErrorCore.IsRpcNeedThrowException(response.Error))
{
action.Tcs.SetException(new Exception($"Rpc error, request: {action.Request} response: {response}"));
return;
}
action.Tcs.SetResult(response);
}
action.Tcs.SetResult會取消異步的阻塞,執行await后面的陳述句,詳情見之前寫的文章 跳轉鏈接: C#異步編程
Actor模型實作
在ET框架的設計中,Actor其實是一個帶有MailboxComponent的組件,其具體的實作方式,ET有比較詳細的檔案說明,有實作思路和使用方式的介紹,這里貼出來,不做贅述,
跳轉鏈接: ET Actor模型 官方介紹
參考鏈接
- 跳轉鏈接: Actor模型介紹
- 跳轉鏈接: RPC介紹
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/552510.html
標籤:其他
上一篇:一種通用的業務監控觸發方案設計
下一篇:返回列表
