使用 Socket 實現的分散式事件匯流排,支援 CQRS,不依賴第三方 MQ。
CodeWF.EventBus.Socket
是一個輕量級的、基於 Socket 的分散式事件匯流排系統,旨在簡化分散式架構中的事件通訊。它允許程序之間透過釋出/訂閱模式進行通訊,無需依賴外部訊息佇列服務。
Command
Query
特性
-
輕量級:不依賴任何外部 MQ 服務,減少了系統複雜性和依賴。
-
高效能:基於 Socket 的直接通訊,提供低延遲、高吞吐量的訊息傳遞。
-
靈活性:支援自定義事件型別和訊息處理器,易於整合到現有系統中。
-
可擴充套件性:支援多客戶端連線,適用於分散式系統環境。
通訊協議
透過 TCP
協議進行資料互動,協議包結構如下:
安裝
透過NuGet
包管理器安裝CodeWF.EventBus.Socket
:
Install-Package CodeWF.EventBus.Socket
服務端使用
執行事件服務
在服務端程式碼中,建立並啟動EventServer
例項以監聽客戶端連線和事件:
using CodeWF.EventBus.Socket;
// 建立事件伺服器例項
IEventServer eventServer = new EventServer();
// 啟動事件伺服器,監聽指定IP和埠
eventServer.Start("127.0.0.1", 9100);
停止事件服務
當不再需要事件服務時,呼叫Stop
方法以優雅地關閉伺服器:
eventServer.Stop();
客戶端使用
連線事件服務
在客戶端程式碼中,建立EventClient
例項並連線到事件伺服器:
using CodeWF.EventBus.Socket;
// 建立事件客戶端例項
IEventClient eventClient = new EventClient();
// 連線到事件伺服器,使用eventClient.ConnectStatus檢查連線狀態
eventClient.Connect("127.0.0.1", 9100));
訂閱事件
訂閱特定型別的事件,並指定事件處理函式:
eventClient.Subscribe<NewEmailCommand>("event.email.new", ReceiveNewEmailCommand);
private void ReceiveNewEmail(NewEmailCommand command)
{
// 處理新郵件通知
Console.WriteLine($"收到新郵件,主題是{message.Subject}");
}
釋出命令(Command)
釋出事件到指定的主題,供已訂閱的客戶端處理:
// 釋出新郵件通知事件
eventClient.Publish("event.email.new", new NewEmailCommand { Subject = "恭喜您中Github一等獎", Content = "我們很開心,您在2024年7月...", SendTime = new DateTime(2024, 7, 27) });
查詢(Query)
查詢指定主題,需要有接收查詢端訂閱相同的主題(即生產者),收到請求後,再以相同的主題釋出查詢結果:
eventClient.Subscribe<EmailQuery>("event.email.query", ReceiveEmailQuery);
private void ReceiveEmailQuery(EmailQuery query)
{
// 執行查詢請求,準備查詢結果
var response = new EmailQueryResponse { Emails = EmailManager.QueryEmail(request.Subject) };
// 以相同的主題,釋出查詢結果
if (_eventClient!.Publish("event.email.query", response,
out var errorMessage))
{
Logger.Info($"Response query result: {response}");
}
else
{
Logger.Error($"Response query failed: {errorMessage}");
}
}
其他端可使用相同的主題查詢(即消費者):
var response = _eventClient!.Query<EmailQuery, EmailQueryResponse>("event.email.query",
new EmailQuery() { Subject = "Account" },
out var errorMessage);
if (string.IsNullOrWhiteSpace(errorMessage) && response != null)
{
Logger.Info($"Query event.email.query, result: {response}");
}
else
{
Logger.Error(
$"Query event.email.query failed: [{errorMessage}]");
}
取消訂閱事件
不再需要接收某類事件時,可以取消訂閱:
eventClient.Unsubscribe<NewEmailNotification>("event.email.new", ReceiveNewEmail);
斷開事件服務
完成事件處理或需要斷開與伺服器的連線時,呼叫Disconnect
方法:
eventClient.Disconnect();
Console.WriteLine("斷開與事件服務的連線");
注意事項
- 確保服務端和客戶端使用的地址和埠號一致,並且埠未被其他服務佔用。
- 在生產環境中,服務端應配置為監聽公共 IP 地址或適當的網路介面。
- 考慮到網路異常和服務重啟等情況,客戶端可能需要實現重連邏輯。
- 根據實際需求,可以擴充套件
EventServer
和EventClient
類以支援更復雜的功能,如訊息加密、認證授權等。