diff --git a/CoreAgent.Domain/Models/Protocol/DirectionLogsType.cs b/CoreAgent.Domain/Models/Protocol/DirectionLogsType.cs new file mode 100644 index 0000000..490e9e8 --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/DirectionLogsType.cs @@ -0,0 +1,34 @@ +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// 日志方向类型枚举 +/// 定义了协议日志的传输方向 +/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分 +/// +public enum DirectionLogsType +{ + /// + /// 未知方向 + /// + Unknown = 0, + + /// + /// 上行方向(UE到网络) + /// + Uplink = 1, + + /// + /// 下行方向(网络到UE) + /// + Downlink = 2, + + /// + /// 双向 + /// + Bidirectional = 3, + + /// + /// 内部处理 + /// + Internal = 4 +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Protocol/MobileUserIdentity.cs b/CoreAgent.Domain/Models/Protocol/MobileUserIdentity.cs new file mode 100644 index 0000000..7bd940d --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/MobileUserIdentity.cs @@ -0,0 +1,200 @@ +using Newtonsoft.Json; + +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// 移动用户身份信息 +/// 用于存储移动网络用户的基本身份和位置信息 +/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分 +/// +public class MobileUserIdentity +{ + /// + /// 公共陆地移动网络标识 + /// Public Land Mobile Network Identifier + /// + [JsonProperty("plmn")] + public string? Plmn { get; set; } + + /// + /// 旧的临时移动用户标识 + /// Old Temporary Mobile Subscriber Identity + /// + [JsonProperty("oldTmsi")] + public string? OldTmsi { get; set; } + + /// + /// 临时移动用户标识 + /// Temporary Mobile Subscriber Identity + /// + [JsonProperty("tmsi")] + public string? Tmsi { get; set; } + + /// + /// 国际移动用户标识 + /// International Mobile Subscriber Identity + /// + [JsonProperty("imsi")] + public string? Imsi { get; set; } + + /// + /// 小区ID + /// Cell Identifier + /// + [JsonProperty("cellId")] + public int? CellId { get; set; } + + /// + /// 用户设备ID + /// User Equipment Identifier + /// + [JsonProperty("ueId")] + public int? UeId { get; set; } + + /// + /// 初始化移动用户身份信息的新实例 + /// + public MobileUserIdentity() + { + } + + /// + /// 初始化移动用户身份信息的新实例 + /// + /// 公共陆地移动网络标识 + /// 旧的临时移动用户标识 + /// 临时移动用户标识 + /// 国际移动用户标识 + /// 小区ID + /// 用户设备ID + public MobileUserIdentity( + string? plmn = null, + string? oldTmsi = null, + string? tmsi = null, + string? imsi = null, + int? cellId = null, + int? ueId = null) + { + Plmn = plmn; + OldTmsi = oldTmsi; + Tmsi = tmsi; + Imsi = imsi; + CellId = cellId; + UeId = ueId; + } + + /// + /// 检查是否包含有效的用户身份信息 + /// + /// 是否包含有效信息 + public bool HasValidIdentity() + { + return !string.IsNullOrWhiteSpace(Imsi) || + !string.IsNullOrWhiteSpace(Tmsi) || + UeId.HasValue; + } + + /// + /// 检查是否包含位置信息 + /// + /// 是否包含位置信息 + public bool HasLocationInfo() + { + return !string.IsNullOrWhiteSpace(Plmn) || CellId.HasValue; + } + + /// + /// 获取用户身份摘要信息 + /// + /// 摘要信息 + public string GetIdentitySummary() + { + var parts = new List(); + + if (!string.IsNullOrWhiteSpace(Imsi)) + parts.Add($"IMSI:{Imsi}"); + + if (!string.IsNullOrWhiteSpace(Tmsi)) + parts.Add($"TMSI:{Tmsi}"); + + if (UeId.HasValue) + parts.Add($"UE:{UeId}"); + + if (!string.IsNullOrWhiteSpace(Plmn)) + parts.Add($"PLMN:{Plmn}"); + + if (CellId.HasValue) + parts.Add($"Cell:{CellId}"); + + return parts.Count > 0 ? string.Join(" | ", parts) : "No Identity Info"; + } + + /// + /// 检查TMSI是否发生变化 + /// + /// TMSI是否发生变化 + public bool HasTmsiChanged() + { + return !string.IsNullOrWhiteSpace(OldTmsi) && + !string.IsNullOrWhiteSpace(Tmsi) && + !OldTmsi.Equals(Tmsi, StringComparison.OrdinalIgnoreCase); + } + + /// + /// 创建身份信息的副本 + /// + /// 新的移动用户身份信息 + public MobileUserIdentity Copy() + { + return new MobileUserIdentity + { + Plmn = Plmn, + OldTmsi = OldTmsi, + Tmsi = Tmsi, + Imsi = Imsi, + CellId = CellId, + UeId = UeId + }; + } + + /// + /// 更新TMSI信息 + /// + /// 新的TMSI + public void UpdateTmsi(string? newTmsi) + { + if (!string.IsNullOrWhiteSpace(Tmsi)) + { + OldTmsi = Tmsi; + } + Tmsi = newTmsi; + } + + /// + /// 转换为JSON字符串 + /// + /// JSON字符串 + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// 从JSON字符串创建移动用户身份信息 + /// + /// JSON字符串 + /// 移动用户身份信息 + public static MobileUserIdentity FromJson(string json) + { + return JsonConvert.DeserializeObject(json) ?? new MobileUserIdentity(); + } + + /// + /// 重写ToString方法 + /// + /// 字符串表示 + public override string ToString() + { + return GetIdentitySummary(); + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Protocol/ProtocolLayerType.cs b/CoreAgent.Domain/Models/Protocol/ProtocolLayerType.cs new file mode 100644 index 0000000..8a38597 --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/ProtocolLayerType.cs @@ -0,0 +1,242 @@ +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// 协议层类型枚举 +/// 定义了系统中支持的各种协议层类型 +/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分 +/// +public enum ProtocolLayerType +{ + /// + /// 无协议层类型 + /// + NONE = 0, + + /// + /// GTP-U协议层 + /// GPRS Tunnelling Protocol User Plane + /// + GTPU = 1, + + /// + /// LPPa协议层 + /// LTE Positioning Protocol Annex + /// + LPPa = 2, + + /// + /// M2AP协议层 + /// M2 Application Protocol + /// + M2AP = 3, + + /// + /// MAC协议层 + /// Medium Access Control + /// + MAC = 4, + + /// + /// NAS协议层 + /// Non-Access Stratum + /// + NAS = 5, + + /// + /// NGAP协议层 + /// Next Generation Application Protocol + /// + NGAP = 6, + + /// + /// NRPPa协议层 + /// NR Positioning Protocol Annex + /// + NRPPa = 7, + + /// + /// PDCP协议层 + /// Packet Data Convergence Protocol + /// + PDCP = 8, + + /// + /// PROD协议层 + /// Production Protocol + /// + PROD = 9, + + /// + /// PHY协议层 + /// Physical Layer + /// + PHY = 10, + + /// + /// RLC协议层 + /// Radio Link Control + /// + RLC = 11, + + /// + /// RRC协议层 + /// Radio Resource Control + /// + RRC = 12, + + /// + /// S1AP协议层 + /// S1 Application Protocol + /// + S1AP = 13, + + /// + /// TRX协议层 + /// Transceiver Protocol + /// + TRX = 14, + + /// + /// X2AP协议层 + /// X2 Application Protocol + /// + X2AP = 15, + + /// + /// XnAP协议层 + /// Xn Application Protocol + /// + XnAP = 16, + + /// + /// IP协议层 + /// Internet Protocol + /// + IP = 17, + + /// + /// IMS协议层 + /// IP Multimedia Subsystem + /// + IMS = 18, + + /// + /// CX协议层 + /// Diameter CX Interface + /// + CX = 19, + + /// + /// RX协议层 + /// Diameter RX Interface + /// + RX = 20, + + /// + /// S6协议层 + /// Diameter S6 Interface + /// + S6 = 21, + + /// + /// S13协议层 + /// Diameter S13 Interface + /// + S13 = 22, + + /// + /// SGsAP协议层 + /// SGs Application Protocol + /// + SGsAP = 23, + + /// + /// SBcAP协议层 + /// SBc Application Protocol + /// + SBcAP = 24, + + /// + /// LCSAP协议层 + /// LCS Application Protocol + /// + LCSAP = 25, + + /// + /// N12协议层 + /// Diameter N12 Interface + /// + N12 = 26, + + /// + /// N8协议层 + /// Diameter N8 Interface + /// + N8 = 27, + + /// + /// N17协议层 + /// Diameter N17 Interface + /// + N17 = 28, + + /// + /// N50协议层 + /// Diameter N50 Interface + /// + N50 = 29, + + /// + /// N13协议层 + /// Diameter N13 Interface + /// + N13 = 30, + + /// + /// NL1协议层 + /// Network Layer 1 + /// + NL1 = 31, + + /// + /// HTTP2协议层 + /// Hypertext Transfer Protocol 2 + /// + HTTP2 = 32, + + /// + /// EPDG协议层 + /// Evolved Packet Data Gateway + /// + EPDG = 33, + + /// + /// IKEV2协议层 + /// Internet Key Exchange Version 2 + /// + IKEV2 = 34, + + /// + /// IPSEC协议层 + /// Internet Protocol Security + /// + IPSEC = 35, + + /// + /// MEDIA协议层 + /// Media Protocol + /// + MEDIA = 36, + + /// + /// MMS协议层 + /// Multimedia Messaging Service + /// + MMS = 37, + + /// + /// SIP协议层 + /// Session Initiation Protocol + /// + SIP = 38 +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Protocol/ProtocolLayerTypeExtensions.cs b/CoreAgent.Domain/Models/Protocol/ProtocolLayerTypeExtensions.cs new file mode 100644 index 0000000..fa6f1c3 --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/ProtocolLayerTypeExtensions.cs @@ -0,0 +1,258 @@ +using System.ComponentModel; +using System.Reflection; + +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// ProtocolLayerType 枚举扩展方法 +/// 提供协议层类型的实用功能 +/// +public static class ProtocolLayerTypeExtensions +{ + /// + /// 获取协议层类型的描述信息 + /// + /// 协议层类型 + /// 描述信息 + public static string GetDescription(this ProtocolLayerType protocolLayerType) + { + var field = protocolLayerType.GetType().GetField(protocolLayerType.ToString()); + var attribute = field?.GetCustomAttribute(); + return attribute?.Description ?? protocolLayerType.ToString(); + } + + /// + /// 获取协议层类型的显示名称 + /// + /// 协议层类型 + /// 显示名称 + public static string GetDisplayName(this ProtocolLayerType protocolLayerType) + { + return protocolLayerType switch + { + ProtocolLayerType.NONE => "无", + ProtocolLayerType.GTPU => "GTP-U", + ProtocolLayerType.LPPa => "LPPa", + ProtocolLayerType.M2AP => "M2AP", + ProtocolLayerType.MAC => "MAC", + ProtocolLayerType.NAS => "NAS", + ProtocolLayerType.NGAP => "NGAP", + ProtocolLayerType.NRPPa => "NRPPa", + ProtocolLayerType.PDCP => "PDCP", + ProtocolLayerType.PROD => "PROD", + ProtocolLayerType.PHY => "PHY", + ProtocolLayerType.RLC => "RLC", + ProtocolLayerType.RRC => "RRC", + ProtocolLayerType.S1AP => "S1AP", + ProtocolLayerType.TRX => "TRX", + ProtocolLayerType.X2AP => "X2AP", + ProtocolLayerType.XnAP => "XnAP", + ProtocolLayerType.IP => "IP", + ProtocolLayerType.IMS => "IMS", + ProtocolLayerType.CX => "CX", + ProtocolLayerType.RX => "RX", + ProtocolLayerType.S6 => "S6", + ProtocolLayerType.S13 => "S13", + ProtocolLayerType.SGsAP => "SGsAP", + ProtocolLayerType.SBcAP => "SBcAP", + ProtocolLayerType.LCSAP => "LCSAP", + ProtocolLayerType.N12 => "N12", + ProtocolLayerType.N8 => "N8", + ProtocolLayerType.N17 => "N17", + ProtocolLayerType.N50 => "N50", + ProtocolLayerType.N13 => "N13", + ProtocolLayerType.NL1 => "NL1", + ProtocolLayerType.HTTP2 => "HTTP/2", + ProtocolLayerType.EPDG => "EPDG", + ProtocolLayerType.IKEV2 => "IKEv2", + ProtocolLayerType.IPSEC => "IPSec", + ProtocolLayerType.MEDIA => "MEDIA", + ProtocolLayerType.MMS => "MMS", + ProtocolLayerType.SIP => "SIP", + _ => protocolLayerType.ToString() + }; + } + + /// + /// 判断是否为RAN相关协议层 + /// + /// 协议层类型 + /// 是否为RAN协议层 + public static bool IsRanProtocol(this ProtocolLayerType protocolLayerType) + { + return protocolLayerType switch + { + ProtocolLayerType.GTPU or + ProtocolLayerType.LPPa or + ProtocolLayerType.M2AP or + ProtocolLayerType.MAC or + ProtocolLayerType.NAS or + ProtocolLayerType.NGAP or + ProtocolLayerType.NRPPa or + ProtocolLayerType.PDCP or + ProtocolLayerType.PHY or + ProtocolLayerType.RLC or + ProtocolLayerType.RRC or + ProtocolLayerType.S1AP or + ProtocolLayerType.TRX or + ProtocolLayerType.X2AP or + ProtocolLayerType.XnAP => true, + _ => false + }; + } + + /// + /// 判断是否为IMS相关协议层 + /// + /// 协议层类型 + /// 是否为IMS协议层 + public static bool IsImsProtocol(this ProtocolLayerType protocolLayerType) + { + return protocolLayerType switch + { + ProtocolLayerType.IMS or + ProtocolLayerType.CX or + ProtocolLayerType.RX or + ProtocolLayerType.S6 or + ProtocolLayerType.S13 or + ProtocolLayerType.SGsAP or + ProtocolLayerType.SBcAP or + ProtocolLayerType.LCSAP or + ProtocolLayerType.N12 or + ProtocolLayerType.N8 or + ProtocolLayerType.N17 or + ProtocolLayerType.N50 or + ProtocolLayerType.N13 or + ProtocolLayerType.HTTP2 or + ProtocolLayerType.EPDG or + ProtocolLayerType.IKEV2 or + ProtocolLayerType.IPSEC or + ProtocolLayerType.MEDIA or + ProtocolLayerType.MMS or + ProtocolLayerType.SIP => true, + _ => false + }; + } + + /// + /// 判断是否为Diameter协议层 + /// + /// 协议层类型 + /// 是否为Diameter协议层 + public static bool IsDiameterProtocol(this ProtocolLayerType protocolLayerType) + { + return protocolLayerType switch + { + ProtocolLayerType.CX or + ProtocolLayerType.RX or + ProtocolLayerType.S6 or + ProtocolLayerType.S13 or + ProtocolLayerType.N12 or + ProtocolLayerType.N8 or + ProtocolLayerType.N17 or + ProtocolLayerType.N50 or + ProtocolLayerType.N13 => true, + _ => false + }; + } + + /// + /// 获取协议层类型的分类 + /// + /// 协议层类型 + /// 协议层分类 + public static string GetCategory(this ProtocolLayerType protocolLayerType) + { + return protocolLayerType switch + { + ProtocolLayerType.NONE => "None", + ProtocolLayerType.GTPU or + ProtocolLayerType.LPPa or + ProtocolLayerType.M2AP or + ProtocolLayerType.MAC or + ProtocolLayerType.NAS or + ProtocolLayerType.NGAP or + ProtocolLayerType.NRPPa or + ProtocolLayerType.PDCP or + ProtocolLayerType.PHY or + ProtocolLayerType.RLC or + ProtocolLayerType.RRC or + ProtocolLayerType.S1AP or + ProtocolLayerType.TRX or + ProtocolLayerType.X2AP or + ProtocolLayerType.XnAP => "RAN", + ProtocolLayerType.IMS or + ProtocolLayerType.CX or + ProtocolLayerType.RX or + ProtocolLayerType.S6 or + ProtocolLayerType.S13 or + ProtocolLayerType.SGsAP or + ProtocolLayerType.SBcAP or + ProtocolLayerType.LCSAP or + ProtocolLayerType.N12 or + ProtocolLayerType.N8 or + ProtocolLayerType.N17 or + ProtocolLayerType.N50 or + ProtocolLayerType.N13 or + ProtocolLayerType.HTTP2 or + ProtocolLayerType.EPDG or + ProtocolLayerType.IKEV2 or + ProtocolLayerType.IPSEC or + ProtocolLayerType.MEDIA or + ProtocolLayerType.MMS or + ProtocolLayerType.SIP => "IMS", + ProtocolLayerType.IP => "Network", + ProtocolLayerType.NL1 => "Network", + ProtocolLayerType.PROD => "Production", + _ => "Other" + }; + } + + /// + /// 从字符串转换为ProtocolLayerType枚举 + /// + /// 字符串值 + /// ProtocolLayerType枚举值,如果转换失败返回NONE + public static ProtocolLayerType FromString(string value) + { + if (string.IsNullOrWhiteSpace(value)) + return ProtocolLayerType.NONE; + + return Enum.TryParse(value, true, out var result) + ? result + : ProtocolLayerType.NONE; + } + + /// + /// 获取所有RAN协议层类型 + /// + /// RAN协议层类型数组 + public static ProtocolLayerType[] GetRanProtocols() + { + return Enum.GetValues() + .Where(p => p.IsRanProtocol()) + .ToArray(); + } + + /// + /// 获取所有IMS协议层类型 + /// + /// IMS协议层类型数组 + public static ProtocolLayerType[] GetImsProtocols() + { + return Enum.GetValues() + .Where(p => p.IsImsProtocol()) + .ToArray(); + } + + /// + /// 获取所有Diameter协议层类型 + /// + /// Diameter协议层类型数组 + public static ProtocolLayerType[] GetDiameterProtocols() + { + return Enum.GetValues() + .Where(p => p.IsDiameterProtocol()) + .ToArray(); + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Protocol/ProtocolLogParsedResult.cs b/CoreAgent.Domain/Models/Protocol/ProtocolLogParsedResult.cs new file mode 100644 index 0000000..6089aae --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/ProtocolLogParsedResult.cs @@ -0,0 +1,338 @@ +using Newtonsoft.Json; + +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// 协议日志解析结果 +/// 用于存储ProtocolLog解析后的分析结果,用于数据传输和处理 +/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分 +/// +public class ProtocolLogParsedResult +{ + /// + /// 唯一标识符 + /// + [JsonProperty("id")] + public string Id { get; set; } = Guid.NewGuid().ToString(); + + /// + /// 日志索引 + /// + [JsonProperty("index")] + public int? Index { get; set; } + + /// + /// 消息ID + /// + [JsonProperty("messageId")] + public int? MessageId { get; set; } + + /// + /// 协议层类型 + /// + [JsonProperty("protocolLayer")] + public ProtocolLayerType ProtocolLayer { get; set; } + + /// + /// 协议类型描述 + /// + [JsonProperty("protocolType")] + public string ProtocolType { get; set; } = string.Empty; + + /// + /// 用户设备ID + /// + [JsonProperty("ueId")] + public int? UeId { get; set; } + + /// + /// 公共陆地移动网络标识 + /// + [JsonProperty("plmn")] + public string? Plmn { get; set; } + + /// + /// 临时移动用户标识 + /// + [JsonProperty("tmsi")] + public string? Tmsi { get; set; } + + /// + /// 国际移动设备标识 + /// + [JsonProperty("imei")] + public string? Imei { get; set; } + + /// + /// 国际移动用户标识 + /// + [JsonProperty("imsi")] + public string? Imsi { get; set; } + + /// + /// 小区ID + /// + [JsonProperty("cellId")] + public int? CellId { get; set; } + + /// + /// 小区信息 + /// + [JsonProperty("cell")] + public string? Cell { get; set; } + + /// + /// 日志信息 + /// + [JsonProperty("info")] + public string? Info { get; set; } + + /// + /// 消息内容 + /// + [JsonProperty("message")] + public string? Message { get; set; } + + /// + /// 消息数据数组 + /// + [JsonProperty("messageData")] + public string[]? MessageData { get; set; } + + /// + /// 时间间隔 + /// + [JsonProperty("time")] + public TimeSpan Time { get; set; } + + /// + /// 时间戳 + /// + [JsonProperty("timestamp")] + public long Timestamp { get; set; } + + /// + /// 日志方向 + /// + [JsonProperty("direction")] + public DirectionLogsType Direction { get; set; } + + /// + /// 协议层分类 + /// + [JsonProperty("category")] + public string Category => ProtocolLayer.GetCategory(); + + /// + /// 协议层显示名称 + /// + [JsonProperty("displayName")] + public string DisplayName => ProtocolLayer.GetDisplayName(); + + /// + /// 初始化协议日志解析结果的新实例 + /// + public ProtocolLogParsedResult() + { + } + + /// + /// 初始化协议日志解析结果的新实例 + /// + /// 消息ID + /// 日志索引 + /// 协议层类型 + /// 用户设备ID + /// 公共陆地移动网络标识 + /// 临时移动用户标识 + /// 国际移动设备标识 + /// 国际移动用户标识 + /// 小区ID + /// 小区信息 + /// 日志信息 + /// 消息内容 + /// 消息数据数组 + /// 日志方向 + public ProtocolLogParsedResult( + int? messageId = null, + int? index = null, + ProtocolLayerType protocolLayer = ProtocolLayerType.NONE, + int? ueId = null, + string? plmn = null, + string? tmsi = null, + string? imei = null, + string? imsi = null, + int? cellId = null, + string? cell = null, + string? info = null, + string? message = null, + string[]? messageData = null, + DirectionLogsType direction = DirectionLogsType.Unknown) + { + MessageId = messageId; + Index = index; + ProtocolLayer = protocolLayer; + UeId = ueId; + Plmn = plmn; + Tmsi = tmsi; + Imei = imei; + Imsi = imsi; + CellId = cellId; + Cell = cell; + Info = info; + Message = message; + MessageData = messageData; + Direction = direction; + ProtocolType = protocolLayer.GetDisplayName(); + } + + /// + /// 从ProtocolLog创建ProtocolLogParsedResult + /// + /// 协议日志 + /// 日志索引 + /// 协议日志解析结果 + public static ProtocolLogParsedResult FromProtocolLog(ProtocolLog protocolLog, int? index = null) + { + // 处理时间戳转换 + long timestamp; + if (protocolLog.Time.HasValue) + { + // 如果 Time 是秒为单位,转换为毫秒 + timestamp = (long)(protocolLog.Time.Value * 1000); + } + else if (protocolLog.Utc.HasValue) + { + // 如果 Utc 是秒为单位,转换为毫秒 + timestamp = (long)(protocolLog.Utc.Value * 1000); + } + else + { + // 默认使用当前时间 + timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + } + + return new ProtocolLogParsedResult + { + MessageId = protocolLog.MessageId, + Index = index, + ProtocolLayer = ProtocolLayerType.NONE, // 需要根据实际内容解析 + Message = protocolLog.Message, + MessageData = protocolLog.Headers, + Timestamp = timestamp, + Time = TimeSpan.FromMilliseconds(protocolLog.Time ?? 0), + Direction = DirectionLogsType.Unknown, + ProtocolType = protocolLog.Type ?? string.Empty + }; + } + + /// + /// 从ProtocolLogDetail创建ProtocolLogParsedResult + /// + /// 协议日志明细 + /// 日志索引 + /// 协议日志解析结果 + public static ProtocolLogParsedResult FromProtocolLogDetail(ProtocolLogDetail detail, int? index = null) + { + return new ProtocolLogParsedResult + { + Index = index ?? detail.Idx, + ProtocolLayer = ProtocolLayerTypeExtensions.FromString(detail.Layer), + UeId = detail.UeId, + CellId = detail.Cell, + Info = detail.Src, + MessageData = detail.Data?.ToArray(), + Timestamp = detail.Timestamp, + Time = TimeSpan.FromMilliseconds(detail.Timestamp), + Direction = ParseDirection(detail.Dir), + ProtocolType = detail.Layer + }; + } + + /// + /// 解析方向字符串为DirectionLogsType + /// + /// 方向字符串 + /// 方向类型 + private static DirectionLogsType ParseDirection(string? direction) + { + if (string.IsNullOrWhiteSpace(direction)) + return DirectionLogsType.Unknown; + + return direction.ToLower() switch + { + "up" or "uplink" or "ul" => DirectionLogsType.Uplink, + "down" or "downlink" or "dl" => DirectionLogsType.Downlink, + "bidirectional" or "bi" => DirectionLogsType.Bidirectional, + "internal" or "int" => DirectionLogsType.Internal, + _ => DirectionLogsType.Unknown + }; + } + + /// + /// 检查解析结果是否包含有效数据 + /// + /// 是否包含有效数据 + public bool HasValidData() + { + return !string.IsNullOrEmpty(Id) && + (ProtocolLayer != ProtocolLayerType.NONE || !string.IsNullOrEmpty(ProtocolType)); + } + + /// + /// 获取解析结果摘要信息 + /// + /// 摘要信息 + public string GetSummary() + { + return $"ProtocolLogParsed[{Id}] - {ProtocolLayer.GetDisplayName()} - {Direction} - UE:{UeId} - Cell:{CellId}"; + } + + /// + /// 创建解析结果的副本 + /// + /// 新的协议日志解析结果 + public ProtocolLogParsedResult Copy() + { + return new ProtocolLogParsedResult + { + Id = Guid.NewGuid().ToString(), // 生成新的ID + Index = Index, + MessageId = MessageId, + ProtocolLayer = ProtocolLayer, + ProtocolType = ProtocolType, + UeId = UeId, + Plmn = Plmn, + Tmsi = Tmsi, + Imei = Imei, + Imsi = Imsi, + CellId = CellId, + Cell = Cell, + Info = Info, + Message = Message, + MessageData = MessageData?.Clone() as string[], + Time = Time, + Timestamp = Timestamp, + Direction = Direction + }; + } + + /// + /// 转换为JSON字符串 + /// + /// JSON字符串 + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// 从JSON字符串创建解析结果 + /// + /// JSON字符串 + /// 协议日志解析结果 + public static ProtocolLogParsedResult FromJson(string json) + { + return JsonConvert.DeserializeObject(json) ?? new ProtocolLogParsedResult(); + } +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Protocol/UserNetworkIdentity.cs b/CoreAgent.Domain/Models/Protocol/UserNetworkIdentity.cs new file mode 100644 index 0000000..2cc08d3 --- /dev/null +++ b/CoreAgent.Domain/Models/Protocol/UserNetworkIdentity.cs @@ -0,0 +1,219 @@ +using Newtonsoft.Json; + +namespace CoreAgent.Domain.Models.Protocol; + +/// +/// 用户网络身份信息 +/// 用于存储移动网络用户的基本身份和位置信息 +/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分 +/// +public class UserNetworkIdentity +{ + /// + /// 公共陆地移动网络标识 + /// + [JsonProperty("plmn")] + public string? Plmn { get; set; } + + /// + /// 旧的临时移动用户标识 + /// + [JsonProperty("oldTmsi")] + public string? OldTmsi { get; set; } + + /// + /// 临时移动用户标识 + /// + [JsonProperty("tmsi")] + public string? Tmsi { get; set; } + + /// + /// 国际移动用户标识 + /// + [JsonProperty("imsi")] + public string? Imsi { get; set; } + + /// + /// 小区ID + /// + [JsonProperty("cellId")] + public int? CellId { get; set; } + + /// + /// 用户设备ID + /// + [JsonProperty("ueId")] + public int? UeId { get; set; } + + /// + /// 初始化用户网络身份信息的新实例 + /// + public UserNetworkIdentity() + { + } + + /// + /// 初始化用户网络身份信息的新实例 + /// + /// 公共陆地移动网络标识 + /// 旧的临时移动用户标识 + /// 临时移动用户标识 + /// 国际移动用户标识 + /// 小区ID + /// 用户设备ID + public UserNetworkIdentity( + string? plmn = null, + string? oldTmsi = null, + string? tmsi = null, + string? imsi = null, + int? cellId = null, + int? ueId = null) + { + Plmn = plmn; + OldTmsi = oldTmsi; + Tmsi = tmsi; + Imsi = imsi; + CellId = cellId; + UeId = ueId; + } + + /// + /// 检查是否包含有效的用户身份信息 + /// + /// 是否包含有效信息 + public bool HasValidIdentity() + { + return !string.IsNullOrWhiteSpace(Imsi) || + !string.IsNullOrWhiteSpace(Tmsi) || + UeId.HasValue; + } + + /// + /// 检查是否包含位置信息 + /// + /// 是否包含位置信息 + public bool HasLocationInfo() + { + return !string.IsNullOrWhiteSpace(Plmn) || CellId.HasValue; + } + + /// + /// 获取用户身份摘要信息 + /// + /// 摘要信息 + public string GetIdentitySummary() + { + var parts = new List(); + + if (!string.IsNullOrWhiteSpace(Imsi)) + parts.Add($"IMSI:{Imsi}"); + + if (!string.IsNullOrWhiteSpace(Tmsi)) + parts.Add($"TMSI:{Tmsi}"); + + if (UeId.HasValue) + parts.Add($"UE:{UeId}"); + + if (!string.IsNullOrWhiteSpace(Plmn)) + parts.Add($"PLMN:{Plmn}"); + + if (CellId.HasValue) + parts.Add($"Cell:{CellId}"); + + return parts.Count > 0 ? string.Join(" | ", parts) : "No Identity Info"; + } + + /// + /// 检查TMSI是否发生变化 + /// + /// TMSI是否发生变化 + public bool HasTmsiChanged() + { + return !string.IsNullOrWhiteSpace(OldTmsi) && + !string.IsNullOrWhiteSpace(Tmsi) && + !OldTmsi.Equals(Tmsi, StringComparison.OrdinalIgnoreCase); + } + + /// + /// 获取TMSI变化信息 + /// + /// TMSI变化信息 + public string GetTmsiChangeInfo() + { + if (HasTmsiChanged()) + { + return $"TMSI Changed: {OldTmsi} -> {Tmsi}"; + } + return "TMSI Unchanged"; + } + + /// + /// 创建用户网络身份信息的副本 + /// + /// 新的用户网络身份信息 + public UserNetworkIdentity Copy() + { + return new UserNetworkIdentity + { + Plmn = Plmn, + OldTmsi = OldTmsi, + Tmsi = Tmsi, + Imsi = Imsi, + CellId = CellId, + UeId = UeId + }; + } + + /// + /// 更新TMSI信息 + /// + /// 新的TMSI + public void UpdateTmsi(string? newTmsi) + { + if (!string.IsNullOrWhiteSpace(Tmsi)) + { + OldTmsi = Tmsi; + } + Tmsi = newTmsi; + } + + /// + /// 转换为JSON字符串 + /// + /// JSON字符串 + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// 从JSON字符串创建用户网络身份信息 + /// + /// JSON字符串 + /// 用户网络身份信息 + public static UserNetworkIdentity FromJson(string json) + { + return JsonConvert.DeserializeObject(json) ?? new UserNetworkIdentity(); + } + + /// + /// 合并另一个用户网络身份信息 + /// + /// 另一个用户网络身份信息 + /// 合并后的用户网络身份信息 + public UserNetworkIdentity Merge(UserNetworkIdentity other) + { + if (other == null) + return this; + + return new UserNetworkIdentity + { + Plmn = Plmn ?? other.Plmn, + OldTmsi = OldTmsi ?? other.OldTmsi, + Tmsi = Tmsi ?? other.Tmsi, + Imsi = Imsi ?? other.Imsi, + CellId = CellId ?? other.CellId, + UeId = UeId ?? other.UeId + }; + } +} \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/IMSLogMessageHandler.cs b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/IMSLogMessageHandler.cs index cca4daa..040f257 100644 --- a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/IMSLogMessageHandler.cs +++ b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/IMSLogMessageHandler.cs @@ -156,7 +156,6 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers private async Task HandleConfigSetMessageAsync(IObserverCustomWebSocketClient observer) { - _messageId++; string configResponse = LayerLogslevelSetting(true); _logger.LogInformation("发送config_set响应: {Response}", configResponse); await Task.Run(() => observer.SendMessage(configResponse)); @@ -167,18 +166,16 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers { if (JArray.FromObject(data["logs"]).Count > 0) { - _messageId++; string logResponse = LayerLogslevelSetting(false); _logger.LogInformation("发送log_get响应: {Response}", logResponse); await Task.Run(() => observer.SendMessage(logResponse)); - _currentMessageId = _messageId.ToString(); + //_currentMessageId = _messageId.ToString(); await Task.Run(() => _messageCallback.Invoke(data.ToString())); } } private async Task HandleStatsMessageAsync(IObserverCustomWebSocketClient observer) { - _messageId++; string statsResponse = CreateStatsMessage(); _logger.LogInformation("发送stats响应: {Response}", statsResponse); await Task.Run(() => observer.SendMessage(statsResponse)); @@ -186,25 +183,21 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers private string CreateMessage(string message) { - _messageId++; - return JObject.FromObject(new { message, message_id = _messageId }).ToString(); + return JObject.FromObject(new { message, message_id = Interlocked.Increment(ref _messageId) }).ToString(); } private JObject CreateRegisterMessage(string register) { - _messageId++; - return JObject.FromObject(new { message = "register", message_id = _messageId, register }); + return JObject.FromObject(new { message = "register", message_id = Interlocked.Increment(ref _messageId), register }); } private string CreateStatsMessage() { - _messageId++; return CreateMessage("stats"); } private JObject SettingBaseLayerLogslevel(JObject keyValues, bool isCloseSystemInfo = false) { - _messageId++; keyValues.Remove("rotate"); keyValues.Remove("path"); keyValues.Remove("count"); @@ -214,13 +207,12 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers { message = "config_set", logs = keyValues, - message_id = _messageId + message_id = Interlocked.Increment(ref _messageId) }); } private string LayerLogslevelSetting(bool isHead = false) { - _messageId++; BaseNetworkLog logtype = new BaseNetworkLog { Timeout = isHead ? 0 : 1, @@ -229,7 +221,7 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers LayerConfig = _context.NetworkLogs.ImsLog, Message = "log_get", IncludeHeaders = isHead, - MessageId = _messageId + MessageId = Interlocked.Increment(ref _messageId) }; return JObject.FromObject(logtype).ToString(); } diff --git a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs new file mode 100644 index 0000000..76e64d9 --- /dev/null +++ b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs @@ -0,0 +1,83 @@ +using CoreAgent.Domain.Helpers; +using CoreAgent.Domain.Interfaces.ProtocolLogHandlers; +using CoreAgent.Domain.Models.Protocol; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers +{ + + + + public class ProtocolLogsParesRanHandle : ProtocolParesHandleLogs + { + private readonly ILogger logger; + private readonly IProtocolLogsProviderObserver observer; + public ProtocolLogsParesRanHandle(IProtocolLogsProviderObserver observer, ILogger logger) + { + this.observer = observer; + this.logger = logger; + } + + public override async Task GetTryParesLogDataHandle(ProtocolLog model) + { + try + { + if (model is { Logs: null }) + { + logger.LogError($"logs is null =====>GetTryParesLogDataHandle Data {model?.ObjToJson()}"); + return; + } + var ParseJsonData = model.Logs.ToString().JsonToObj(); + var parseResultData = LogParsedResultHandle(ParseJsonData, (model.MessageId ?? 0)); + //if (parseResultData.Any()) + //{ + // var MsgData = new { data = parseResultData, MessageType = CSCIMessageType.ProtocolLogsRAN }.ObjToJson(); + // logger.LogInformation($"OnData:{MsgData}"); + // observer.OnData(MsgData); + //} + } + catch (Exception ex) + { + logger.LogError($"GetTryParesLogDataHandle Data {model?.ObjToJson()}"); + logger.LogError(ex.ToString()); + } + } + + public ProtocolLogParsedResult[] LogParsedResultHandle(ProtocolLogDetail[] logDetails, int MessageId) + { + List parsedResults = new List(); + + return parsedResults.ToArray(); + } + + public void LogListParse(ProtocolLogDetail[] list) + { + int length = list.Length; + for (int i = 0; i < length; i++) + { + var log= list[i]; + switch (log.Layer) + { + case "PHY": + break; + case "MAC": + break; + case "RRC": + break; + case "NAS": + break; + + default: + break; + + } + } + } + } +} diff --git a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs.cs b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs.cs deleted file mode 100644 index df4dc78..0000000 --- a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/ProtocolRanParesHandleLogs.cs.cs +++ /dev/null @@ -1,284 +0,0 @@ -using CoreAgent.Domain.Helpers; -using CoreAgent.Domain.Interfaces.ProtocolLogHandlers; -using CoreAgent.Domain.Models.Protocol; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers -{ - - - - public class ProtocolLogsParesRanHandle : ProtocolParesHandleLogs - { - private readonly ILogger logger; - private readonly IProtocolLogsProviderObserver observer; - public ProtocolLogsParesRanHandle(IProtocolLogsProviderObserver observer, ILogger logger) - { - this.observer = observer; - this.logger = logger; - } - - public override async Task GetTryParesLogDataHandle(ProtocolLog model) - { - try - { - if (model is { Logs: null }) - { - logger.LogError($"logs is null =====>GetTryParesLogDataHandle Data {model?.ObjToJson()}"); - return; - } - var ParseJsonData = model.Logs.ToString().JsonToObj(); - //var parseResultData = RanLogParseHandle(ParseJsonData, (model.MessageId ?? 0)); - //if (parseResultData.Any()) - //{ - // var MsgData = new { data = parseResultData, MessageType = CSCIMessageType.ProtocolLogsRAN }.ObjToJson(); - // logger.LogInformation($"OnData:{MsgData}"); - // observer.OnData(MsgData); - //} - } - catch (Exception ex) - { - logger.LogError($"GetTryParesLogDataHandle Data {model?.ObjToJson()}"); - logger.LogError(ex.ToString()); - } - } - - - //#region 分析 - //private List RanLogParseHandle(ProtocolLogDetail[] data, int MessageID) - //{ - // List cellulars = new List(); - // try - // { - // foreach (var msg in data) - // { - // ProtocolLogslayerType LayerType; - // Enum.TryParse(msg.layer, out LayerType); - // string info = string.Empty; - // string TMIS = string.Empty; - // string MessageInfo = msg.data[0]; - // if (LayerType == ProtocolLogslayerType.RRC) - // { - // var reg = _regExpRRC_UE_ID.Match(MessageInfo); - // if (reg is { Success: true }) - // { - // int ue_id = Convert.ToInt32(reg.Groups[1].ToString(), 16); - - // } - // reg = _regExpInfo1.Match(MessageInfo); - // if (reg.Success) - // { - // info = reg.Groups[1].Value; - // MessageInfo = reg.Groups[2].Value; - // GetlogListRRC(msg, MessageInfo); - - // } - // reg = _regExpRRC_BC.Match(MessageInfo); - // if (reg is { Success: true }) - // { - // string result = string.Join("\n", msg.data); - - // } - // } - // else if (LayerType == ProtocolLogslayerType.NAS) - // { - // var reg = _regExpInfo1.Match(MessageInfo); - // if (reg is { Success: true }) - // { - // info = reg.Groups[1].Value; - // MessageInfo = reg.Groups[2].Value; - // TMIS = GetlogListNAS(msg, MessageInfo); - // if (info.Equals("BCCH_NR")) - // { - - // } - - // } - // } - // else if (LayerType == ProtocolLogslayerType.PHY) - // { - // var reg = _regExpPhy.Match(MessageInfo); - // if (reg is { Success: true }) - // { - // int cell = Convert.ToInt32(reg.Groups[1].Value, 16); - // int rnti = Convert.ToInt32(reg.Groups[2].Value, 16); - // var channel = reg.Groups[4].Value; - // string[] frames = reg.Groups[3].Value.Split('.'); - // int frame = Convert.ToInt32(frames[0]) - 0; - // int slot = Convert.ToInt32(frames[1]) - 0; - // } - - // } - // else if (LayerType == ProtocolLogslayerType.MAC) - // { - // var reg = _regExpCellID.Match(MessageInfo); - // if (reg is { Success: true }) - // { - // int cell = Convert.ToInt32(reg.Groups[1].Value, 16); - // MessageInfo = reg.Groups[2].Value; - // } - // } - // CellularNetworkProtocolLogsEntity entity = new CellularNetworkProtocolLogsEntity - // { - // MessageID = MessageID, - // CellID = msg.cell, - // Timestamp = msg.timestamp, - // UEID = msg.ue_id, - // Time = msg.timestamp.UnixTimeStamp13ToBeijingTime().TimeOfDay, - // ProtocolLayer = LayerType, - // Info = info, - // TMSI = TMIS, - // Message = MessageInfo, - // ProtocolType = msg.src, - // Index = msg.idx, - // Direction = msg.dir switch - // { - // "UL" => DirectionLogsType.UL, - // "DL" => DirectionLogsType.DL, - // _ => DirectionLogsType._ - // }, - // MessageData = msg.data.ToArray(), - // }; - // cellulars.Add(entity); - // } - // return cellulars; - // } - // catch (Exception ex) - // { - // logger.Error("ran logs analysis combination" + ex.Message); - // return cellulars; - // } - //} - - //private void GetlogListRRC(ProtocolNetWorkCoreLogsDetailEntity log, string logType) - //{ - // try - // { - // switch (logType.ToLower()) - // { - // case "sib1": - // break; - // case "sib": - // break; - // case "rrc connection request": - // var lte = GetFindData(log.data, _regExpRRC_TMSI); - // if (lte is { Success: true }) - // { - // int tmsi = GetTMSI(log, lte.Groups[2].Value.ToString()); - // } - // break; - // case "rrc connection reconfiguration": - // var connection = GetFindData(log.data, _regExpRRC_TMSI); - // if (connection is { Success: true }) - // { - // int rnti = GetRNTI(log, connection.Groups[1].Value); - // } - // break; - // case "rrc connection reestablishment request": - // var request = GetFindData(log.data, _regExpRRC_TMSI); - // if (request is { Success: true }) - // { - // int rnti = GetRNTI(log, request.Groups[1].Value); - // } - // break; - // case "rrc setup request": - // var RRCrequest = GetFindData(log.data, _regExpRRC_TMSI); - // break; - // case "ue capability information": - - // break; - // default: - // break; - // } - // } - // catch (Exception ex) - // { - // logger.Error("GetlogListRRC" + ex.Message); - // } - //} - - //private string GetlogListNAS(ProtocolNetWorkCoreLogsDetailEntity log, string logType) - //{ - // switch (logType.ToLower()) - // { - // case "attach accept": - // var lte = GetFindData(log.data, _regExpNAS_TMSI); - // if (lte is not null && !string.IsNullOrWhiteSpace(lte.Groups[1]?.ToString())) - // { - - // int tmsi = GetTMSI(log, lte.Groups[1].Value); - // return lte.Groups[1].Value; - - // } - // break; - // case "attach request": - // var data = log.data; - // break; - // case "registration accept": - // var Nr = GetFindData(log.data, _regExpNAS_5GTMSI); - // if (Nr is not null && !string.IsNullOrWhiteSpace(Nr?.Groups[1]?.ToString())) - // { - // int tmsi = GetTMSI(log, Nr.Groups[1].Value); - // return Nr.Groups[1].Value; - // } - // break; - // case "registration request": - // var requestData = log.data; - // break; - - // } - // return string.Empty; - - //} - - //private Match GetFindData(List data, Regex regExp) - //{ - // if (data.Any()) - // { - // for (var i = 0; i < data.Count; i++) - // { - // Match m = regExp.Match(data[i]); - // if (m.Success) - // return m; - // } - // } - // return default; - //} - - //private int GetTMSI(ProtocolNetWorkCoreLogsDetailEntity log, string tmsi) - //{ - // return Convert.ToInt32(tmsi, 16); - //} - - //private int GetRNTI(ProtocolNetWorkCoreLogsDetailEntity log, string rnti) - //{ - // // 定义正则表达式模式 - // string pattern = @"'([\dA-F]+)'H"; - - // // 创建正则表达式对象 - // Regex regex = new Regex(pattern); - - // // 进行匹配 - // Match match = regex.Match(rnti); - - // // 检查是否有匹配 - // if (match.Success) - // return Convert.ToInt32(match.Groups[1].Value, 16); - // else return 0; - //} - - //private bool GetCheckLayerTypeInfo(string layer) - //{ - // string[] ArraryLayer = new string[] { "PDSCH", "PDCCH", "EPDCCH", "PUSCH", "PUCCH", "NPDSCH", "NPUSCH", "NPBCH", "BCCH-NR", "HINTS", "SRS", "CSI", "SIM-Even", "IP-SIM" }; - // return ArraryLayer.Any(s => s.Equals(layer)); - //} - //#endregion - } - -} diff --git a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/RanLogMessageHandler.cs b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/RanLogMessageHandler.cs index 76720eb..20ac73a 100644 --- a/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/RanLogMessageHandler.cs +++ b/CoreAgent.Infrastructure/Services/ProtocolLogHandlers/RanLogMessageHandler.cs @@ -159,8 +159,7 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers /// WebSocket客户端观察者 private async Task HandleReadyMessageAsync(IObserverCustomWebSocketClient observer) { - _messageId++; - string readyResponse = JObject.FromObject(new { message = "config_get", message_id = _messageId }).ToString(); + string readyResponse = JObject.FromObject(new { message = "config_get", message_id = Interlocked.Increment(ref _messageId) }).ToString(); _logger.LogInformation("发送ready响应: {Response}", readyResponse); await Task.Run(() => observer.SendMessage(readyResponse)); _currentMessageId = _messageId.ToString(); @@ -179,11 +178,9 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers _logger.LogInformation("处理config_get请求"); var responseArray = new JArray(); - _messageId++; - var statsConfig = new { message = "stats", message_id = _messageId, rf = false, samples = false }; + var statsConfig = new { message = "stats", message_id = Interlocked.Increment(ref _messageId), rf = false, samples = false }; responseArray.Add(JObject.FromObject(statsConfig)); - _messageId++; string baseLayerConfig = ConfigureBaseLayerLogs(data); responseArray.Add(JObject.Parse(baseLayerConfig)); @@ -204,7 +201,6 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers /// WebSocket客户端观察者 private async Task HandleConfigSetMessageAsync(IObserverCustomWebSocketClient observer) { - _messageId++; string configResponse = ConfigureLayerLogs(true); await Task.Run(() => observer.SendMessage(configResponse)); _currentMessageId = _messageId.ToString(); @@ -221,7 +217,6 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers { if (_currentMessageId == data["message_id"]!.ToString()) { - _messageId++; string logResponse = ConfigureLayerLogs(false); await Task.Run(() => observer.SendMessage(logResponse)); _currentMessageId = _messageId.ToString(); @@ -242,11 +237,10 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers /// WebSocket客户端观察者 private async Task HandleStatsMessageAsync(IObserverCustomWebSocketClient observer) { - _messageId++; string statsResponse = JObject.FromObject(new { message = "stats", - message_id = _messageId, + message_id = Interlocked.Increment(ref _messageId), rf = false, samples = false }).ToString(); @@ -287,7 +281,7 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers { message = "config_set", logs = keyValues, - message_id = _messageId, + message_id = Interlocked.Increment(ref _messageId), }; string response = JObject.FromObject(configMessage).ToString(); @@ -313,7 +307,7 @@ namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers LayerConfig = _networkContext.NetworkLogs.RanLog, Message = "log_get", IncludeHeaders = includeHeaders, - MessageId = _messageId, + MessageId = Interlocked.Increment(ref _messageId), }; string response = JObject.FromObject(logConfig).ToString();