From 121e4773af8d60dabb589fbf43708980fc593257 Mon Sep 17 00:00:00 2001 From: SmallChi <564952747@qq.com> Date: Mon, 5 Nov 2018 19:31:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BC=9A=E8=AF=9D=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=8F=8A=E7=BB=9F=E4=B8=80=E4=B8=8B=E5=8F=91=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT808.DotNetty.Hosting/Program.cs | 1 + src/JT808.DotNetty/Dtos/JT808ResultDto.cs | 15 ++ .../Dtos/JT808SessionInfoDto.cs | 26 +++ .../Handlers/JT808ConnectionHandler.cs | 2 + .../Interfaces/IJT808SessionService.cs | 58 +++++ .../IJT808UnificationSendService.cs | 15 ++ .../JT808SessionServiceDefaultImpl.cs | 203 ++++++++++++++++++ .../JT808UnificationSendServiceDefaultImpl.cs | 37 ++++ src/JT808.DotNetty/JT808.DotNetty.csproj | 1 + src/JT808.DotNetty/JT808DotnettyExtensions.cs | 36 +++- src/JT808.DotNetty/JT808SessionManager.cs | 67 +++++- src/JT808.DotNetty/Metadata/JT808Session.cs | 8 + 12 files changed, 454 insertions(+), 15 deletions(-) create mode 100644 src/JT808.DotNetty/Dtos/JT808ResultDto.cs create mode 100644 src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs create mode 100644 src/JT808.DotNetty/Interfaces/IJT808SessionService.cs create mode 100644 src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs create mode 100644 src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs create mode 100644 src/JT808.DotNetty/Internal/JT808UnificationSendServiceDefaultImpl.cs diff --git a/src/JT808.DotNetty.Hosting/Program.cs b/src/JT808.DotNetty.Hosting/Program.cs index bed0717..7890985 100644 --- a/src/JT808.DotNetty.Hosting/Program.cs +++ b/src/JT808.DotNetty.Hosting/Program.cs @@ -36,6 +36,7 @@ namespace JT808.DotNetty.Hosting services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHandlerBase), typeof(JT808MsgIdCustomHandler), ServiceLifetime.Singleton)); }) .UseJT808Host(); + await serverHostBuilder.RunConsoleAsync(); } } diff --git a/src/JT808.DotNetty/Dtos/JT808ResultDto.cs b/src/JT808.DotNetty/Dtos/JT808ResultDto.cs new file mode 100644 index 0000000..cb334c8 --- /dev/null +++ b/src/JT808.DotNetty/Dtos/JT808ResultDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Dtos +{ + public class JT808ResultDto + { + public string Message { get; set; } + + public int Code { get; set; } + + public T Data { get; set; } + } +} diff --git a/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs b/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs new file mode 100644 index 0000000..e50a69a --- /dev/null +++ b/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Dtos +{ + public class JT808SessionInfoDto + { + /// + /// 通道Id + /// + public string ChannelId { get; set; } + /// + /// 最后上线时间 + /// + public DateTime LastActiveTime { get; set; } + /// + /// 上线时间 + /// + public DateTime StartTime { get; set; } + /// + /// 终端手机号 + /// + public string TerminalPhoneNo { get; set; } + } +} diff --git a/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs b/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs index ef39504..c14d70c 100644 --- a/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs +++ b/src/JT808.DotNetty/Handlers/JT808ConnectionHandler.cs @@ -1,5 +1,6 @@ using DotNetty.Handlers.Timeout; using DotNetty.Transport.Channels; +using JT808.DotNetty.Metadata; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -32,6 +33,7 @@ namespace JT808.DotNetty.Handlers string channelId = context.Channel.Id.AsShortText(); if (logger.IsEnabled(LogLevel.Debug)) logger.LogDebug($"<<<{ channelId } Successful client connection to server."); + jT808SessionManager.TryAddSession(new JT808Session(context.Channel)); base.ChannelActive(context); } diff --git a/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs new file mode 100644 index 0000000..7eddb27 --- /dev/null +++ b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs @@ -0,0 +1,58 @@ +using JT808.DotNetty.Dtos; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Interfaces +{ + /// + /// JT808会话服务 + /// + public interface IJT808SessionService + { + /// + /// 获取真实连接数 + /// + /// + JT808ResultDto GetRealLinkCount(); + /// + /// 获取设备相关连的连接数 + /// + /// + JT808ResultDto GetRelevanceLinkCount(); + /// + /// 获取实际会话集合 + /// + /// + JT808ResultDto> GetRealAll(); + /// + /// 获取设备相关连会话集合 + /// + /// + JT808ResultDto> GetRelevanceAll(); + /// + /// 通过通道Id移除对应会话 + /// + /// + /// + JT808ResultDto RemoveByChannelId(string channelId); + /// + /// 通过设备终端号移除对应会话 + /// + /// + /// + JT808ResultDto RemoveByTerminalPhoneNo(string terminalPhoneNo); + /// + /// 通过通道Id获取会话信息 + /// + /// + /// + JT808ResultDto GetByChannelId(string channelId); + /// + /// 通过设备终端号获取会话信息 + /// + /// + /// + JT808ResultDto GetByTerminalPhoneNo(string terminalPhoneNo); + } +} diff --git a/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs b/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs new file mode 100644 index 0000000..2477e7b --- /dev/null +++ b/src/JT808.DotNetty/Interfaces/IJT808UnificationSendService.cs @@ -0,0 +1,15 @@ +using JT808.DotNetty.Dtos; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Interfaces +{ + /// + /// JT808统一下发命令 + /// + public interface IJT808UnificationSendService + { + JT808ResultDto Send(string terminalPhoneNo, byte[] data); + } +} diff --git a/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs b/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs new file mode 100644 index 0000000..64e976e --- /dev/null +++ b/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs @@ -0,0 +1,203 @@ +using JT808.DotNetty.Dtos; +using JT808.DotNetty.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace JT808.DotNetty.Internal +{ + internal class JT808SessionServiceDefaultImpl : IJT808SessionService + { + private readonly JT808SessionManager jT808SessionManager; + + public JT808SessionServiceDefaultImpl(JT808SessionManager jT808SessionManager) + { + this.jT808SessionManager = jT808SessionManager; + } + + public JT808ResultDto GetByChannelId(string channelId) + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + var result = jT808SessionManager.GetSessionByID(channelId); + JT808SessionInfoDto jT808SessionInfoDto = new JT808SessionInfoDto + { + TerminalPhoneNo = result.TerminalPhoneNo, + ChannelId=result.SessionID, + LastActiveTime=result.LastActiveTime, + StartTime=result.StartTime + }; + resultDto.Data = jT808SessionInfoDto; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto GetRelevanceLinkCount() + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + resultDto.Data = jT808SessionManager.RelevanceSessionCount; + resultDto.Code = 200; + } + catch (Exception ex) + { + resultDto.Data = 0; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto GetRealLinkCount() + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + resultDto.Data = jT808SessionManager.RealSessionCount; + resultDto.Code = 200; + } + catch (Exception ex) + { + resultDto.Data = 0; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto> GetRealAll() + { + JT808ResultDto> resultDto = new JT808ResultDto>(); + try + { + resultDto.Data = jT808SessionManager.GetRealAll().Select(s => new JT808SessionInfoDto + { + ChannelId = s.SessionID, + LastActiveTime = s.LastActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo + }).ToList(); + resultDto.Code = 200; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto> GetRelevanceAll() + { + JT808ResultDto> resultDto = new JT808ResultDto>(); + try + { + resultDto.Data = jT808SessionManager.GetRelevanceAll().Select(s => new JT808SessionInfoDto + { + ChannelId = s.SessionID, + LastActiveTime = s.LastActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo + }).ToList(); + resultDto.Code = 200; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto RemoveByChannelId(string channelId) + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + var session = jT808SessionManager.RemoveSessionByID(channelId); + if (session != null) + { + session.Channel.CloseAsync(); + } + resultDto.Code = 200; + resultDto.Data = true; + } + catch (AggregateException ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto RemoveByTerminalPhoneNo(string terminalPhoneNo) + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + var session = jT808SessionManager.RemoveSessionByTerminalPhoneNo(terminalPhoneNo); + if (session != null) + { + session.Channel.CloseAsync(); + } + resultDto.Code = 200; + resultDto.Data = true; + } + catch (AggregateException ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + + public JT808ResultDto GetByTerminalPhoneNo(string terminalPhoneNo) + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + var result = jT808SessionManager.GetSessionByTerminalPhoneNo(terminalPhoneNo); + JT808SessionInfoDto jT808SessionInfoDto = new JT808SessionInfoDto + { + TerminalPhoneNo = result.TerminalPhoneNo, + ChannelId = result.SessionID, + LastActiveTime = result.LastActiveTime, + StartTime = result.StartTime + }; + resultDto.Data = jT808SessionInfoDto; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + } +} diff --git a/src/JT808.DotNetty/Internal/JT808UnificationSendServiceDefaultImpl.cs b/src/JT808.DotNetty/Internal/JT808UnificationSendServiceDefaultImpl.cs new file mode 100644 index 0000000..9784732 --- /dev/null +++ b/src/JT808.DotNetty/Internal/JT808UnificationSendServiceDefaultImpl.cs @@ -0,0 +1,37 @@ +using DotNetty.Buffers; +using JT808.DotNetty.Dtos; +using JT808.DotNetty.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Internal +{ + internal class JT808UnificationSendServiceDefaultImpl : IJT808UnificationSendService + { + private readonly JT808SessionManager jT808SessionManager; + + public JT808UnificationSendServiceDefaultImpl(JT808SessionManager jT808SessionManager) + { + this.jT808SessionManager = jT808SessionManager; + } + + public JT808ResultDto Send(string terminalPhoneNo, byte[] data) + { + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + var session = jT808SessionManager.GetSessionByTerminalPhoneNo(terminalPhoneNo); + session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); + resultDto.Data = true; + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + } + return resultDto; + } + } +} diff --git a/src/JT808.DotNetty/JT808.DotNetty.csproj b/src/JT808.DotNetty/JT808.DotNetty.csproj index f9df2b8..55f0152 100644 --- a/src/JT808.DotNetty/JT808.DotNetty.csproj +++ b/src/JT808.DotNetty/JT808.DotNetty.csproj @@ -14,6 +14,7 @@ + diff --git a/src/JT808.DotNetty/JT808DotnettyExtensions.cs b/src/JT808.DotNetty/JT808DotnettyExtensions.cs index 4b37b26..bbefa67 100644 --- a/src/JT808.DotNetty/JT808DotnettyExtensions.cs +++ b/src/JT808.DotNetty/JT808DotnettyExtensions.cs @@ -16,16 +16,32 @@ namespace JT808.DotNetty public static IHostBuilder UseJT808Host(this IHostBuilder builder) { return builder.ConfigureServices((hostContext, services) => - { - services.Configure(hostContext.Configuration.GetSection("JT808Configuration")); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.AddHostedService(); - }); + { + services.Configure(hostContext.Configuration.GetSection("JT808Configuration")); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.AddHostedService(); + }); + } + + public static void UseJT808Host(this IServiceCollection serviceDescriptors, HostBuilderContext hostContext) + { + serviceDescriptors.Configure(hostContext.Configuration.GetSection("JT808Configuration")); + serviceDescriptors.TryAddSingleton(); + serviceDescriptors.TryAddSingleton(); + serviceDescriptors.TryAddSingleton(); + serviceDescriptors.TryAddScoped(); + serviceDescriptors.TryAddScoped(); + serviceDescriptors.TryAddScoped(); + serviceDescriptors.TryAddSingleton(); + serviceDescriptors.TryAddSingleton(); + serviceDescriptors.AddHostedService(); } } } \ No newline at end of file diff --git a/src/JT808.DotNetty/JT808SessionManager.cs b/src/JT808.DotNetty/JT808SessionManager.cs index e49643c..a8d3c37 100644 --- a/src/JT808.DotNetty/JT808SessionManager.cs +++ b/src/JT808.DotNetty/JT808SessionManager.cs @@ -29,8 +29,8 @@ namespace JT808.DotNetty { while (!cancellationTokenSource.IsCancellationRequested) { - logger.LogInformation($"Online Count>>>{SessionCount}"); - if (SessionCount > 0) + logger.LogInformation($"Online Count>>>{RealSessionCount}"); + if (RealSessionCount > 0) { logger.LogInformation($"SessionIds>>>{string.Join(",", SessionIdDict.Select(s => s.Key))}"); logger.LogInformation($"TerminalPhoneNos>>>{string.Join(",", TerminalPhoneNo_SessionId_Dict.Select(s => $"{s.Key}-{s.Value}"))}"); @@ -53,7 +53,10 @@ namespace JT808.DotNetty /// private ConcurrentDictionary TerminalPhoneNo_SessionId_Dict = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - public int SessionCount + /// + /// 实际连接数 + /// + public int RealSessionCount { get { @@ -61,6 +64,17 @@ namespace JT808.DotNetty } } + /// + /// 获取设备相关连的连接数 + /// + public int RelevanceSessionCount + { + get + { + return TerminalPhoneNo_SessionId_Dict.Count; + } + } + public JT808Session GetSessionByID(string sessionID) { if (string.IsNullOrEmpty(sessionID)) @@ -130,9 +144,14 @@ namespace JT808.DotNetty TerminalPhoneNo_SessionId_Dict.AddOrUpdate(appSession.TerminalPhoneNo, appSession.SessionID, (x, y) => appSession.SessionID); } - public void RemoveSessionByID(string sessionID) + public void TryAddSession(JT808Session appSession) + { + SessionIdDict.AddOrUpdate(appSession.SessionID, appSession, (x, y) => appSession); + } + + public JT808Session RemoveSessionByID(string sessionID) { - if (sessionID == null) return; + if (sessionID == null) return null; try { if (SessionIdDict.TryRemove(sessionID, out JT808Session session)) @@ -148,14 +167,52 @@ namespace JT808.DotNetty { logger.LogInformation($">>>{sessionID} Session Remove."); } + return session; } + return null; } catch (Exception ex) { logger.LogError(ex, $">>>{sessionID} Session Remove Exception"); } + return null; } + public JT808Session RemoveSessionByTerminalPhoneNo(string terminalPhoneNo) + { + if (terminalPhoneNo == null) return null; + try + { + if (TerminalPhoneNo_SessionId_Dict.TryRemove(terminalPhoneNo, out string sessionid)) + { + if (SessionIdDict.TryRemove(sessionid, out JT808Session session)) + { + logger.LogInformation($">>>{sessionid}-{session.TerminalPhoneNo} Session Remove."); + return session; + } + else + { + return null; + } + } + } + catch (Exception ex) + { + logger.LogError(ex, $">>>{terminalPhoneNo} Session Remove Exception"); + } + return null; + } + + public IEnumerable GetRealAll() + { + return SessionIdDict.Select(s=>s.Value); + } + + public List GetRelevanceAll() + { + return SessionIdDict.Join(TerminalPhoneNo_SessionId_Dict, m => m.Key, s => s.Value, (m, s) => m.Value).ToList(); + } + public void Dispose() { cancellationTokenSource.Cancel(); diff --git a/src/JT808.DotNetty/Metadata/JT808Session.cs b/src/JT808.DotNetty/Metadata/JT808Session.cs index ba56136..0c3af26 100644 --- a/src/JT808.DotNetty/Metadata/JT808Session.cs +++ b/src/JT808.DotNetty/Metadata/JT808Session.cs @@ -16,6 +16,14 @@ namespace JT808.DotNetty.Metadata SessionID = Channel.Id.AsShortText(); } + public JT808Session(IChannel channel) + { + Channel = channel; + StartTime = DateTime.Now; + LastActiveTime = DateTime.Now; + SessionID = Channel.Id.AsShortText(); + } + /// /// 终端手机号 ///