diff --git a/src/JT808.Gateway.Abstractions/Dtos/JT808DefaultResultDto.cs b/src/JT808.Gateway.Abstractions/Dtos/JT808DefaultResultDto.cs new file mode 100644 index 0000000..5ec9049 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/Dtos/JT808DefaultResultDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Gateway.Abstractions.Dtos +{ + public class JT808DefaultResultDto: JT808ResultDto + { + public JT808DefaultResultDto() + { + Data = "Hello,JT808 WebAPI"; + Code = JT808ResultCode.Ok; + } + } +} diff --git a/src/JT808.Gateway.Abstractions/Dtos/JT808ResultDto.cs b/src/JT808.Gateway.Abstractions/Dtos/JT808ResultDto.cs new file mode 100644 index 0000000..c323862 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/Dtos/JT808ResultDto.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Gateway.Abstractions.Dtos +{ + public class JT808ResultDto + { + public JT808ResultDto() + { + Code = JT808ResultCode.Ok; + } + + public string Message { get; set; } + + public int Code { get; set; } + + public T Data { get; set; } + } + + public class JT808ResultCode + { + public const int Ok = 200; + public const int Empty = 201; + public const int AuthFail = 401; + public const int NotFound = 404; + public const int Fail = 400; + public const int Error = 500; + } +} diff --git a/src/JT808.Gateway.Abstractions/Dtos/JT808TcpSessionInfoDto.cs b/src/JT808.Gateway.Abstractions/Dtos/JT808TcpSessionInfoDto.cs new file mode 100644 index 0000000..942b9f3 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/Dtos/JT808TcpSessionInfoDto.cs @@ -0,0 +1,24 @@ +using System; + +namespace JT808.Gateway.Abstractions.Dtos +{ + public class JT808TcpSessionInfoDto + { + /// + /// 最后上线时间 + /// + public DateTime LastActiveTime { get; set; } + /// + /// 上线时间 + /// + public DateTime StartTime { get; set; } + /// + /// 终端手机号 + /// + public string TerminalPhoneNo { get; set; } + /// + /// 远程ip地址 + /// + public string RemoteAddressIP { get; set; } + } +} diff --git a/src/JT808.Gateway.Abstractions/Dtos/JT808UdpSessionInfoDto.cs b/src/JT808.Gateway.Abstractions/Dtos/JT808UdpSessionInfoDto.cs new file mode 100644 index 0000000..ef2e179 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/Dtos/JT808UdpSessionInfoDto.cs @@ -0,0 +1,24 @@ +using System; + +namespace JT808.Gateway.Abstractions.Dtos +{ + public class JT808UdpSessionInfoDto + { + /// + /// 最后上线时间 + /// + public DateTime LastActiveTime { get; set; } + /// + /// 上线时间 + /// + public DateTime StartTime { get; set; } + /// + /// 终端手机号 + /// + public string TerminalPhoneNo { get; set; } + /// + /// 远程ip地址 + /// + public string RemoteAddressIP { get; set; } + } +} diff --git a/src/JT808.Gateway.Abstractions/Dtos/JT808UnificationSendRequestDto.cs b/src/JT808.Gateway.Abstractions/Dtos/JT808UnificationSendRequestDto.cs new file mode 100644 index 0000000..065234b --- /dev/null +++ b/src/JT808.Gateway.Abstractions/Dtos/JT808UnificationSendRequestDto.cs @@ -0,0 +1,11 @@ +namespace JT808.Gateway.Abstractions.Dtos +{ + /// + /// 统一下发请求参数 + /// + public class JT808UnificationSendRequestDto + { + public string TerminalPhoneNo { get; set; } + public string Data { get; set; } + } +} diff --git a/src/JT808.Gateway.Abstractions/IJT808Authorization.cs b/src/JT808.Gateway.Abstractions/IJT808Authorization.cs new file mode 100644 index 0000000..1c92f40 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/IJT808Authorization.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Security.Principal; +using System.Text; + +namespace JT808.Gateway.Abstractions +{ + public interface IJT808Authorization + { + bool Authorization(HttpListenerContext context, out IPrincipal principal); + } +} diff --git a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj index 5fbd11f..269968f 100644 --- a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj +++ b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj @@ -26,17 +26,8 @@ JT808.Gateway.Abstractions.xml - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + diff --git a/src/JT808.Gateway.Abstractions/JT808GatewayConstants.cs b/src/JT808.Gateway.Abstractions/JT808GatewayConstants.cs index 6c631de..cefd329 100644 --- a/src/JT808.Gateway.Abstractions/JT808GatewayConstants.cs +++ b/src/JT808.Gateway.Abstractions/JT808GatewayConstants.cs @@ -7,5 +7,44 @@ public const string SessionTopic = "jt808session"; public const string MsgTopic = "jt808msgdefault"; public const string MsgReplyTopic = "jt808msgreplydefault"; + public static class JT808WebApiRouteTable + { + public const string RouteTablePrefix = "/jt808api"; + + public const string SessionPrefix = "Session"; + + public const string TcpPrefix = "Tcp"; + + public const string UdpPrefix = "Udp"; + + /// + /// 基于Tcp的会话服务集合 + /// + public static string SessionTcpGetAll = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/GetAll"; + /// + /// 会话服务-通过设备终端号移除对应会话 + /// + public static string SessionRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/RemoveByTerminalPhoneNo"; + /// + /// 会话服务-通过设备终端号查询对应会话 + /// + public static string QueryTcpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/QueryTcpSessionByTerminalPhoneNo"; + /// + /// 统一下发信息 + /// + public static string UnificationSend = $"{RouteTablePrefix}/UnificationSend"; + /// + /// 基于Udp的虚拟会话服务集合 + /// + public static string SessionUdpGetAll = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/GetAll"; + /// + /// 会话服务-通过设备终端号移除对应会话 + /// + public static string RemoveUdpByTerminalPhoneNo = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/RemoveUdpByTerminalPhoneNo"; + /// + /// 会话服务-通过设备终端号查询对应会话 + /// + public static string QueryUdpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/QueryUdpSessionByTerminalPhoneNo"; + } } } diff --git a/src/JT808.Gateway.Abstractions/JT808MsgIdHttpHandlerBase.cs b/src/JT808.Gateway.Abstractions/JT808MsgIdHttpHandlerBase.cs new file mode 100644 index 0000000..1a94939 --- /dev/null +++ b/src/JT808.Gateway.Abstractions/JT808MsgIdHttpHandlerBase.cs @@ -0,0 +1,90 @@ +using JT808.Gateway.Abstractions.Dtos; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; + +namespace JT808.Gateway.Abstractions +{ + public abstract class JT808MsgIdHttpHandlerBase + { + public Dictionary> HandlerDict { get; } + + /// + /// 初始化消息处理业务 + /// + protected JT808MsgIdHttpHandlerBase() + { + HandlerDict = new Dictionary>(); + } + + protected void CreateRoute(string url, Func func) + { + if (!HandlerDict.ContainsKey(url)) + { + HandlerDict.Add(url, func); + } + else + { + // 替换 + HandlerDict[url] = func; + } + } + + protected byte[] CreateHttpResponse(dynamic dynamicObject) + { + byte[] data = JsonSerializer.SerializeToUtf8Bytes(dynamicObject); + return data; + } + + public byte[] DefaultHttpResponse() + { + byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808DefaultResultDto()); + return json; + } + + public byte[] EmptyHttpResponse() + { + byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() + { + Code = JT808ResultCode.Empty, + Message = "内容为空", + Data = "Content Empty" + }); + return json; + } + + public byte[] NotFoundHttpResponse() + { + byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() + { + Code = JT808ResultCode.NotFound, + Message = "没有该服务", + Data = "没有该服务" + }); + return json; + } + + public byte[] AuthFailHttpResponse() + { + byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() + { + Code = JT808ResultCode.AuthFail, + Message = "token认证失败", + Data = "token认证失败" + }); + return json; + } + + public byte[] ErrorHttpResponse(Exception ex) + { + byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() + { + Code = JT808ResultCode.Error, + Message = ex.StackTrace, + Data = ex.Message + }); + return json; + } + } +} diff --git a/src/JT808.Gateway.Abstractions/Protos/JT808Gateway.proto b/src/JT808.Gateway.Abstractions/Protos/JT808Gateway.proto deleted file mode 100644 index 81fe9f6..0000000 --- a/src/JT808.Gateway.Abstractions/Protos/JT808Gateway.proto +++ /dev/null @@ -1,73 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "JT808.Gateway.GrpcService"; - -package JT808GatewayGrpc; - -service JT808Gateway{ - // 会话服务-获取会话服务集合 - rpc GetTcpSessionAll(Empty) returns (TcpSessionInfoReply); - // 会话服务-获取会话总数 - rpc GetTcpSessionCount(Empty) returns (SessionCountReply); - // 会话服务-通过设备终端号获取当前会话信息 - rpc GetTcpSessionByTerminalPhoneNo(SessionRequest) returns (SessionInfo); - // 会话服务-通过设备终端号移除对应会话 - rpc RemoveSessionByTerminalPhoneNo(SessionRemoveRequest) returns (SessionRemoveReply); - // 统一下发信息 - rpc UnificationSend(UnificationSendRequest) returns (UnificationSendReply); - // 获取Tcp包计数器 - rpc GetTcpAtomicCounter(Empty) returns (TcpAtomicCounterReply); - // 会话服务-获取会话服务集合 - rpc GetUdpSessionAll(Empty) returns (UdpSessionInfoReply); - // 获取Udp包计数器 - rpc GetUdpAtomicCounter(Empty) returns (UdpAtomicCounterReply); -} - -message Empty{} - -message TcpSessionInfoReply{ - repeated SessionInfo TcpSessions=1; -} -message SessionRequest{ - string TerminalPhoneNo=1; -} -message SessionCountReply{ - int64 Count=1; -} -message UdpSessionInfoReply{ - repeated SessionInfo UdpSessions=1; -} - -message SessionInfo{ - string StartTime=1; - string LastActiveTime=2; - string TerminalPhoneNo=3; - string RemoteAddressIP=4; -} - -message SessionRemoveRequest{ - string TerminalPhoneNo=1; -} - -message SessionRemoveReply{ - bool Success = 1; -} - -message UnificationSendRequest{ - string TerminalPhoneNo=1; - bytes Data=2; -} - -message UnificationSendReply{ - bool Success = 1; -} - -message TcpAtomicCounterReply{ - int64 MsgSuccessCount=1; - int64 MsgFailCount=2; -} - -message UdpAtomicCounterReply{ - int64 MsgSuccessCount=1; - int64 MsgFailCount=2; -} \ No newline at end of file diff --git a/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj b/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj index b069c13..d2b8bbd 100644 --- a/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj +++ b/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj @@ -12,11 +12,11 @@ - - - - - + + + + + diff --git a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj index 62f3fc3..35a79af 100644 --- a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj +++ b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj @@ -6,10 +6,10 @@ - - + + - + diff --git a/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj b/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj index 95de2ec..df8fdcf 100644 --- a/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj +++ b/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj @@ -22,12 +22,12 @@ - - - + + + - - + + diff --git a/src/JT808.Gateway.Client/JT808TcpClient.cs b/src/JT808.Gateway.Client/JT808TcpClient.cs index 82ea98e..c5db80e 100644 --- a/src/JT808.Gateway.Client/JT808TcpClient.cs +++ b/src/JT808.Gateway.Client/JT808TcpClient.cs @@ -15,8 +15,11 @@ using Microsoft.Extensions.DependencyInjection; namespace JT808.Gateway.Client { + public class JT808TcpClient:IDisposable { + //todo: 客户端的断线重连 + //todo: 客户端的消息处理handler private bool disposed = false; private Socket clientSocket; private readonly ILogger Logger; diff --git a/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj b/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj index acc5861..b3204f2 100644 --- a/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj +++ b/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj @@ -20,12 +20,12 @@ $(JT808GatewayPackageVersion) - - - - - - + + + + + + diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj b/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj index 6651c8f..a9a8058 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj +++ b/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj @@ -22,7 +22,7 @@ LICENSE - + diff --git a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj b/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj index 70d1057..17f45f4 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj +++ b/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj @@ -21,7 +21,7 @@ LICENSE - + diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj b/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj index 5e17e0b..6c3dd4f 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj +++ b/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj @@ -22,7 +22,7 @@ LICENSE - + diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj b/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj index 29e5037..64ba4aa 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj +++ b/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj @@ -22,7 +22,7 @@ LICENSE - + diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj index 2c53225..d338923 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj @@ -5,12 +5,16 @@ netcoreapp3.1 + + + + - - + + - + diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs index 59ba3a3..265ecb3 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs @@ -60,7 +60,6 @@ namespace JT808.Gateway.NormalHosting .AddTransmit(hostContext.Configuration) .AddTcp() .AddUdp() - .AddGrpc() ; //流量统计 services.AddHostedService(); diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj index 96ec2ee..ab48acf 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj @@ -6,10 +6,14 @@ - - + + + + + + - + diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs index 7c9bf83..a9e3e58 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs @@ -52,7 +52,6 @@ namespace JT808.Gateway.QueueHosting .AddServerKafkaMsgReplyConsumer(hostContext.Configuration) .AddTcp() .AddUdp() - .AddGrpc() .Builder() //添加客户端工具 .AddClient() diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj index ca5e220..f19de0f 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj @@ -7,15 +7,15 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.csproj b/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.csproj new file mode 100644 index 0000000..a5877ab --- /dev/null +++ b/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.csproj @@ -0,0 +1,34 @@ + + + + netstandard2.1 + 8.0 + Copyright 2019. + SmallChi(Koike) + https://github.com/SmallChi/JT808Gateway + https://github.com/SmallChi/JT808Gateway + https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE + https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE + false + $(JT808GatewayPackageVersion) + false + LICENSE + true + JT808.Gateway.WebApiClientTool + JT808.Gateway.WebApiClientTool + 基于Pipeline的WebApiClient客户端调用工具 + 基于Pipeline的WebApiClient客户端调用工具 + + + JT808.Gateway.WebApiClientTool.xml + + + + + + + + + + + diff --git a/src/JT808.Gateway.WebApiClientTool/JT808HttpClient.cs b/src/JT808.Gateway.WebApiClientTool/JT808HttpClient.cs new file mode 100644 index 0000000..c6b01bf --- /dev/null +++ b/src/JT808.Gateway.WebApiClientTool/JT808HttpClient.cs @@ -0,0 +1,81 @@ +using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Dtos; +using System; +using System.Buffers.Text; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace JT808.Gateway.WebApiClientTool +{ + public class JT808HttpClient + { + //todo:其余接口待接入 + public HttpClient HttpClient { get; } + public JT808HttpClient(HttpClient httpClient) + { + HttpClient = httpClient; + } + /// + /// 会话服务集合 + /// + /// + public async ValueTask>> GetTcpSessionAll() + { + var request = new HttpRequestMessage(HttpMethod.Get, JT808GatewayConstants.JT808WebApiRouteTable.SessionTcpGetAll); + var response = HttpClient.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + var data = await response.Content.ReadAsStreamAsync(); + var value = await JsonSerializer.DeserializeAsync>>(data); + return value; + } + + /// + /// 会话服务-通过设备终端号移除对应会话 + /// + /// + /// + public async ValueTask> RemoveByTerminalPhoneNo(string terminalPhoneNo) + { + var request = new HttpRequestMessage(HttpMethod.Post, JT808GatewayConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo); + request.Content = new StringContent(terminalPhoneNo); + var response = HttpClient.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + var data = await response.Content.ReadAsStreamAsync(); + var value = await JsonSerializer.DeserializeAsync>(data); + return value; + } + + /// + /// 统一下发信息 + /// + /// + /// + public async ValueTask> UnificationSend(JT808UnificationSendRequestDto jT808UnificationSendRequestDto) + { + var request = new HttpRequestMessage(HttpMethod.Post, JT808GatewayConstants.JT808WebApiRouteTable.UnificationSend); + request.Content = new StringContent(JsonSerializer.Serialize(jT808UnificationSendRequestDto)); + var response = HttpClient.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + var data = await response.Content.ReadAsStreamAsync(); + var value = await JsonSerializer.DeserializeAsync>(data); + return value; + } + + /// + /// 会话服务集合 + /// + /// + public async ValueTask>> GetUdpSessionAll() + { + var request = new HttpRequestMessage(HttpMethod.Get, JT808GatewayConstants.JT808WebApiRouteTable.SessionUdpGetAll); + var response = HttpClient.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + var data = await response.Content.ReadAsStreamAsync(); + var value = await JsonSerializer.DeserializeAsync>>(data); + return value; + } + } +} diff --git a/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs b/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs new file mode 100644 index 0000000..11f6b1d --- /dev/null +++ b/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.Gateway.WebApiClientTool +{ + public static class JT808HttpClientExtensions + { + public static IServiceCollection AddJT808WebApiClientTool(this IServiceCollection serviceDescriptors, Uri webapiUri) + { + serviceDescriptors.AddHttpClient("JT808WebApiClientTool", c => + { + c.BaseAddress = webapiUri; + c.Timeout = TimeSpan.FromSeconds(3); + }) + .AddTypedClient(); + return serviceDescriptors; + } + + public static IServiceCollection AddJT808WebApiClientTool(this IServiceCollection serviceDescriptors, IConfiguration configuration) + { + serviceDescriptors.AddHttpClient("JT808WebApiClientTool", c => + { + c.BaseAddress = new Uri(configuration.GetSection("JT808WebApiClientToolConfig").Get()); + c.Timeout = TimeSpan.FromSeconds(3); + }) + .AddTypedClient(); + return serviceDescriptors; + } + } +} diff --git a/src/JT808.Gateway.sln b/src/JT808.Gateway.sln index 02ca89a..bf58e6c 100644 --- a/src/JT808.Gateway.sln +++ b/src/JT808.Gateway.sln @@ -21,8 +21,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ReplyMessage" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Transmit", "JT808.Gateway.Services\JT808.Gateway.Transmit\JT808.Gateway.Transmit.csproj", "{598E445A-AF2E-42F0-98F4-18EC22E473FC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Traffic", "JT808.Gateway.Services\JT808.Gateway.Traffic\JT808.Gateway.Traffic.csproj", "{8FCC6D65-8A49-4AE7-8B19-F255100849D6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Client", "JT808.Gateway.Client\JT808.Gateway.Client.csproj", "{AC3070AC-A938-4213-A562-C079BB4A3F9E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{7CBAACEE-19BF-499A-8C41-36A1324D45E9}" @@ -39,6 +37,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.CleintBenchma EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ServerBenchmark", "JT808.Gateway.Benchmark\JT808.Gateway.ServerBenchmark\JT808.Gateway.ServerBenchmark.csproj", "{AF0C529A-D3CA-4FE4-93B4-735D0934EBEF}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Traffic", "JT808.Gateway.Services\JT808.Gateway.Traffic\JT808.Gateway.Traffic.csproj", "{E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.WebApiClientTool", "JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj", "{479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -77,10 +79,6 @@ Global {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Debug|Any CPU.Build.0 = Debug|Any CPU {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Release|Any CPU.ActiveCfg = Release|Any CPU {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Release|Any CPU.Build.0 = Release|Any CPU - {8FCC6D65-8A49-4AE7-8B19-F255100849D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8FCC6D65-8A49-4AE7-8B19-F255100849D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8FCC6D65-8A49-4AE7-8B19-F255100849D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8FCC6D65-8A49-4AE7-8B19-F255100849D6}.Release|Any CPU.Build.0 = Release|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -105,6 +103,14 @@ Global {AF0C529A-D3CA-4FE4-93B4-735D0934EBEF}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF0C529A-D3CA-4FE4-93B4-735D0934EBEF}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF0C529A-D3CA-4FE4-93B4-735D0934EBEF}.Release|Any CPU.Build.0 = Release|Any CPU + {E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE}.Release|Any CPU.Build.0 = Release|Any CPU + {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -115,12 +121,12 @@ Global {1CB84599-5F56-4461-A451-DF16E3854AB9} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} {604BB5CF-9ED1-4D78-9328-59436E2B4EB4} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} {598E445A-AF2E-42F0-98F4-18EC22E473FC} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} - {8FCC6D65-8A49-4AE7-8B19-F255100849D6} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} {E3DC260E-0B55-4993-B051-402E44D4E883} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} {22368AAD-A1F3-446B-B68F-98A0933BF1F6} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} {52D895BD-C60B-42D8-9229-C85927546FDA} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} {E34C6B7D-A48B-4871-895C-07AC12F959D3} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} {AF0C529A-D3CA-4FE4-93B4-735D0934EBEF} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} + {E5A0BFB6-4345-4592-A2B1-E3CB1FA423AE} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AA9303A7-6FB3-4572-88AA-3302E85330D1} diff --git a/src/JT808.Gateway/Configurations/JT808Configuration.cs b/src/JT808.Gateway/Configurations/JT808Configuration.cs index 1f3e80c..898c02a 100644 --- a/src/JT808.Gateway/Configurations/JT808Configuration.cs +++ b/src/JT808.Gateway/Configurations/JT808Configuration.cs @@ -9,7 +9,6 @@ namespace JT808.Gateway.Configurations public int TcpPort { get; set; } = 808; public int UdpPort { get; set; } = 808; public int WebApiPort { get; set; } = 828; - public string WebApiHost{ get; set; } = "localhost"; /// /// WebApi 默认token 123456 /// diff --git a/src/JT808.Gateway/Extensions/JT808HttpContextExtensions.cs b/src/JT808.Gateway/Extensions/JT808HttpContextExtensions.cs new file mode 100644 index 0000000..1a1c8ee --- /dev/null +++ b/src/JT808.Gateway/Extensions/JT808HttpContextExtensions.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace JT808.Gateway.Extensions +{ + public static class JT808HttpContextExtensions + { + private const string jsonType = "application/json"; + + public static async ValueTask Http401(this HttpListenerContext context) + { + byte[] b = Encoding.UTF8.GetBytes("auth error"); + context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; + context.Response.ContentType = jsonType; + context.Response.KeepAlive = false; + context.Response.ContentLength64 = b.Length; + var output = context.Response.OutputStream; + await output.WriteAsync(b, 0, b.Length); + context.Response.OutputStream.Close(); + context.Response.Close(); + } + + public static async ValueTask Http400(this HttpListenerContext context) + { + byte[] b = Encoding.UTF8.GetBytes($"sim and channel parameter required."); + context.Response.StatusCode = (int)HttpStatusCode.BadRequest; + context.Response.KeepAlive = false; + context.Response.ContentType = jsonType; + context.Response.ContentLength64 = b.Length; + var output = context.Response.OutputStream; + await output.WriteAsync(b, 0, b.Length); + context.Response.OutputStream.Close(); + context.Response.Close(); + } + + public static void Http404(this HttpListenerContext context) + { + context.Response.StatusCode = (int)HttpStatusCode.NotFound; + context.Response.KeepAlive = false; + context.Response.ContentType = jsonType; + context.Response.OutputStream.Close(); + context.Response.Close(); + } + + public static async ValueTask Http500(this HttpListenerContext context) + { + byte[] b = Encoding.UTF8.GetBytes("inner error"); + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + context.Response.KeepAlive = false; + context.Response.ContentType = jsonType; + context.Response.ContentLength64 = b.Length; + var output = context.Response.OutputStream; + await output.WriteAsync(b, 0, b.Length); + context.Response.OutputStream.Close(); + context.Response.Close(); + } + + public static async ValueTask HttpSend(this HttpListenerContext context, ReadOnlyMemory buffer) + { + context.Response.StatusCode = (int)HttpStatusCode.OK; + context.Response.KeepAlive = true; + context.Response.ContentType = jsonType; + context.Response.ContentLength64 = buffer.Length; + await context.Response.OutputStream.WriteAsync(buffer); + context.Response.OutputStream.Close(); + context.Response.Close(); + } + + public static async ValueTask HttpSend(this HttpListenerContext context, string json) + { + byte[] b = Encoding.UTF8.GetBytes(json); + context.Response.StatusCode = (int)HttpStatusCode.OK; + context.Response.KeepAlive = true; + context.Response.ContentType = jsonType; + context.Response.ContentLength64 = b.Length; + await context.Response.OutputStream.WriteAsync(b); + context.Response.OutputStream.Close(); + context.Response.Close(); + } + } +} diff --git a/src/JT808.Gateway/Handlers/JT808MsgIdDefaultWebApiHandler.cs b/src/JT808.Gateway/Handlers/JT808MsgIdDefaultWebApiHandler.cs new file mode 100644 index 0000000..3652cdf --- /dev/null +++ b/src/JT808.Gateway/Handlers/JT808MsgIdDefaultWebApiHandler.cs @@ -0,0 +1,261 @@ +using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Dtos; +using JT808.Gateway.Session; +using JT808.Protocol.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; + +namespace JT808.Gateway.Handlers +{ + /// + /// 默认消息处理业务实现 + /// + public class JT808MsgIdDefaultWebApiHandler : JT808MsgIdHttpHandlerBase + { + private JT808SessionManager JT808SessionManager; + public JT808MsgIdDefaultWebApiHandler(JT808SessionManager jT808SessionManager) + { + this.JT808SessionManager = jT808SessionManager; + InitTcpRoute(); + InitUdpRoute(); + InitCommontRoute(); + } + + /// + /// 会话服务集合 + /// + /// + /// + public byte[] GetTcpSessionAll(string json) + { + JT808ResultDto> resultDto = new JT808ResultDto>(); + try + { + resultDto.Data = JT808SessionManager.GetTcpAll().Select(s => new JT808TcpSessionInfoDto + { + LastActiveTime = s.ActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo, + RemoteAddressIP = s.RemoteEndPoint.ToString(), + }).ToList(); + resultDto.Code = JT808ResultCode.Ok; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 通过终端手机号查询对应会话 + /// + /// + /// + public byte[] QueryTcpSessionByTerminalPhoneNo(string json) + { + if (string.IsNullOrEmpty(json)) + { + return EmptyHttpResponse(); + } + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + resultDto.Data = JT808SessionManager.GetTcpAll().Where(w => w.TerminalPhoneNo == json).Select(s => new JT808TcpSessionInfoDto + { + LastActiveTime = s.ActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo, + RemoteAddressIP = s.RemoteEndPoint.ToString(), + }).FirstOrDefault(); + resultDto.Code = JT808ResultCode.Ok; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 会话服务-通过设备终端号移除对应会话 + /// + /// + /// + public byte[] RemoveSessionByTerminalPhoneNo(string json) + { + if (string.IsNullOrEmpty(json)) + { + return EmptyHttpResponse(); + } + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + JT808SessionManager.RemoveByTerminalPhoneNo(json); + resultDto.Code = JT808ResultCode.Ok; + resultDto.Data = true; + } + catch (AggregateException ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = ex.StackTrace; + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 会话服务集合 + /// + /// + /// + public byte[] GetUdpSessionAll(string json) + { + JT808ResultDto> resultDto = new JT808ResultDto>(); + try + { + resultDto.Data = JT808SessionManager.GetUdpAll().Select(s => new JT808UdpSessionInfoDto + { + LastActiveTime = s.ActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo, + RemoteAddressIP = s.RemoteEndPoint.ToString(), + }).ToList(); + resultDto.Code = JT808ResultCode.Ok; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 通过终端手机号查询对应会话 + /// + /// + /// + public byte[] QueryUdpSessionByTerminalPhoneNo(string json) + { + if (string.IsNullOrEmpty(json)) + { + return EmptyHttpResponse(); + } + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + resultDto.Data = JT808SessionManager.GetUdpAll().Where(w => w.TerminalPhoneNo == json).Select(s => new JT808UdpSessionInfoDto + { + LastActiveTime = s.ActiveTime, + StartTime = s.StartTime, + TerminalPhoneNo = s.TerminalPhoneNo, + RemoteAddressIP = s.RemoteEndPoint.ToString(), + }).FirstOrDefault(); + resultDto.Code = JT808ResultCode.Ok; + } + catch (Exception ex) + { + resultDto.Data = null; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 会话服务-通过设备终端号移除对应会话 + /// + /// + /// + public byte[] RemoveUdpByTerminalPhoneNo(string json) + { + if (string.IsNullOrEmpty(json)) + { + return EmptyHttpResponse(); + } + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + JT808SessionManager.RemoveByTerminalPhoneNo(json); + resultDto.Code = JT808ResultCode.Ok; + resultDto.Data = true; + } + catch (AggregateException ex) + { + resultDto.Data = false; + resultDto.Code = 500; + resultDto.Message = ex.StackTrace; + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + /// + /// 统一下发信息 + /// + /// + /// + public byte[] UnificationSend(string json) + { + if (string.IsNullOrEmpty(json)) + { + return EmptyHttpResponse(); + } + JT808ResultDto resultDto = new JT808ResultDto(); + try + { + JT808UnificationSendRequestDto jT808UnificationSendRequestDto = JsonSerializer.Deserialize(json); + resultDto.Data = JT808SessionManager.TrySendByTerminalPhoneNoAsync(jT808UnificationSendRequestDto.TerminalPhoneNo, jT808UnificationSendRequestDto.Data.ToHexBytes()) + .GetAwaiter() + .GetResult(); + resultDto.Code = JT808ResultCode.Ok; + } + catch (Exception ex) + { + resultDto.Data = false; + resultDto.Code = JT808ResultCode.Error; + resultDto.Message = ex.StackTrace; + } + return CreateHttpResponse(resultDto); + } + + protected virtual void InitCommontRoute() + { + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.UnificationSend, UnificationSend); + } + + protected virtual void InitTcpRoute() + { + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.SessionTcpGetAll, GetTcpSessionAll); + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.QueryTcpSessionByTerminalPhoneNo, QueryTcpSessionByTerminalPhoneNo); + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo, RemoveSessionByTerminalPhoneNo); + } + + protected virtual void InitUdpRoute() + { + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.SessionUdpGetAll, GetUdpSessionAll); + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.QueryUdpSessionByTerminalPhoneNo, QueryUdpSessionByTerminalPhoneNo); + CreateRoute(JT808GatewayConstants.JT808WebApiRouteTable.RemoveUdpByTerminalPhoneNo, RemoveUdpByTerminalPhoneNo); + } + } +} diff --git a/src/JT808.Gateway/JT808.Gateway.csproj b/src/JT808.Gateway/JT808.Gateway.csproj index 6ec6dd1..419fda3 100644 --- a/src/JT808.Gateway/JT808.Gateway.csproj +++ b/src/JT808.Gateway/JT808.Gateway.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/src/JT808.Gateway/JT808GatewayExtensions.cs b/src/JT808.Gateway/JT808GatewayExtensions.cs index 38fbc8e..539798a 100644 --- a/src/JT808.Gateway/JT808GatewayExtensions.cs +++ b/src/JT808.Gateway/JT808GatewayExtensions.cs @@ -1,6 +1,7 @@ using JT808.Gateway.Abstractions; using JT808.Gateway.Configurations; using JT808.Gateway.Enums; +using JT808.Gateway.Handlers; using JT808.Gateway.Internal; using JT808.Gateway.Services; using JT808.Gateway.Session; @@ -74,15 +75,23 @@ namespace JT808.Gateway return config; } - public static IJT808GatewayBuilder AddGrpc(this IJT808GatewayBuilder config) + public static IJT808GatewayBuilder AddHttp(this IJT808GatewayBuilder config) { - config.JT808Builder.Services.AddHostedService(); + config.JT808Builder.Services.AddSingleton(); + config.JT808Builder.Services.AddHostedService(); + return config; + } + + public static IJT808GatewayBuilder AddHttp(this IJT808GatewayBuilder config) + where TJT808MsgIdDefaultWebApiHandler: JT808MsgIdDefaultWebApiHandler + { + config.JT808Builder.Services.AddSingleton(typeof(JT808MsgIdDefaultWebApiHandler),typeof(TJT808MsgIdDefaultWebApiHandler)); + config.JT808Builder.Services.AddHostedService(); return config; } private static IJT808GatewayBuilder AddJT808Core(this IJT808GatewayBuilder config) { - config.JT808Builder.Services.TryAddSingleton(); config.JT808Builder.Services.TryAddSingleton(); return config; } diff --git a/src/JT808.Gateway/JT808GrpcServer.cs b/src/JT808.Gateway/JT808GrpcServer.cs deleted file mode 100644 index 121f3e5..0000000 --- a/src/JT808.Gateway/JT808GrpcServer.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; -using JT808.Gateway.Configurations; -using JT808.Gateway.GrpcService; -using JT808.Gateway.Services; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace JT808.Gateway -{ - public class JT808GrpcServer : IHostedService - { - private readonly ILogger Logger; - private readonly JT808Configuration Configuration; - private readonly IServiceProvider ServiceProvider; - private Server server; - public JT808GrpcServer( - IServiceProvider serviceProvider, - IOptions jT808ConfigurationAccessor, - ILoggerFactory loggerFactory) - { - Logger = loggerFactory.CreateLogger("JT808GrpcServer"); - Configuration = jT808ConfigurationAccessor.Value; - ServiceProvider = serviceProvider; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - server = new Server - { - Services = { JT808Gateway.BindService(new JT808GatewayService(ServiceProvider)) }, - Ports = { new ServerPort(Configuration.WebApiHost, Configuration.WebApiPort, ServerCredentials.Insecure) } - }; - Logger.LogInformation($"JT808 Grpc Server start at {Configuration.WebApiHost}:{Configuration.WebApiPort}."); - try - { - server.Start(); - } - catch (Exception ex) - { - Logger.LogError(ex, "JT808 Grpc Server start error"); - } - return Task.CompletedTask; - } - public Task StopAsync(CancellationToken cancellationToken) - { - Logger.LogInformation("JT808 Grpc Server Stop"); - server.ShutdownAsync(); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.Gateway/JT808HttpServer.cs b/src/JT808.Gateway/JT808HttpServer.cs new file mode 100644 index 0000000..208cc77 --- /dev/null +++ b/src/JT808.Gateway/JT808HttpServer.cs @@ -0,0 +1,125 @@ +using JT808.Gateway.Abstractions; +using JT808.Gateway.Configurations; +using JT808.Gateway.Extensions; +using JT808.Gateway.Handlers; +using JT808.Gateway.Session; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.WebSockets; +using System.Security.Principal; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace JT808.Gateway +{ + public class JT808HttpServer : IHostedService + { + private readonly ILogger Logger; + + private readonly JT808Configuration Configuration; + + private readonly IJT808Authorization authorization; + + private HttpListener listener; + + private readonly JT808MsgIdDefaultWebApiHandler MsgIdDefaultWebApiHandler; + + public JT808HttpServer( + JT808MsgIdDefaultWebApiHandler jT808MsgIdDefaultWebApiHandler, + IOptions jT808ConfigurationAccessor, + IJT808Authorization authorization, + ILoggerFactory loggerFactory) + { + Logger = loggerFactory.CreateLogger(); + Configuration = jT808ConfigurationAccessor.Value; + MsgIdDefaultWebApiHandler = jT808MsgIdDefaultWebApiHandler; + this.authorization = authorization; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + if (!HttpListener.IsSupported) + { + Logger.LogWarning("Windows XP SP2 or Server 2003 is required to use the HttpListener class."); + return Task.CompletedTask; + } + listener = new HttpListener(); + listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; + try + { + listener.Prefixes.Add($"http://*:{Configuration.WebApiPort}/"); + listener.Start(); + } + catch (System.Net.HttpListenerException ex) + { + Logger.LogWarning(ex, $"{ex.Message}:使用cmd命令[netsh http add urlacl url=http://*:{Configuration.WebApiPort}/ user=Everyone]"); + } + Logger.LogInformation($"JT808 Http Server start at {IPAddress.Any}:{Configuration.WebApiPort}."); + Task.Factory.StartNew(async() => + { + while (listener.IsListening) + { + var context = await listener.GetContextAsync(); + try + { + if (authorization.Authorization(context,out var principal)) + { + await ProcessRequestAsync(context, principal); + } + else + { + await context.Http401(); + } + } + catch (Exception ex) + { + await context.Http500(); + Logger.LogError(ex, ex.StackTrace); + } + } + }, cancellationToken); + return Task.CompletedTask; + } + + private async ValueTask ProcessRequestAsync(HttpListenerContext context, IPrincipal principal) + { + if(context.Request.RawUrl.StartsWith("/favicon.ico")) + { + context.Http404(); + return; + } + var uri = new Uri(context.Request.RawUrl); + //todo: 处理对应的handler + string url = uri.AbsolutePath; + var queryParams = uri.Query.Substring(1, uri.Query.Length - 1).Split('&'); + if (queryParams.Length < 2) { + context.Http404(); + return; + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + try + { + listener.Stop(); + } + catch (System.ObjectDisposedException ex) + { + + } + catch (Exception ex) + { + + } + return Task.CompletedTask; + } + } +} diff --git a/src/JT808.Gateway/JT808TcpServer.cs b/src/JT808.Gateway/JT808TcpServer.cs index 5079f54..3d6e137 100644 --- a/src/JT808.Gateway/JT808TcpServer.cs +++ b/src/JT808.Gateway/JT808TcpServer.cs @@ -34,8 +34,6 @@ namespace JT808.Gateway private readonly JT808Serializer Serializer; - private readonly JT808AtomicCounterService AtomicCounterService; - private readonly JT808Configuration Configuration; private readonly JT808NormalReplyMessageHandler JT808NormalReplyMessageHandler; @@ -56,14 +54,12 @@ namespace JT808.Gateway IJT808Config jT808Config, ILoggerFactory loggerFactory, JT808SessionManager jT808SessionManager, - IJT808MsgProducer jT808MsgProducer, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) + IJT808MsgProducer jT808MsgProducer) { SessionManager = jT808SessionManager; Logger = loggerFactory.CreateLogger("JT808TcpServer"); Serializer = jT808Config.GetSerializer(); MsgProducer = jT808MsgProducer; - AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); Configuration = jT808ConfigurationAccessor.Value; JT808UseType = JT808UseType.Queue; InitServer(); @@ -82,14 +78,12 @@ namespace JT808.Gateway IJT808Config jT808Config, ILoggerFactory loggerFactory, JT808SessionManager jT808SessionManager, - JT808NormalReplyMessageHandler replyMessageHandler, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) + JT808NormalReplyMessageHandler replyMessageHandler) { SessionManager = jT808SessionManager; Logger = loggerFactory.CreateLogger("JT808TcpServer"); Serializer = jT808Config.GetSerializer(); JT808NormalReplyMessageHandler = replyMessageHandler; - AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); Configuration = jT808ConfigurationAccessor.Value; JT808UseType = JT808UseType.Normal; InitServer(); @@ -235,8 +229,6 @@ namespace JT808.Gateway if (contentSpan.Length > 14) { var package = Serializer.HeaderDeserialize(contentSpan, minBufferSize: 10240); - AtomicCounterService.MsgSuccessIncrement(); - if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug($"[Atomic Success Counter]:{AtomicCounterService.MsgSuccessCount}"); if (Logger.IsEnabled(LogLevel.Trace)) Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); SessionManager.TryLink(package.Header.TerminalPhoneNo, session); if(JT808UseType== JT808UseType.Normal) @@ -255,8 +247,6 @@ namespace JT808.Gateway } catch (JT808Exception ex) { - AtomicCounterService.MsgFailIncrement(); - if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{contentSpan.ToArray().ToHexString()}"); } totalConsumed += (seqReader.Consumed - totalConsumed); diff --git a/src/JT808.Gateway/JT808UdpServer.cs b/src/JT808.Gateway/JT808UdpServer.cs index 1a2ada1..8c40aab 100644 --- a/src/JT808.Gateway/JT808UdpServer.cs +++ b/src/JT808.Gateway/JT808UdpServer.cs @@ -34,8 +34,6 @@ namespace JT808.Gateway private readonly JT808Serializer Serializer; - private readonly JT808AtomicCounterService AtomicCounterService; - private readonly JT808Configuration Configuration; private readonly IPEndPoint LocalIPEndPoint; @@ -49,14 +47,12 @@ namespace JT808.Gateway IJT808Config jT808Config, ILoggerFactory loggerFactory, JT808SessionManager jT808SessionManager, - IJT808MsgProducer jT808MsgProducer, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) + IJT808MsgProducer jT808MsgProducer) { SessionManager = jT808SessionManager; Logger = loggerFactory.CreateLogger("JT808UdpServer"); Serializer = jT808Config.GetSerializer(); MsgProducer = jT808MsgProducer; - AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); Configuration = jT808ConfigurationAccessor.Value; JT808UseType = JT808UseType.Queue; LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); @@ -69,14 +65,12 @@ namespace JT808.Gateway IJT808Config jT808Config, ILoggerFactory loggerFactory, JT808SessionManager jT808SessionManager, - JT808NormalReplyMessageHandler replyMessageHandler, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) + JT808NormalReplyMessageHandler replyMessageHandler) { SessionManager = jT808SessionManager; Logger = loggerFactory.CreateLogger("JT808UdpServer"); Serializer = jT808Config.GetSerializer(); JT808NormalReplyMessageHandler = replyMessageHandler; - AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); Configuration = jT808ConfigurationAccessor.Value; JT808UseType = JT808UseType.Normal; LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); @@ -120,8 +114,6 @@ namespace JT808.Gateway try { var package = Serializer.HeaderDeserialize(buffer, minBufferSize: 10240); - AtomicCounterService.MsgSuccessIncrement(); - if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug($"[Atomic Success Counter]:{AtomicCounterService.MsgSuccessCount}"); if (Logger.IsEnabled(LogLevel.Trace)) Logger.LogTrace($"[Accept Hex {receiveMessageFromResult.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); var session = SessionManager.TryLink(package.Header.TerminalPhoneNo, socket, receiveMessageFromResult.RemoteEndPoint); if (Logger.IsEnabled(LogLevel.Information)) @@ -143,14 +135,11 @@ namespace JT808.Gateway } catch (JT808Exception ex) { - AtomicCounterService.MsgFailIncrement(); - if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{buffer.ToArray().ToHexString()}"); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) { - if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); Logger.LogError(ex, $"[ReaderBuffer]:{ buffer.ToArray().ToHexString()}"); } #pragma warning restore CA1031 // Do not catch general exception types diff --git a/src/JT808.Gateway/Services/JT808AtomicCounterService.cs b/src/JT808.Gateway/Services/JT808AtomicCounterService.cs deleted file mode 100644 index cddd31f..0000000 --- a/src/JT808.Gateway/Services/JT808AtomicCounterService.cs +++ /dev/null @@ -1,52 +0,0 @@ -using JT808.Gateway.Metadata; - -namespace JT808.Gateway.Services -{ - /// - /// 计数包服务 - /// - public class JT808AtomicCounterService - { - private readonly JT808AtomicCounter MsgSuccessCounter; - - private readonly JT808AtomicCounter MsgFailCounter; - - public JT808AtomicCounterService() - { - MsgSuccessCounter=new JT808AtomicCounter(); - MsgFailCounter = new JT808AtomicCounter(); - } - - public void Reset() - { - MsgSuccessCounter.Reset(); - MsgFailCounter.Reset(); - } - - public long MsgSuccessIncrement() - { - return MsgSuccessCounter.Increment(); - } - - public long MsgSuccessCount - { - get - { - return MsgSuccessCounter.Count; - } - } - - public long MsgFailIncrement() - { - return MsgFailCounter.Increment(); - } - - public long MsgFailCount - { - get - { - return MsgFailCounter.Count; - } - } - } -} diff --git a/src/JT808.Gateway/Services/JT808AtomicCounterServiceFactory.cs b/src/JT808.Gateway/Services/JT808AtomicCounterServiceFactory.cs deleted file mode 100644 index e4c9536..0000000 --- a/src/JT808.Gateway/Services/JT808AtomicCounterServiceFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -using JT808.Gateway.Abstractions.Enums; -using System; -using System.Collections.Concurrent; - -namespace JT808.Gateway.Services -{ - public class JT808AtomicCounterServiceFactory - { - private readonly ConcurrentDictionary cache; - - public JT808AtomicCounterServiceFactory() - { - cache = new ConcurrentDictionary(); - } - - public JT808AtomicCounterService Create(JT808TransportProtocolType type) - { - if(cache.TryGetValue(type,out var service)) - { - return service; - } - else - { - var serviceNew = new JT808AtomicCounterService(); - cache.TryAdd(type, serviceNew); - return serviceNew; - } - } - } -} diff --git a/src/JT808.Gateway/Services/JT808GatewayService.cs b/src/JT808.Gateway/Services/JT808GatewayService.cs deleted file mode 100644 index adcedcf..0000000 --- a/src/JT808.Gateway/Services/JT808GatewayService.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Linq; -using JT808.Gateway.GrpcService; -using Grpc.Core; -using System.Threading.Tasks; -using JT808.Gateway.Abstractions.Enums; -using JT808.Gateway.Session; -using Microsoft.Extensions.DependencyInjection; -using static Grpc.Core.Metadata; -using Microsoft.Extensions.Options; -using JT808.Gateway.Configurations; - -namespace JT808.Gateway.Services -{ - public class JT808GatewayService: JT808Gateway.JT808GatewayBase - { - private readonly JT808AtomicCounterService jT808TcpAtomicCounterService; - - private readonly JT808AtomicCounterService jT808UdpAtomicCounterService; - - private readonly JT808SessionManager jT808SessionManager; - - private readonly IOptionsMonitor ConfigurationOptionsMonitor; - - public JT808GatewayService( - IOptionsMonitor configurationOptionsMonitor, - JT808SessionManager jT808SessionManager, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory - ) - { - this.jT808SessionManager = jT808SessionManager; - this.ConfigurationOptionsMonitor = configurationOptionsMonitor; - this.jT808TcpAtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); - this.jT808UdpAtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); - } - - public JT808GatewayService(IServiceProvider serviceProvider) - { - this.jT808SessionManager = serviceProvider.GetRequiredService(); - this.jT808TcpAtomicCounterService = serviceProvider.GetRequiredService().Create(JT808TransportProtocolType.tcp); - this.jT808UdpAtomicCounterService = serviceProvider.GetRequiredService().Create(JT808TransportProtocolType.udp); - this.ConfigurationOptionsMonitor = serviceProvider.GetRequiredService>(); - } - - public override Task GetTcpSessionAll(Empty request, ServerCallContext context) - { - Auth(context); - var result = jT808SessionManager.GetTcpAll(); - TcpSessionInfoReply reply = new TcpSessionInfoReply(); - foreach (var item in result) - { - reply.TcpSessions.Add(new SessionInfo - { - LastActiveTime = item.ActiveTime.ToString("yyyy-MM-dd HH:mm:ss"), - StartTime = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"), - RemoteAddressIP = item.RemoteEndPoint.ToString(), - TerminalPhoneNo = item.TerminalPhoneNo - }); - } - return Task.FromResult(reply); - } - - public override Task GetTcpSessionByTerminalPhoneNo(SessionRequest request, ServerCallContext context) - { - Auth(context); - var result = jT808SessionManager.GetTcpAll().FirstOrDefault(f=>f.TerminalPhoneNo==request.TerminalPhoneNo); - SessionInfo sessionInfo = new SessionInfo(); - if (result != null) - { - sessionInfo.LastActiveTime = result.ActiveTime.ToString("yyyy-MM-dd HH:mm:ss"); - sessionInfo.StartTime = result.StartTime.ToString("yyyy-MM-dd HH:mm:ss"); - sessionInfo.RemoteAddressIP = result.RemoteEndPoint.ToString(); - sessionInfo.TerminalPhoneNo = result.TerminalPhoneNo; - return Task.FromResult(sessionInfo); - } - else - { - throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, $"{request.TerminalPhoneNo} not exists")); - } - } - - public override Task GetTcpSessionCount(Empty request, ServerCallContext context) - { - Auth(context); - return Task.FromResult(new SessionCountReply - { - Count = jT808SessionManager.TcpSessionCount - }); - } - - public override Task RemoveSessionByTerminalPhoneNo(SessionRemoveRequest request, ServerCallContext context) - { - Auth(context); - try - { - jT808SessionManager.RemoveByTerminalPhoneNo(request.TerminalPhoneNo); - return Task.FromResult(new SessionRemoveReply { Success = true }); - } - catch (Exception) - { - return Task.FromResult(new SessionRemoveReply { Success = false }); - } - } - - public override Task GetUdpSessionAll(Empty request, ServerCallContext context) - { - Auth(context); - var result = jT808SessionManager.GetUdpAll(); - UdpSessionInfoReply reply = new UdpSessionInfoReply(); - foreach (var item in result) - { - reply.UdpSessions.Add(new SessionInfo - { - LastActiveTime = item.ActiveTime.ToString("yyyy-MM-dd HH:mm:ss"), - StartTime = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"), - RemoteAddressIP = item.RemoteEndPoint.ToString(), - TerminalPhoneNo = item.TerminalPhoneNo - }); - } - - return Task.FromResult(reply); - } - - public override async Task UnificationSend(UnificationSendRequest request, ServerCallContext context) - { - Auth(context); - try - { - var flag = await jT808SessionManager.TrySendByTerminalPhoneNoAsync(request.TerminalPhoneNo, request.Data.ToByteArray()); - return new UnificationSendReply { Success = flag }; - } - catch (Exception) - { - return new UnificationSendReply { Success = false }; - } - } - - public override Task GetTcpAtomicCounter(Empty request, ServerCallContext context) - { - Auth(context); - TcpAtomicCounterReply reply = new TcpAtomicCounterReply(); - reply.MsgFailCount=jT808TcpAtomicCounterService.MsgFailCount; - reply.MsgSuccessCount=jT808TcpAtomicCounterService.MsgSuccessCount; - return Task.FromResult(reply); - } - - public override Task GetUdpAtomicCounter(Empty request, ServerCallContext context) - { - Auth(context); - UdpAtomicCounterReply reply = new UdpAtomicCounterReply(); - reply.MsgFailCount = jT808UdpAtomicCounterService.MsgFailCount; - reply.MsgSuccessCount = jT808UdpAtomicCounterService.MsgSuccessCount; - return Task.FromResult(reply); - } - - private void Auth(ServerCallContext context) - { - Entry tokenEntry = context.RequestHeaders.FirstOrDefault(w => w.Key == "token"); - if (tokenEntry != null) - { - if(tokenEntry.Value != ConfigurationOptionsMonitor.CurrentValue.WebApiToken) - { - throw new Grpc.Core.RpcException(new Status(StatusCode.Unauthenticated, "token error")); - } - } - else - { - throw new Grpc.Core.RpcException(new Status(StatusCode.Unauthenticated,"token empty")); - } - } - } -}