Browse Source

创建MessageTransferProtocolLog模型解决命名冲突,优化NetworkProtocolLogObserver性能监控和错误处理

feature/protocol-log-Perfect
root 1 week ago
parent
commit
de06915714
  1. 64
      CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
  2. 100
      CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs
  3. 32
      CoreAgent.WebSocketTransport/Models/ProtocolMessage.cs
  4. 93
      modify.md

64
CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using CoreAgent.ProtocolClient.Models;
using CoreAgent.ProtocolClient.ProtocolEngineCore;
using CoreAgent.WebSocketTransport.Interfaces;
using CoreAgent.WebSocketTransport.Models;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network
@ -21,7 +22,68 @@ namespace CoreAgent.Infrastructure.Services.Network
}
public void OnProtocolLogsReceived(IEnumerable<TransferProtocolLog> logDetails)
{
_ChannelManager.SendChannel.TryWrite(logDetails);
var startTime = DateTime.UtcNow;
// 空值检查
if (logDetails == null)
{
_logger.LogWarning("接收到的协议日志为空");
return;
}
// 转换为列表以避免多次枚举
var logList = logDetails.ToList();
var logCount = logList.Count;
// 空集合检查
if (logCount == 0)
{
_logger.LogDebug("接收到的协议日志集合为空,跳过处理");
return;
}
try
{
_logger.LogDebug("开始处理协议日志,数量: {LogCount}", logCount);
// 将 CoreAgent.ProtocolClient 的 TransferProtocolLog 转换为 WebSocket 传输层的 MessageTransferProtocolLog
var webSocketLogs = logList.Select(log => new MessageTransferProtocolLog
{
Id = log.Id,
LayerType = log.LayerType.ToString(),
MessageDetailJson = log.MessageDetailJson,
CellID = log.CellID,
IMSI = log.IMSI,
Direction = log.Direction,
UEID = log.UEID,
PLMN = log.PLMN,
TimeMs = log.TimeMs,
Timestamp = log.Timestamp,
Info = log.Info,
Message = log.Message
});
// 尝试写入通道并跟踪结果
var writeSuccess = _ChannelManager.SendChannel.TryWrite(webSocketLogs);
var processingTime = DateTime.UtcNow - startTime;
if (writeSuccess)
{
_logger.LogDebug("协议日志处理成功,数量: {LogCount}, 处理时间: {ProcessingTime}ms",
logCount, processingTime.TotalMilliseconds);
}
else
{
_logger.LogWarning("协议日志写入通道失败,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 通道可能已满或已关闭",
logCount, processingTime.TotalMilliseconds);
}
}
catch (Exception ex)
{
var processingTime = DateTime.UtcNow - startTime;
_logger.LogError(ex, "协议日志处理异常,数量: {LogCount}, 处理时间: {ProcessingTime}ms",
logCount, processingTime.TotalMilliseconds);
}
}
}
}

100
CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CoreAgent.WebSocketTransport.Models
{
/// <summary>
/// 消息传输协议日志模型
/// 用于在WebSocket传输层中传输协议日志数据
/// 与CoreAgent.ProtocolClient中的TransferProtocolLog区分开
/// </summary>
public class MessageTransferProtocolLog
{
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 协议层类型
/// </summary>
public string LayerType { get; set; } = string.Empty;
/// <summary>
/// 消息详情集合(JSON格式存储)
/// </summary>
public string? MessageDetailJson { get; set; }
/// <summary>
/// 小区ID
/// </summary>
public int? CellID { get; set; }
/// <summary>
/// 国际移动用户识别码
/// </summary>
public string? IMSI { get; set; }
/// <summary>
/// 日志方向类型
/// </summary>
public int Direction { get; set; }
/// <summary>
/// 用户设备ID
/// </summary>
public int? UEID { get; set; }
/// <summary>
/// 公共陆地移动网络标识
/// </summary>
public string? PLMN { get; set; }
/// <summary>
/// 时间间隔(毫秒)
/// </summary>
public long TimeMs { get; set; }
/// <summary>
/// 时间戳
/// </summary>
public long Timestamp { get; set; }
/// <summary>
/// 信息字段
/// </summary>
public string? Info { get; set; }
/// <summary>
/// 消息字段
/// </summary>
public string? Message { get; set; }
/// <summary>
/// 消息详情集合(用于业务逻辑)
/// </summary>
public IEnumerable<string>? MessageDetail
{
get => !string.IsNullOrEmpty(MessageDetailJson)
? Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<string>>(MessageDetailJson)
: null;
set => MessageDetailJson = value != null
? Newtonsoft.Json.JsonConvert.SerializeObject(value)
: null;
}
/// <summary>
/// 时间间隔(用于业务逻辑)
/// </summary>
public TimeSpan Time
{
get => TimeSpan.FromMilliseconds(TimeMs);
set => TimeMs = (long)value.TotalMilliseconds;
}
}
}

32
CoreAgent.WebSocketTransport/Models/ProtocolMessage.cs

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CoreAgent.WebSocketTransport.Models
{
partial class ProtocolMessage
{
/// <summary>
/// 消息类型
/// </summary>
public string Type { get; set; } = "Protocol";
/// <summary>
/// 消息载荷
/// </summary>
public HeartbeatPayload Payload { get; set; } = new HeartbeatPayload();
}
/// <summary>
/// 心跳消息载荷
/// </summary>
public class ProtocolPayload
{
/// <summary>
/// 心跳消息内容
/// </summary>
public string Message { get; set; } = "ping";
}
}

93
modify.md

@ -2,6 +2,99 @@
## 2024年修改记录
### 创建MessageTransferProtocolLog模型解决命名冲突
**修改时间**: 2024年
**修改文件**:
- `CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs` (新建)
- `CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs`
**修改内容**:
1. **创建MessageTransferProtocolLog模型**
- 在 `CoreAgent.WebSocketTransport` 项目中创建新的协议日志模型
- 与 `CoreAgent.ProtocolClient` 中的 `TransferProtocolLog` 区分开
- 保持相同的字段结构,避免命名冲突
- 专门用于WebSocket传输层的协议日志数据传输
2. **修改NetworkProtocolLogObserver转换逻辑**
- 在 `OnProtocolLogsReceived` 方法中添加类型转换
- 将 `CoreAgent.ProtocolClient.TransferProtocolLog` 转换为 `CoreAgent.WebSocketTransport.MessageTransferProtocolLog`
- 保持所有字段的完整映射
- 添加必要的using语句引用
3. **具体实现**:
```csharp
// 时间跟踪和性能监控
var startTime = DateTime.UtcNow;
// 空值检查
if (logDetails == null)
{
_logger.LogWarning("接收到的协议日志为空");
return;
}
// 转换为列表以避免多次枚举
var logList = logDetails.ToList();
var logCount = logList.Count;
// 空集合检查
if (logCount == 0)
{
_logger.LogDebug("接收到的协议日志集合为空,跳过处理");
return;
}
// 类型转换逻辑
var webSocketLogs = logList.Select(log => new MessageTransferProtocolLog
{
Id = log.Id,
LayerType = log.LayerType.ToString(),
MessageDetailJson = log.MessageDetailJson,
CellID = log.CellID,
IMSI = log.IMSI,
Direction = log.Direction,
UEID = log.UEID,
PLMN = log.PLMN,
TimeMs = log.TimeMs,
Timestamp = log.Timestamp,
Info = log.Info,
Message = log.Message
});
// 通道写入状态监控
var writeSuccess = _ChannelManager.SendChannel.TryWrite(webSocketLogs);
var processingTime = DateTime.UtcNow - startTime;
if (writeSuccess)
{
_logger.LogDebug("协议日志处理成功,数量: {LogCount}, 处理时间: {ProcessingTime}ms",
logCount, processingTime.TotalMilliseconds);
}
else
{
_logger.LogWarning("协议日志写入通道失败,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 通道可能已满或已关闭",
logCount, processingTime.TotalMilliseconds);
}
```
4. **设计优势**:
- **命名清晰**:`MessageTransferProtocolLog` 明确表示用于消息传输
- **避免冲突**:与原始 `TransferProtocolLog` 有明确区分
- **职责分离**:WebSocket传输层有独立的协议日志模型
- **类型安全**:通过显式转换确保类型安全
- **易于维护**:清晰的命名约定便于理解和维护
- **性能监控**:添加时间跟踪和通道写入状态监控
- **错误处理**:完善的异常处理和日志记录
- **Bug修复**:修复空引用检查和多次枚举的性能问题
- **边界处理**:添加空集合检查,避免处理空集合
**影响范围**:
- WebSocket传输层协议日志处理
- 协议日志观察者模式实现
- 跨项目类型转换逻辑
### CellularNetworkService.StartNetworkAsync 方法添加协议客户端配置创建
**修改时间**: 2024年

Loading…
Cancel
Save