Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

277 Zeilen
12KB

  1. using DotNetty.Buffers;
  2. using DotNetty.Transport.Channels;
  3. using Microsoft.Extensions.Logging;
  4. using NearCardAttendance.Common.helper;
  5. using NearCardAttendance.Service.TcpServer.Mapper;
  6. using NearCardAttendance.Service.TcpServer.Protocol;
  7. using Newtonsoft.Json;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Channels;
  13. using System.Threading.Tasks;
  14. using NearCardAttendance.Model;
  15. using Microsoft.Extensions.Options;
  16. namespace NearCardAttendance.Service.TcpServer.Handler
  17. {
  18. public class RegisterHandler : ChannelHandlerAdapter
  19. {
  20. private readonly ILogger<RegisterHandler> _logger;
  21. private readonly HttpHelper _httpHelper = default!;
  22. private readonly IDisposable _loggerScope = default!;
  23. private readonly ServiceConfig _configService;
  24. //private readonly TcpClientsManager _managerTcpClients;
  25. //private readonly ScheduleResendManager _managerScheduleResend;
  26. public RegisterHandler(ILogger<RegisterHandler> logger,HttpHelper httpHelper, IOptions<ServiceConfig> configService)
  27. {
  28. _logger = logger;
  29. _httpHelper = httpHelper;
  30. _configService = configService.Value;
  31. }
  32. public override void ChannelActive(IChannelHandlerContext context)
  33. {
  34. base.ChannelActive(context); // Pass the event to the next handler
  35. }
  36. public override async void ChannelInactive(IChannelHandlerContext context)
  37. {
  38. try
  39. {
  40. }
  41. catch (Exception ex)
  42. {
  43. _logger.LogInformation($"{nameof(RegisterHandler)} --- {nameof(ChannelInactive)} 出错\n{ex.Message}\n{ex.StackTrace}");
  44. }
  45. }
  46. public override void HandlerRemoved(IChannelHandlerContext context)
  47. {
  48. base.HandlerRemoved(context);
  49. }
  50. public override async void ChannelRead(IChannelHandlerContext context, object message)
  51. {
  52. if (message is ProtocolParser parser)
  53. {
  54. try
  55. {
  56. using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = parser.SeqNo }))
  57. {
  58. //认证
  59. //if (parser.FuncNo.Equals("10"))
  60. //{
  61. // #region 认证业务
  62. // // PHONE_AUTHEN
  63. // ProtocolWrapper phoneAuthWrapper = new(parser.FuncNo, parser.SeqNo, "1");
  64. // await SendToTcpClientAsync(phoneAuthWrapper, context.Channel);
  65. // // ABT_STATUS 延时3秒 给终端同步时间
  66. // await context.Channel.EventLoop.Schedule(async () =>
  67. // {
  68. // ProtocolWrapper abtStatusWrapper = new("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
  69. // await SendToTcpClientAsync(abtStatusWrapper, context.Channel);
  70. // },TimeSpan.FromSeconds(3));
  71. // #endregion
  72. //}
  73. //else if (parser.FuncNo.Equals("82"))
  74. //{
  75. // // 认证成功
  76. // _logger.LogInformation($"认证成功{parser.Data}.");
  77. //}
  78. //// 心跳
  79. //else if (parser.FuncNo.Equals("05"))
  80. //{
  81. // ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo,"");
  82. // await SendToTcpClientAsync(stdtSignRecsWrapper, context.Channel);
  83. //} // STDT_SIGN_RECS
  84. //else if (parser.FuncNo.Equals("04"))
  85. //{
  86. // // 回应设备
  87. // ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo,"1");
  88. // await SendToTcpClientAsync(stdtSignRecsWrapper, context.Channel);
  89. // // 刷卡考勤信息,需要推送给第三方平台
  90. // //var url = "";
  91. // //await _httpHelper.HttpToPostAsync(url, new object());
  92. //}
  93. //// STDT_SCHOOL_RECS
  94. //else if (parser.FuncNo.Equals("08"))
  95. //{
  96. // _logger.LogInformation($"接受STDT_SCHOOL_RECS 08 成功{parser.Data}.");
  97. // ProtocolWrapper stdtSchoolRecsWrapper = new(parser.FuncNo, parser.SeqNo, "1");
  98. // await SendToTcpClientAsync(stdtSchoolRecsWrapper, context.Channel);
  99. //}
  100. //switch (parser.FuncNo)
  101. //{
  102. // case "10":
  103. // break;
  104. // case "82":
  105. // break;
  106. // default:
  107. // break;
  108. //}
  109. switch (parser.FuncNo)
  110. {
  111. case "10":
  112. await HandleAuthenticationAsync(parser, context.Channel);
  113. break;
  114. case "82":
  115. await HandleAuthenticationSuccessAsync(parser, context.Channel);
  116. break;
  117. case "05":
  118. await SendHeartbeatAsync(parser, context.Channel);
  119. break;
  120. case "04":
  121. await HandleSignRecsAsync(parser, context.Channel);
  122. break;
  123. case "08":
  124. await HandleStdtSchoolRecsAsync(parser, context.Channel);
  125. break;
  126. default:
  127. _logger.LogInformation($"未处理业务,func_no:{parser.FuncNo},seq_no{parser.SeqNo},data:{parser.Data}");
  128. break;
  129. }
  130. }
  131. }
  132. catch (Exception ex)
  133. {
  134. _logger.LogInformation($"{nameof(RegisterHandler)} --- {nameof(ChannelRead)} 处理消息 {parser.SeqNo} 出错\n{ex.Message}\n{ex.StackTrace}");
  135. }
  136. }
  137. }
  138. /// <summary>
  139. /// 发送到TCP客户端
  140. /// </summary>
  141. /// <param name="wrapper"></param>
  142. /// <param name="channel"></param>
  143. private async Task SendToTcpClientAsync(ProtocolWrapper wrapper, IChannel channel)
  144. {
  145. string protocolMsg = wrapper.GenerateProtocolString();
  146. // 发送protocolMsg到tcp客户端
  147. await channel
  148. .WriteAndFlushAsync(Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(protocolMsg)))
  149. .ContinueWith(Action => {
  150. _logger.LogInformation($"{nameof(RegisterHandler)} -- {nameof(SendToTcpClientAsync)} -- 下发设备内容:\n{protocolMsg}");
  151. });
  152. }
  153. /// <summary>
  154. /// 认证业务
  155. /// </summary>
  156. /// <param name="parser"></param>
  157. /// <param name="channel"></param>
  158. /// <returns></returns>
  159. private async Task HandleAuthenticationAsync(ProtocolParser parser, IChannel channel)
  160. {
  161. ProtocolWrapper phoneAuthWrapper = new(parser.FuncNo, parser.SeqNo, "1");
  162. await SendToTcpClientAsync(phoneAuthWrapper, channel);
  163. await channel.EventLoop.Schedule(async () =>
  164. {
  165. ProtocolWrapper abtStatusWrapper = new("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
  166. await SendToTcpClientAsync(abtStatusWrapper, channel);
  167. }, TimeSpan.FromSeconds(3));
  168. }
  169. /// <summary>
  170. /// 认证业务成功
  171. /// </summary>
  172. /// <param name="parser"></param>
  173. /// <param name="channel"></param>
  174. /// <returns></returns>
  175. private async Task HandleAuthenticationSuccessAsync(ProtocolParser parser, IChannel channel)
  176. {
  177. _logger.LogInformation($"认证成功: func_no:{parser.FuncNo},seq_no{parser.SeqNo},data:{parser.Data}.");
  178. await Task.CompletedTask;
  179. }
  180. /// <summary>
  181. /// CONNECT_STATUS 网络连接状态查询[取值:05] (心跳业务)
  182. /// </summary>
  183. /// <param name="parser"></param>
  184. /// <param name="channel"></param>
  185. /// <returns></returns>
  186. private async Task SendHeartbeatAsync(ProtocolParser parser, IChannel channel)
  187. {
  188. ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo, "");
  189. await SendToTcpClientAsync(stdtSignRecsWrapper, channel);
  190. }
  191. /// <summary>
  192. /// STDT_SIGN_RECS 学生签到记录[取值:04]
  193. /// </summary>
  194. /// <param name="parser"></param>
  195. /// <param name="channel"></param>
  196. /// <returns></returns>
  197. private async Task HandleSignRecsAsync(ProtocolParser parser, IChannel channel)
  198. {
  199. ProtocolWrapper stdtSignRecsWrapper = new(parser.FuncNo, parser.SeqNo, "1");
  200. await SendToTcpClientAsync(stdtSignRecsWrapper, channel);
  201. var deviceId = parser.Data.Substring(0, 18).TrimEnd();
  202. var cardId= parser.Data.Substring(18,18).TrimEnd();
  203. var studentId = parser.Data.Substring(36,18).TrimEnd();
  204. var startTime = parser.Data.Substring(54, 14).TrimEnd();
  205. // Push card attendance information to third-party platform
  206. //var url = "https://midplat.xinhualeyu.com/dev-api/user/electronicCardAttendance/receiveTbAttendanceRecord";
  207. var url = _configService.XinHuaLeYuUrl;
  208. var data = new
  209. {
  210. attendanceStatus = 2, //考勤状态: 0.进 1.出 2.未知
  211. attendanceTime = DateTime.TryParse(startTime, out DateTime time) ? time.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  212. imei = deviceId
  213. };
  214. var res=await _httpHelper.HttpToPostAsync(url, data);
  215. _logger.LogInformation($"{nameof(HandleSignRecsAsync)} 推送 {JsonConvert.SerializeObject(data)} 结果,{res}");
  216. }
  217. /// <summary>
  218. /// STDT_SCHOOL_RECS 学生进校离校记录[取值:08]
  219. /// </summary>
  220. /// <param name="parser"></param>
  221. /// <param name="channel"></param>
  222. /// <returns></returns>
  223. private async Task HandleStdtSchoolRecsAsync(ProtocolParser parser, IChannel channel)
  224. {
  225. _logger.LogInformation($"Received STDT_SCHOOL_RECS successfully: {parser.Data}.");
  226. ProtocolWrapper stdtSchoolRecsWrapper = new(parser.FuncNo, parser.SeqNo, "1");
  227. await SendToTcpClientAsync(stdtSchoolRecsWrapper, channel);
  228. var deviceId = parser.Data.Substring(0, 18).TrimEnd();
  229. var cardId = parser.Data.Substring(18, 18).TrimEnd();
  230. var studentId = parser.Data.Substring(36, 18).TrimEnd();
  231. var startTime = parser.Data.Substring(54, 14).TrimEnd();
  232. var optType = parser.Data.Substring(68, 1).TrimEnd();
  233. //var url = "https://midplat.xinhualeyu.com/dev-api/user/electronicCardAttendance/receiveTbAttendanceRecord";
  234. var url = _configService.XinHuaLeYuUrl;
  235. var data = new
  236. {
  237. attendanceStatus = int.TryParse(optType,out int type) ? type : 0,
  238. attendanceTime = DateTime.TryParse(startTime, out DateTime time) ? time.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  239. imei = deviceId
  240. };
  241. var res = await _httpHelper.HttpToPostAsync(url, data);
  242. _logger.LogInformation($"{nameof(HandleStdtSchoolRecsAsync)} 推送 {JsonConvert.SerializeObject(data)} 结果,{res}");
  243. }
  244. }
  245. }