You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
5.2 KiB

using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Interfaces.ProtocolLogHandlers;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Infrastructure.Contexts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers
{
/// <summary>
/// 协议日志提供者观察者
/// 负责接收、缓存和转发协议日志数据
/// 使用生产者-消费者模式处理日志数据流
/// </summary>
public class ProtocolLogsProviderObserver : IProtocolLogsProviderObserver
{
/// <summary>
/// 用于存储待处理的协议日志消息的阻塞队列
/// </summary>
private readonly static BlockingCollection<string> BlockingQueue = new BlockingCollection<string>();
/// <summary>
/// 日志记录器
/// </summary>
private readonly ILogger logger;
/// <summary>
/// 网络上下文,用于检查网络状态
/// </summary>
private readonly CellularNetworkContext networkContext;
/// <summary>
/// 初始化协议日志提供者观察者
/// </summary>
/// <param name="networkContext">网络上下文</param>
/// <param name="logger">日志记录器</param>
public ProtocolLogsProviderObserver(CellularNetworkContext networkContext, ILogger logger)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.networkContext = networkContext ?? throw new ArgumentNullException(nameof(networkContext));
logger.LogInformation("ProtocolLogsProviderObserver 初始化完成");
_ = Task.Run(Consumer);
logger.LogInformation("消费者任务已启动");
}
/// <summary>
/// 接收并处理新的协议日志数据
/// </summary>
/// <param name="msg">协议日志消息</param>
public void OnData(string msg)
{
if (string.IsNullOrEmpty(msg))
{
logger.LogWarning("收到空的协议日志消息");
return;
}
try
{
logger.LogDebug("收到新的协议日志消息: {Message}", msg);
Producer(msg);
}
catch (Exception ex)
{
logger.LogError(ex, "处理协议日志消息时发生错误: {Message}", msg);
}
}
/// <summary>
/// 生产者方法:将消息添加到阻塞队列中
/// </summary>
/// <param name="message">要添加的消息</param>
private void Producer(string message)
{
try
{
var networkState = networkContext.GetNetworkState();
if (networkState.CurrentStatus == NetworkStatus.Connected)
{
logger.LogDebug("网络已连接,将消息添加到队列: {Message}", message);
BlockingQueue.Add(message);
}
else
{
logger.LogWarning("网络未连接,丢弃消息: {Message}", message);
}
}
catch (Exception ex)
{
logger.LogError(ex, "添加消息到队列时发生错误: {Message}", message);
throw;
}
}
/// <summary>
/// 消费者方法:从队列中获取并处理消息
/// </summary>
public async Task Consumer()
{
logger.LogInformation("消费者任务开始运行");
try
{
while (networkContext.GetNetworkState().CurrentStatus == NetworkStatus.Connected)
{
try
{
if (BlockingQueue.TryTake(out var message, TimeSpan.FromMilliseconds(1000)))
{
logger.LogDebug("从队列中获取到消息: {Message}", message);
// TODO: 实现消息发送逻辑
// await client.SendAsync(message, true);
}
else
{
await Task.Delay(1000);
}
}
catch (Exception ex)
{
logger.LogError(ex, "处理队列消息时发生错误");
await Task.Delay(1000); // 发生错误时等待一段时间再继续
}
}
}
catch (OperationCanceledException)
{
logger.LogWarning("消费者任务被取消");
}
catch (Exception ex)
{
logger.LogError(ex, "消费者任务发生未处理的错误");
}
finally
{
logger.LogInformation("消费者任务已结束");
}
}
}
}