|
@@ -21,6 +21,7 @@ using TelpoDataService.Util.QueryObjects; |
|
|
using NearCardAttendance.Service.MessageQueue; |
|
|
using NearCardAttendance.Service.MessageQueue; |
|
|
using NearCardAttendance.Service.MessageQueue.Model; |
|
|
using NearCardAttendance.Service.MessageQueue.Model; |
|
|
using Newtonsoft.Json.Linq; |
|
|
using Newtonsoft.Json.Linq; |
|
|
|
|
|
using DotNetty.Common.Concurrency; |
|
|
|
|
|
|
|
|
namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
{ |
|
|
{ |
|
@@ -32,17 +33,20 @@ namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
//private readonly IDisposable _loggerScope = default!; |
|
|
//private readonly IDisposable _loggerScope = default!; |
|
|
private readonly ServiceConfig _configService; |
|
|
private readonly ServiceConfig _configService; |
|
|
private readonly GpsCardAccessorClient<GpsDeviceConfig> _deviceConfigApiClient; |
|
|
private readonly GpsCardAccessorClient<GpsDeviceConfig> _deviceConfigApiClient; |
|
|
|
|
|
private readonly ScheduleResendManager _managerScheduleResend; |
|
|
|
|
|
|
|
|
//private readonly TcpClientsManager _managerTcpClients; |
|
|
//private readonly TcpClientsManager _managerTcpClients; |
|
|
//private readonly ScheduleResendManager _managerScheduleResend; |
|
|
//private readonly ScheduleResendManager _managerScheduleResend; |
|
|
|
|
|
|
|
|
public RegisterHandler(ILogger<RegisterHandler> logger, GpsCardAccessorClient<GpsDeviceConfig> deviceConfigApiClient,HttpHelper httpHelper, IOptions<ServiceConfig> configService, MqProcessLogic serviceMqProcess) |
|
|
|
|
|
|
|
|
public RegisterHandler(ILogger<RegisterHandler> logger, GpsCardAccessorClient<GpsDeviceConfig> deviceConfigApiClient, |
|
|
|
|
|
ScheduleResendManager scheduleResendManager, HttpHelper httpHelper, IOptions<ServiceConfig> configService, MqProcessLogic serviceMqProcess) |
|
|
{ |
|
|
{ |
|
|
_logger = logger; |
|
|
_logger = logger; |
|
|
_httpHelper = httpHelper; |
|
|
_httpHelper = httpHelper; |
|
|
_configService = configService.Value; |
|
|
_configService = configService.Value; |
|
|
_deviceConfigApiClient= deviceConfigApiClient; |
|
|
_deviceConfigApiClient= deviceConfigApiClient; |
|
|
_serviceMqProcess = serviceMqProcess; |
|
|
_serviceMqProcess = serviceMqProcess; |
|
|
|
|
|
_managerScheduleResend = scheduleResendManager; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public override void ChannelActive(IChannelHandlerContext context) |
|
|
public override void ChannelActive(IChannelHandlerContext context) |
|
@@ -75,6 +79,45 @@ namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
{ |
|
|
{ |
|
|
using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = parser.SeqNo })) |
|
|
using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = parser.SeqNo })) |
|
|
{ |
|
|
{ |
|
|
|
|
|
#region 启动keepalived业务 |
|
|
|
|
|
// _managerScheduleResend.AddOrUpdate(context.Channel.Id.AsShortText(),(context.Channel.Id.AsShortText(),IScheduledTask)); |
|
|
|
|
|
// 超过3分钟无任何数据就断链 |
|
|
|
|
|
_ = _managerScheduleResend.AddOrUpdate(context.Channel.Id.AsShortText(), key => |
|
|
|
|
|
{ |
|
|
|
|
|
// 创建新的 IScheduledTask |
|
|
|
|
|
return context.Channel.EventLoop.Schedule(async () => |
|
|
|
|
|
{ |
|
|
|
|
|
// var channel = _managerTcpClients.FirstOrDefault(x => x.Key.Equals(imei)).Value; |
|
|
|
|
|
//await channel.CloseAsync(); |
|
|
|
|
|
await context.Channel.CloseAsync(); |
|
|
|
|
|
_logger.LogInformation($"3分钟超时无数据,主动断链"); |
|
|
|
|
|
// 执行任务逻辑 |
|
|
|
|
|
}, |
|
|
|
|
|
#if DEBUG |
|
|
|
|
|
TimeSpan.FromSeconds(99999) |
|
|
|
|
|
#else |
|
|
|
|
|
TimeSpan.FromSeconds(180) |
|
|
|
|
|
#endif |
|
|
|
|
|
); |
|
|
|
|
|
}, |
|
|
|
|
|
(oldKey, oldValue) => |
|
|
|
|
|
{ |
|
|
|
|
|
// 更新现有的 IScheduledTask |
|
|
|
|
|
oldValue.Cancel(); // 取消旧的任务 |
|
|
|
|
|
return context.Channel.EventLoop.Schedule(async () => |
|
|
|
|
|
{ |
|
|
|
|
|
await context.Channel.CloseAsync(); |
|
|
|
|
|
_logger.LogInformation($"3分钟超时无数据,主动断链"); |
|
|
|
|
|
// 执行任务逻辑 |
|
|
|
|
|
}, |
|
|
|
|
|
#if DEBUG |
|
|
|
|
|
TimeSpan.FromSeconds(99999) |
|
|
|
|
|
#else |
|
|
|
|
|
TimeSpan.FromSeconds(180) |
|
|
|
|
|
#endif |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
|
|
|
#endregion |
|
|
//认证 |
|
|
//认证 |
|
|
//if (parser.FuncNo.Equals("10")) |
|
|
//if (parser.FuncNo.Equals("10")) |
|
|
//{ |
|
|
//{ |
|
@@ -143,6 +186,7 @@ namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
await HandleAuthenticationSuccessAsync(parser, context.Channel); |
|
|
await HandleAuthenticationSuccessAsync(parser, context.Channel); |
|
|
break; |
|
|
break; |
|
|
case "05": |
|
|
case "05": |
|
|
|
|
|
//ChannelKeepAlived(context, parser); |
|
|
await SendHeartbeatAsync(parser, context.Channel); |
|
|
await SendHeartbeatAsync(parser, context.Channel); |
|
|
break; |
|
|
break; |
|
|
case "04": |
|
|
case "04": |
|
@@ -223,10 +267,63 @@ namespace NearCardAttendance.Service.TcpServer.Handler |
|
|
/// <returns></returns> |
|
|
/// <returns></returns> |
|
|
private async Task SendHeartbeatAsync(ProtocolParser parser, IChannel channel) |
|
|
private async Task SendHeartbeatAsync(ProtocolParser parser, IChannel channel) |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo, ""); |
|
|
ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo, ""); |
|
|
await SendToTcpClientAsync(stdtSignRecsWrapper, channel); |
|
|
await SendToTcpClientAsync(stdtSignRecsWrapper, channel); |
|
|
|
|
|
|
|
|
|
|
|
#region 启动keepalived业务 |
|
|
|
|
|
// // _managerScheduleResend.AddOrUpdate(context.Channel.Id.AsShortText(),(context.Channel.Id.AsShortText(),IScheduledTask)); |
|
|
|
|
|
// // 超过3分钟无任何数据就断链 |
|
|
|
|
|
// _ = _managerScheduleResend.AddOrUpdate(channel.Id.AsShortText(), key => |
|
|
|
|
|
// { |
|
|
|
|
|
// // 创建新的 IScheduledTask |
|
|
|
|
|
// return channel.EventLoop.Schedule(async () => |
|
|
|
|
|
// { |
|
|
|
|
|
// // var channel = _managerTcpClients.FirstOrDefault(x => x.Key.Equals(imei)).Value; |
|
|
|
|
|
// //await channel.CloseAsync(); |
|
|
|
|
|
// await channel.CloseAsync(); |
|
|
|
|
|
// // 执行任务逻辑 |
|
|
|
|
|
// }, |
|
|
|
|
|
//#if DEBUG |
|
|
|
|
|
// TimeSpan.FromSeconds(999999) |
|
|
|
|
|
//#else |
|
|
|
|
|
// TimeSpan.FromSeconds(180) |
|
|
|
|
|
//#endif |
|
|
|
|
|
// ); |
|
|
|
|
|
// }, |
|
|
|
|
|
// (oldKey, oldValue) => |
|
|
|
|
|
// { |
|
|
|
|
|
// // 更新现有的 IScheduledTask |
|
|
|
|
|
// oldValue.Cancel(); // 取消旧的任务 |
|
|
|
|
|
// return channel.EventLoop.Schedule(async () => |
|
|
|
|
|
// { |
|
|
|
|
|
// await channel.CloseAsync(); |
|
|
|
|
|
// // 执行任务逻辑 |
|
|
|
|
|
// }, |
|
|
|
|
|
//#if DEBUG |
|
|
|
|
|
// TimeSpan.FromSeconds(999999) |
|
|
|
|
|
//#else |
|
|
|
|
|
// TimeSpan.FromSeconds(180) |
|
|
|
|
|
//#endif |
|
|
|
|
|
|
|
|
|
|
|
// ); |
|
|
|
|
|
// }); |
|
|
|
|
|
#endregion |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void ChannelKeepAlived(IChannelHandlerContext context, ProtocolParser parser) |
|
|
|
|
|
{ |
|
|
|
|
|
if (_managerScheduleResend.TryRemove(context.Channel.Id.AsShortText(), out IScheduledTask? scheduledTask)) |
|
|
|
|
|
{ |
|
|
|
|
|
scheduledTask.Cancel(); |
|
|
|
|
|
scheduledTask = null; |
|
|
|
|
|
_logger.LogInformation($"{nameof(ChannelKeepAlived)} --{parser.SeqNo} -- {context.Channel} 活跃..."); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
Console.WriteLine("No Task"); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary> |
|
|
/// <summary> |
|
|
/// STDT_SIGN_RECS 学生签到记录[取值:04] |
|
|
/// STDT_SIGN_RECS 学生签到记录[取值:04] |
|
|
/// </summary> |
|
|
/// </summary> |
|
|