消息系统技术文档
概述
本文档详细说明了如何在现有的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
本文档记录了李消息系统的完整实现过程,可作为后续添加其他消息类型的参考模板。