消息系統技術文檔
概述
本文檔詳細說明了如何在現有的LHD通信系統中添加自己的消息類型,包括消息的發送、接收、解析和處理的完整流程。
系統架構
消息流程架構圖
時序圖
一、項目結構與依賴關系
1.1 核心項目
- Lihongli2Message: 消息類型定義項目
- MessageCommunicationServer: 服務端通信組件
- MessageCommunicationClient: 客戶端通信組件
- MessageServerApp: 服務端應用程序
- MessageClientApp: 客戶端應用程序
1.2 依賴關系修復
在添加李宏利消息類型過程中,修復了以下依賴關系問題:
<!-- Demos/HomeWork/Lihongli2Message/Lihongli2Message.csproj -->
<ItemGroup><!-- 修復前:路徑錯誤 --><ProjectReference Include="..\..\Configuration\SystemConst\SystemConst.csproj" /><!-- 修復后:正確的相對路徑 --><ProjectReference Include="..\..\..\Configuration\SystemConst\SystemConst.csproj" /><ProjectReference Include="..\..\..\MessageCommunication\CommunicationTCPMessage\CommunicationTCPMessage.csproj" />
</ItemGroup>
二、消息類型實現
2.1 消息類定義
文件: Demos/HomeWork/Lihongli2Message/Lihongli2Message.cs
using System;
using System.Text;
using CommunicationMessage;namespace CommunicationMessage.MessageObject
{[Serializable]public class Lihongli2Message : MessageBase{public string SenderName { get; set; } = "";public string MessageContent { get; set; } = "";public DateTime SendTime { get; set; }public string MessageType { get; set; } = "李宏利消息";// 關鍵:使用消息ID 0x0006 和正常消息類型public Lihongli2Message() : base((byte)EnumDispatchMessageTypeID.EnumNornalMessage, 0x0006){this.SendTime = DateTime.Now;this.DataLength = 0;}// 消息序列化public override byte[] BuildPackage(){string messageString = $"{SenderName}|{MessageContent}|{SendTime:yyyy-MM-dd HH:mm:ss}|{MessageType}";byte[] data = Encoding.UTF8.GetBytes(messageString);this.DataLength = data.Length;return data;}// 消息反序列化public override void ParsePackage(byte[] data, int startIndex){try{if (data == null || data.Length < startIndex + DataLength){return;}byte[] messageData = new byte[DataLength];Array.Copy(data, startIndex, messageData, 0, DataLength);var message = FromBytes(messageData);if (message != null){this.SenderName = message.SenderName;this.MessageContent = message.MessageContent;this.SendTime = message.SendTime;this.MessageType = message.MessageType;}}catch (Exception ex){Console.WriteLine($"解析李宏利消息包失敗: {ex.Message}");}}}
}
2.2 消息ID注冊
文件: MessageCommunication/CommunicationTCPMessage/EnumDispatchMessageID.cs
public enum EnumDispatchMessageID : UInt32
{// 其他消息ID...//lihongli消息 - 關鍵:分配唯一IDEnumMessagelihongli = 0x0006,
}
三、消息發送實現
3.1 客戶端發送邏輯
文件: MessageCommunication/MessageClientApp/Program.cs
private static void SendLihongli2Message()
{Console.WriteLine("=== 發送李宏利消息 ===");// 收集用戶輸入Console.Write("請輸入發送者姓名: ");string senderName = Console.ReadLine() ?? "匿名";Console.Write("請輸入消息內容: ");string content = Console.ReadLine() ?? "";Console.Write("請輸入消息類型 (默認:李宏利消息): ");string messageType = Console.ReadLine()?.Trim() ?? "李宏利消息";// 創建并發送消息var message = new Lihongli2Message(senderName, content, messageType);ServerApp.SendMessage((uint)EnumTCPCommunicationChannel.ClientView, message);Console.WriteLine($"發送李宏利消息: {message.ToJsonString()}");
}
四、消息接收與路由
4.1 消息路由機制
文件: MessageCommunication/MessageCommunicationClient/CommunicationClientReceivePackage.cs
private void ReceivePackage(MessagePackage package)
{// 提取消息碼uint messageCode = package.MessageCode & 0x00FFFFFF;Console.WriteLine($"收到消息包: MessageCode=0x{package.MessageCode:X}, 處理后=0x{messageCode:X}");switch ((EnumDispatchMessageID)messageCode){case EnumDispatchMessageID.EnumMessagelihongli: // 李宏利消息路由Console.WriteLine("? 匹配到李宏利消息,開始處理...");if (ReceiveDefaultMessage != null){// 創建消息對象并設置屬性Lihongli2Message msg = new Lihongli2Message(){MessageSource = package.MessageSource,MessageTarget = package.MessageTarget,DataLength = package.DataLength,};// 解析消息數據msg.ParsePackage(package.MessageData, 0);Console.WriteLine("? 李宏利消息解析完成,觸發事件");// 觸發事件處理ReceiveDefaultMessage(msg);}break;// 其他消息類型處理...}
}
五、消息處理與顯示
5.1 事件處理器
文件: MessageCommunication/MessageClientApp/Program.cs
private static void ServerApp_ReceiveDefaultMessage(MessageBase message)
{try{Console.WriteLine($"事件處理器被調用,消息類型: {message.GetType().Name}");Console.WriteLine($"消息碼: 0x{message.GetMessageCode():X}");// 檢查是否是李消息if (message.GetMessageCode() == 0x0006) // Lihongli2Message的消息碼{Console.WriteLine("? 消息碼匹配,檢查消息類型...");// 使用反射安全地訪問屬性var senderNameProperty = message.GetType().GetProperty("SenderName");var messageContentProperty = message.GetType().GetProperty("MessageContent");var sendTimeProperty = message.GetType().GetProperty("SendTime");var messageTypeProperty = message.GetType().GetProperty("MessageType");if (senderNameProperty != null && messageContentProperty != null && sendTimeProperty != null && messageTypeProperty != null){Console.WriteLine("? 使用反射成功獲取消息屬性");// 顯示消息內容Console.WriteLine("\n=== 收到李宏利消息 ===");Console.WriteLine($"發送者: {senderNameProperty.GetValue(message)}");Console.WriteLine($"內容: {messageContentProperty.GetValue(message)}");Console.WriteLine($"時間: {sendTimeProperty.GetValue(message)}");Console.WriteLine($"類型: {messageTypeProperty.GetValue(message)}");Console.WriteLine("=====================");}}}catch (Exception ex){Console.WriteLine($"處理李消息時發生錯誤: {ex.Message}");}
}
六、關鍵修改文件清單
6.1 新增文件
Demos/HomeWork/Lihongli2Message/Lihongli2Message.cs
- 消息類定義Demos/HomeWork/Lihongli2Message/Lihongli2Message.csproj
- 項目配置
6.2 修改的文件
文件路徑 | 修改內容 | 說明 |
---|---|---|
MessageCommunication/CommunicationTCPMessage/EnumDispatchMessageID.cs | 添加 EnumMessagelihongli = 0x0006 | 注冊消息ID |
MessageCommunication/MessageCommunicationClient/CommunicationClientReceivePackage.cs | 添加李宏利消息處理分支 | 消息路由 |
MessageCommunication/MessageClientApp/Program.cs | 添加發送和接收處理邏輯 | 客戶端功能 |
MessageCommunication/MessageServerApp/Program.cs | 添加李宏利消息創建示例 | 服務端功能 |
6.3 項目引用修復
- 修復了
Lihongli2Message.csproj
中的相對路徑引用 - 確保所有依賴項目能夠正確編譯和鏈接
七、測試驗證
7.1 成功運行日志示例
Input debug command to show info...
收到消息包: MessageCode=0x6, 處理后=0x6
? 匹配到李宏利消息,開始處理...
ParsePackage: data長度=54, startIndex=0, DataLength=54
ParsePackage: 復制的數據長度=54
ParsePackage: 原始數據=李宏利|11111111111111111111|2025-08-04 22:57:37|123
ParsePackage: FromBytes成功,設置屬性
ParsePackage: 設置完成 - SenderName='李宏利', Content='11111111111111111111'
? 李宏利消息解析完成,觸發事件
事件處理器被調用,消息類型: Lihongli2Message
消息碼: 0x6
? 消息碼匹配,檢查消息類型...
? 使用反射成功獲取消息屬性=== 收到李宏利消息 ===
發送者: 李宏利
內容: 11111111111111111111
時間: 2025/8/4 22:57:37
類型: 123
=====================
八、添加新消息類型的通用步驟
基于李宏利消息的實現經驗,添加新消息類型的通用步驟:
-
定義消息類
- 繼承
MessageBase
- 分配唯一的消息ID
- 實現
BuildPackage()
和ParsePackage()
方法
- 繼承
-
注冊消息ID
- 在
EnumDispatchMessageID
中添加新的枚舉值
- 在
-
添加消息路由
- 在
CommunicationClientReceivePackage.cs
中添加處理分支
- 在
-
實現發送邏輯
- 在客戶端應用中添加發送功能
-
實現接收處理
- 在事件處理器中添加消息處理邏輯
-
測試驗證
- 編譯所有項目
- 運行服務端和客戶端進行測試
九、注意事項
- 消息ID唯一性: 確保每種消息類型都有唯一的消息ID
- 序列化格式: 保持
BuildPackage()
和ParsePackage()
方法的格式一致性 - 錯誤處理: 在消息解析和處理過程中添加適當的異常處理
- 項目依賴: 確保所有項目引用路徑正確,能夠正常編譯
- 向后兼容: 新增消息類型不應影響現有消息處理邏輯
十、編譯和部署指南
10.1 編譯順序
# 1. 編譯依賴項目
dotnet build Configuration/SystemConst/SystemConst.csproj
dotnet build MessageCommunication/CommunicationTCPMessage/CommunicationTCPMessage.csproj# 2. 編譯消息類項目
dotnet build Demos/HomeWork/Lihongli2Message/Lihongli2Message.csproj# 3. 編譯應用程序
dotnet build MessageCommunication/MessageServerApp/MessageServerApp.csproj
dotnet build MessageCommunication/MessageClientApp/MessageClientApp.csproj# 4. 編譯整個解決方案
dotnet build LHDDispatch.sln
10.2 運行說明
# 啟動服務端
dotnet run --project MessageCommunication/MessageServerApp/MessageServerApp.csproj# 啟動客戶端(在新的終端窗口中)
dotnet run --project MessageCommunication/MessageClientApp/MessageClientApp.csproj
文檔版本: 1.0
創建時間: 2025年8月4日
最后更新: 2025年8月4日
文檔位置: D:\APPfile\Cshape_learn\LHD\李宏利消息系統技術文檔.md
本文檔記錄了李消息系統的完整實現過程,可作為后續添加其他消息類型的參考模板。