消息系统技术文档

发布于:2025-08-05 ⋅ 阅读:(16) ⋅ 点赞:(0)

消息系统技术文档

概述

本文档详细说明了如何在现有的LHD通信系统中添加自己的消息类型,包括消息的发送、接收、解析和处理的完整流程。

系统架构

消息流程架构图

客户端B
服务端
通信框架
客户端A
消息解析
TCP接收
消息ID匹配 0x0006
ParsePackage
触发ReceiveDefaultMessage事件
反射获取属性
显示消息内容
TCP监听
MessageServerApp
消息路由
转发到目标客户端
消息序列化
MessageCommunicationClient
TCP发送
发送李宏利消息
MessageClientApp
创建Lihongli2Message
调用SendMessage

时序图

客户端A MessageServerApp 客户端B 发送李宏利消息(0x0006) 消息路由处理 转发消息到客户端B 消息解析(ParsePackage) 事件触发(ReceiveDefaultMessage) 显示消息内容 客户端A MessageServerApp 客户端B

一、项目结构与依赖关系

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消息 - 关键:分配唯一ID
    EnumMessagelihongli = 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
=====================

八、添加新消息类型的通用步骤

基于李宏利消息的实现经验,添加新消息类型的通用步骤:

  1. 定义消息类

    • 继承 MessageBase
    • 分配唯一的消息ID
    • 实现 BuildPackage()ParsePackage() 方法
  2. 注册消息ID

    • EnumDispatchMessageID 中添加新的枚举值
  3. 添加消息路由

    • CommunicationClientReceivePackage.cs 中添加处理分支
  4. 实现发送逻辑

    • 在客户端应用中添加发送功能
  5. 实现接收处理

    • 在事件处理器中添加消息处理逻辑
  6. 测试验证

    • 编译所有项目
    • 运行服务端和客户端进行测试

九、注意事项

  1. 消息ID唯一性: 确保每种消息类型都有唯一的消息ID
  2. 序列化格式: 保持 BuildPackage()ParsePackage() 方法的格式一致性
  3. 错误处理: 在消息解析和处理过程中添加适当的异常处理
  4. 项目依赖: 确保所有项目引用路径正确,能够正常编译
  5. 向后兼容: 新增消息类型不应影响现有消息处理逻辑

十、编译和部署指南

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

本文档记录了李消息系统的完整实现过程,可作为后续添加其他消息类型的参考模板。


网站公告

今日签到

点亮在社区的每一天
去签到