@@ -0,0 +1,15 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.Gateway.Abstractions.Dtos | |||||
{ | |||||
public class JT808DefaultResultDto: JT808ResultDto<string> | |||||
{ | |||||
public JT808DefaultResultDto() | |||||
{ | |||||
Data = "Hello,JT808 WebAPI"; | |||||
Code = JT808ResultCode.Ok; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.Gateway.Abstractions.Dtos | |||||
{ | |||||
public class JT808ResultDto<T> | |||||
{ | |||||
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; | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
using System; | |||||
namespace JT808.Gateway.Abstractions.Dtos | |||||
{ | |||||
public class JT808TcpSessionInfoDto | |||||
{ | |||||
/// <summary> | |||||
/// 最后上线时间 | |||||
/// </summary> | |||||
public DateTime LastActiveTime { get; set; } | |||||
/// <summary> | |||||
/// 上线时间 | |||||
/// </summary> | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | |||||
/// 终端手机号 | |||||
/// </summary> | |||||
public string TerminalPhoneNo { get; set; } | |||||
/// <summary> | |||||
/// 远程ip地址 | |||||
/// </summary> | |||||
public string RemoteAddressIP { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
using System; | |||||
namespace JT808.Gateway.Abstractions.Dtos | |||||
{ | |||||
public class JT808UdpSessionInfoDto | |||||
{ | |||||
/// <summary> | |||||
/// 最后上线时间 | |||||
/// </summary> | |||||
public DateTime LastActiveTime { get; set; } | |||||
/// <summary> | |||||
/// 上线时间 | |||||
/// </summary> | |||||
public DateTime StartTime { get; set; } | |||||
/// <summary> | |||||
/// 终端手机号 | |||||
/// </summary> | |||||
public string TerminalPhoneNo { get; set; } | |||||
/// <summary> | |||||
/// 远程ip地址 | |||||
/// </summary> | |||||
public string RemoteAddressIP { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
namespace JT808.Gateway.Abstractions.Dtos | |||||
{ | |||||
/// <summary> | |||||
/// 统一下发请求参数 | |||||
/// </summary> | |||||
public class JT808UnificationSendRequestDto | |||||
{ | |||||
public string TerminalPhoneNo { get; set; } | |||||
public string Data { get; set; } | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -26,17 +26,8 @@ | |||||
<DocumentationFile>JT808.Gateway.Abstractions.xml</DocumentationFile> | <DocumentationFile>JT808.Gateway.Abstractions.xml</DocumentationFile> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Protobuf Include="Protos\JT808Gateway.proto" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Google.Protobuf" Version="3.11.4" /> | |||||
<PackageReference Include="Grpc.Core" Version="2.28.1" /> | |||||
<PackageReference Include="Grpc.Tools" Version="2.28.1"> | |||||
<PrivateAssets>all</PrivateAssets> | |||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||||
</PackageReference> | |||||
<PackageReference Include="JT808" Version="2.2.10" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="JT808" Version="2.2.12" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -7,5 +7,44 @@ | |||||
public const string SessionTopic = "jt808session"; | public const string SessionTopic = "jt808session"; | ||||
public const string MsgTopic = "jt808msgdefault"; | public const string MsgTopic = "jt808msgdefault"; | ||||
public const string MsgReplyTopic = "jt808msgreplydefault"; | 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"; | |||||
/// <summary> | |||||
/// 基于Tcp的会话服务集合 | |||||
/// </summary> | |||||
public static string SessionTcpGetAll = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/GetAll"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
public static string SessionRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/RemoveByTerminalPhoneNo"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号查询对应会话 | |||||
/// </summary> | |||||
public static string QueryTcpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/QueryTcpSessionByTerminalPhoneNo"; | |||||
/// <summary> | |||||
/// 统一下发信息 | |||||
/// </summary> | |||||
public static string UnificationSend = $"{RouteTablePrefix}/UnificationSend"; | |||||
/// <summary> | |||||
/// 基于Udp的虚拟会话服务集合 | |||||
/// </summary> | |||||
public static string SessionUdpGetAll = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/GetAll"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
public static string RemoveUdpByTerminalPhoneNo = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/RemoveUdpByTerminalPhoneNo"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号查询对应会话 | |||||
/// </summary> | |||||
public static string QueryUdpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/QueryUdpSessionByTerminalPhoneNo"; | |||||
} | |||||
} | } | ||||
} | } |
@@ -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<string, Func<string,byte[]>> HandlerDict { get; } | |||||
/// <summary> | |||||
/// 初始化消息处理业务 | |||||
/// </summary> | |||||
protected JT808MsgIdHttpHandlerBase() | |||||
{ | |||||
HandlerDict = new Dictionary<string, Func<string, byte[]>>(); | |||||
} | |||||
protected void CreateRoute(string url, Func<string, byte[]> 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<string>() | |||||
{ | |||||
Code = JT808ResultCode.Empty, | |||||
Message = "内容为空", | |||||
Data = "Content Empty" | |||||
}); | |||||
return json; | |||||
} | |||||
public byte[] NotFoundHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.NotFound, | |||||
Message = "没有该服务", | |||||
Data = "没有该服务" | |||||
}); | |||||
return json; | |||||
} | |||||
public byte[] AuthFailHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.AuthFail, | |||||
Message = "token认证失败", | |||||
Data = "token认证失败" | |||||
}); | |||||
return json; | |||||
} | |||||
public byte[] ErrorHttpResponse(Exception ex) | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.Error, | |||||
Message = ex.StackTrace, | |||||
Data = ex.Message | |||||
}); | |||||
return json; | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -12,11 +12,11 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.3" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -6,10 +6,10 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | ||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.3" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -22,12 +22,12 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="JT808" Version="2.2.10" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="JT808" Version="2.2.12" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | <PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | ||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -15,8 +15,11 @@ using Microsoft.Extensions.DependencyInjection; | |||||
namespace JT808.Gateway.Client | namespace JT808.Gateway.Client | ||||
{ | { | ||||
public class JT808TcpClient:IDisposable | public class JT808TcpClient:IDisposable | ||||
{ | { | ||||
//todo: 客户端的断线重连 | |||||
//todo: 客户端的消息处理handler | |||||
private bool disposed = false; | private bool disposed = false; | ||||
private Socket clientSocket; | private Socket clientSocket; | ||||
private readonly ILogger Logger; | private readonly ILogger Logger; | ||||
@@ -20,12 +20,12 @@ | |||||
<Version>$(JT808GatewayPackageVersion)</Version> | <Version>$(JT808GatewayPackageVersion)</Version> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Confluent.Kafka" Version="1.4.2" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Confluent.Kafka" Version="1.5.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -22,7 +22,7 @@ | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -21,7 +21,7 @@ | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -22,7 +22,7 @@ | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -22,7 +22,7 @@ | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | <None Include="..\..\..\LICENSE" Pack="true" PackagePath="" /> | ||||
@@ -5,12 +5,16 @@ | |||||
<TargetFramework>netcoreapp3.1</TargetFramework> | <TargetFramework>netcoreapp3.1</TargetFramework> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<Compile Remove="Jobs\CallGrpcClientJob.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | ||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.3" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -60,7 +60,6 @@ namespace JT808.Gateway.NormalHosting | |||||
.AddTransmit(hostContext.Configuration) | .AddTransmit(hostContext.Configuration) | ||||
.AddTcp() | .AddTcp() | ||||
.AddUdp() | .AddUdp() | ||||
.AddGrpc() | |||||
; | ; | ||||
//流量统计 | //流量统计 | ||||
services.AddHostedService<TrafficJob>(); | services.AddHostedService<TrafficJob>(); | ||||
@@ -6,10 +6,14 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<Compile Remove="Jobs\CallGrpcClientJob.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" /> | ||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.3" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -52,7 +52,6 @@ namespace JT808.Gateway.QueueHosting | |||||
.AddServerKafkaMsgReplyConsumer(hostContext.Configuration) | .AddServerKafkaMsgReplyConsumer(hostContext.Configuration) | ||||
.AddTcp() | .AddTcp() | ||||
.AddUdp() | .AddUdp() | ||||
.AddGrpc() | |||||
.Builder() | .Builder() | ||||
//添加客户端工具 | //添加客户端工具 | ||||
.AddClient() | .AddClient() | ||||
@@ -7,15 +7,15 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> | |||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | <PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | ||||
<PackageReference Include="xunit" Version="2.4.1" /> | <PackageReference Include="xunit" Version="2.4.1" /> | ||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | |||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
</PackageReference> | </PackageReference> | ||||
<PackageReference Include="coverlet.collector" Version="1.2.1"> | |||||
<PackageReference Include="coverlet.collector" Version="1.3.0"> | |||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
</PackageReference> | </PackageReference> | ||||
@@ -0,0 +1,34 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<Import Project="..\Version.props" /> | |||||
<PropertyGroup> | |||||
<TargetFramework>netstandard2.1</TargetFramework> | |||||
<LangVersion>8.0</LangVersion> | |||||
<Copyright>Copyright 2019.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<RepositoryUrl>https://github.com/SmallChi/JT808Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT808Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<Version>$(JT808GatewayPackageVersion)</Version> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<PackageId>JT808.Gateway.WebApiClientTool</PackageId> | |||||
<Product>JT808.Gateway.WebApiClientTool</Product> | |||||
<Description>基于Pipeline的WebApiClient客户端调用工具</Description> | |||||
<PackageReleaseNotes>基于Pipeline的WebApiClient客户端调用工具</PackageReleaseNotes> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||||
<DocumentationFile>JT808.Gateway.WebApiClientTool.xml</DocumentationFile> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.7" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\JT808.Gateway.Abstractions\JT808.Gateway.Abstractions.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -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; | |||||
} | |||||
/// <summary> | |||||
/// 会话服务集合 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
public async ValueTask<JT808ResultDto<List<JT808TcpSessionInfoDto>>> 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<JT808ResultDto<List<JT808TcpSessionInfoDto>>>(data); | |||||
return value; | |||||
} | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
/// <param name="terminalPhoneNo"></param> | |||||
/// <returns></returns> | |||||
public async ValueTask<JT808ResultDto<bool>> 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<JT808ResultDto<bool>>(data); | |||||
return value; | |||||
} | |||||
/// <summary> | |||||
/// 统一下发信息 | |||||
/// </summary> | |||||
/// <param name="jT808UnificationSendRequestDto"></param> | |||||
/// <returns></returns> | |||||
public async ValueTask<JT808ResultDto<bool>> 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<JT808ResultDto<bool>>(data); | |||||
return value; | |||||
} | |||||
/// <summary> | |||||
/// 会话服务集合 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
public async ValueTask<JT808ResultDto<List<JT808UdpSessionInfoDto>>> 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<JT808ResultDto<List<JT808UdpSessionInfoDto>>>(data); | |||||
return value; | |||||
} | |||||
} | |||||
} |
@@ -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<JT808HttpClient>(); | |||||
return serviceDescriptors; | |||||
} | |||||
public static IServiceCollection AddJT808WebApiClientTool(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.AddHttpClient("JT808WebApiClientTool", c => | |||||
{ | |||||
c.BaseAddress = new Uri(configuration.GetSection("JT808WebApiClientToolConfig").Get<string>()); | |||||
c.Timeout = TimeSpan.FromSeconds(3); | |||||
}) | |||||
.AddTypedClient<JT808HttpClient>(); | |||||
return serviceDescriptors; | |||||
} | |||||
} | |||||
} |
@@ -21,8 +21,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ReplyMessage" | |||||
EndProject | 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}" | 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 | 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}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Client", "JT808.Gateway.Client\JT808.Gateway.Client.csproj", "{AC3070AC-A938-4213-A562-C079BB4A3F9E}" | ||||
EndProject | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{7CBAACEE-19BF-499A-8C41-36A1324D45E9}" | 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 | 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}" | 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 | 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 | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | 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}.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.ActiveCfg = Release|Any CPU | ||||
{598E445A-AF2E-42F0-98F4-18EC22E473FC}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU | ||||
{AC3070AC-A938-4213-A562-C079BB4A3F9E}.Debug|Any CPU.Build.0 = 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 | {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}.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.ActiveCfg = Release|Any CPU | ||||
{AF0C529A-D3CA-4FE4-93B4-735D0934EBEF}.Release|Any CPU.Build.0 = 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 | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -115,12 +121,12 @@ Global | |||||
{1CB84599-5F56-4461-A451-DF16E3854AB9} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} | {1CB84599-5F56-4461-A451-DF16E3854AB9} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} | ||||
{604BB5CF-9ED1-4D78-9328-59436E2B4EB4} = {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} | {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} | {E3DC260E-0B55-4993-B051-402E44D4E883} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} | ||||
{22368AAD-A1F3-446B-B68F-98A0933BF1F6} = {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} | {52D895BD-C60B-42D8-9229-C85927546FDA} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} | ||||
{E34C6B7D-A48B-4871-895C-07AC12F959D3} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} | {E34C6B7D-A48B-4871-895C-07AC12F959D3} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} | ||||
{AF0C529A-D3CA-4FE4-93B4-735D0934EBEF} = {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 | EndGlobalSection | ||||
GlobalSection(ExtensibilityGlobals) = postSolution | GlobalSection(ExtensibilityGlobals) = postSolution | ||||
SolutionGuid = {AA9303A7-6FB3-4572-88AA-3302E85330D1} | SolutionGuid = {AA9303A7-6FB3-4572-88AA-3302E85330D1} | ||||
@@ -9,7 +9,6 @@ namespace JT808.Gateway.Configurations | |||||
public int TcpPort { get; set; } = 808; | public int TcpPort { get; set; } = 808; | ||||
public int UdpPort { get; set; } = 808; | public int UdpPort { get; set; } = 808; | ||||
public int WebApiPort { get; set; } = 828; | public int WebApiPort { get; set; } = 828; | ||||
public string WebApiHost{ get; set; } = "localhost"; | |||||
/// <summary> | /// <summary> | ||||
/// WebApi 默认token 123456 | /// WebApi 默认token 123456 | ||||
/// </summary> | /// </summary> | ||||
@@ -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<byte> 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(); | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 默认消息处理业务实现 | |||||
/// </summary> | |||||
public class JT808MsgIdDefaultWebApiHandler : JT808MsgIdHttpHandlerBase | |||||
{ | |||||
private JT808SessionManager JT808SessionManager; | |||||
public JT808MsgIdDefaultWebApiHandler(JT808SessionManager jT808SessionManager) | |||||
{ | |||||
this.JT808SessionManager = jT808SessionManager; | |||||
InitTcpRoute(); | |||||
InitUdpRoute(); | |||||
InitCommontRoute(); | |||||
} | |||||
/// <summary> | |||||
/// 会话服务集合 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] GetTcpSessionAll(string json) | |||||
{ | |||||
JT808ResultDto<List<JT808TcpSessionInfoDto>> resultDto = new JT808ResultDto<List<JT808TcpSessionInfoDto>>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 通过终端手机号查询对应会话 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] QueryTcpSessionByTerminalPhoneNo(string json) | |||||
{ | |||||
if (string.IsNullOrEmpty(json)) | |||||
{ | |||||
return EmptyHttpResponse(); | |||||
} | |||||
JT808ResultDto<JT808TcpSessionInfoDto> resultDto = new JT808ResultDto<JT808TcpSessionInfoDto>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] RemoveSessionByTerminalPhoneNo(string json) | |||||
{ | |||||
if (string.IsNullOrEmpty(json)) | |||||
{ | |||||
return EmptyHttpResponse(); | |||||
} | |||||
JT808ResultDto<bool> resultDto = new JT808ResultDto<bool>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 会话服务集合 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] GetUdpSessionAll(string json) | |||||
{ | |||||
JT808ResultDto<List<JT808UdpSessionInfoDto>> resultDto = new JT808ResultDto<List<JT808UdpSessionInfoDto>>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 通过终端手机号查询对应会话 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] QueryUdpSessionByTerminalPhoneNo(string json) | |||||
{ | |||||
if (string.IsNullOrEmpty(json)) | |||||
{ | |||||
return EmptyHttpResponse(); | |||||
} | |||||
JT808ResultDto<JT808UdpSessionInfoDto> resultDto = new JT808ResultDto<JT808UdpSessionInfoDto>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] RemoveUdpByTerminalPhoneNo(string json) | |||||
{ | |||||
if (string.IsNullOrEmpty(json)) | |||||
{ | |||||
return EmptyHttpResponse(); | |||||
} | |||||
JT808ResultDto<bool> resultDto = new JT808ResultDto<bool>(); | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 统一下发信息 | |||||
/// </summary> | |||||
/// <param name="json"></param> | |||||
/// <returns></returns> | |||||
public byte[] UnificationSend(string json) | |||||
{ | |||||
if (string.IsNullOrEmpty(json)) | |||||
{ | |||||
return EmptyHttpResponse(); | |||||
} | |||||
JT808ResultDto<bool> resultDto = new JT808ResultDto<bool>(); | |||||
try | |||||
{ | |||||
JT808UnificationSendRequestDto jT808UnificationSendRequestDto = JsonSerializer.Deserialize<JT808UnificationSendRequestDto>(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); | |||||
} | |||||
} | |||||
} |
@@ -21,8 +21,8 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.7" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.7" /> | |||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | <PackageReference Include="System.IO.Pipelines" Version="4.7.2" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -1,6 +1,7 @@ | |||||
using JT808.Gateway.Abstractions; | using JT808.Gateway.Abstractions; | ||||
using JT808.Gateway.Configurations; | using JT808.Gateway.Configurations; | ||||
using JT808.Gateway.Enums; | using JT808.Gateway.Enums; | ||||
using JT808.Gateway.Handlers; | |||||
using JT808.Gateway.Internal; | using JT808.Gateway.Internal; | ||||
using JT808.Gateway.Services; | using JT808.Gateway.Services; | ||||
using JT808.Gateway.Session; | using JT808.Gateway.Session; | ||||
@@ -74,15 +75,23 @@ namespace JT808.Gateway | |||||
return config; | return config; | ||||
} | } | ||||
public static IJT808GatewayBuilder AddGrpc(this IJT808GatewayBuilder config) | |||||
public static IJT808GatewayBuilder AddHttp(this IJT808GatewayBuilder config) | |||||
{ | { | ||||
config.JT808Builder.Services.AddHostedService<JT808GrpcServer>(); | |||||
config.JT808Builder.Services.AddSingleton<JT808MsgIdDefaultWebApiHandler>(); | |||||
config.JT808Builder.Services.AddHostedService<JT808HttpServer>(); | |||||
return config; | |||||
} | |||||
public static IJT808GatewayBuilder AddHttp<TJT808MsgIdDefaultWebApiHandler>(this IJT808GatewayBuilder config) | |||||
where TJT808MsgIdDefaultWebApiHandler: JT808MsgIdDefaultWebApiHandler | |||||
{ | |||||
config.JT808Builder.Services.AddSingleton(typeof(JT808MsgIdDefaultWebApiHandler),typeof(TJT808MsgIdDefaultWebApiHandler)); | |||||
config.JT808Builder.Services.AddHostedService<JT808HttpServer>(); | |||||
return config; | return config; | ||||
} | } | ||||
private static IJT808GatewayBuilder AddJT808Core(this IJT808GatewayBuilder config) | private static IJT808GatewayBuilder AddJT808Core(this IJT808GatewayBuilder config) | ||||
{ | { | ||||
config.JT808Builder.Services.TryAddSingleton<JT808AtomicCounterServiceFactory>(); | |||||
config.JT808Builder.Services.TryAddSingleton<JT808SessionManager>(); | config.JT808Builder.Services.TryAddSingleton<JT808SessionManager>(); | ||||
return config; | return config; | ||||
} | } | ||||
@@ -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<JT808Configuration> 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; | |||||
} | |||||
} | |||||
} |
@@ -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<JT808Configuration> jT808ConfigurationAccessor, | |||||
IJT808Authorization authorization, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
Logger = loggerFactory.CreateLogger<JT808HttpServer>(); | |||||
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; | |||||
} | |||||
} | |||||
} |
@@ -34,8 +34,6 @@ namespace JT808.Gateway | |||||
private readonly JT808Serializer Serializer; | private readonly JT808Serializer Serializer; | ||||
private readonly JT808AtomicCounterService AtomicCounterService; | |||||
private readonly JT808Configuration Configuration; | private readonly JT808Configuration Configuration; | ||||
private readonly JT808NormalReplyMessageHandler JT808NormalReplyMessageHandler; | private readonly JT808NormalReplyMessageHandler JT808NormalReplyMessageHandler; | ||||
@@ -56,14 +54,12 @@ namespace JT808.Gateway | |||||
IJT808Config jT808Config, | IJT808Config jT808Config, | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
JT808SessionManager jT808SessionManager, | JT808SessionManager jT808SessionManager, | ||||
IJT808MsgProducer jT808MsgProducer, | |||||
JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) | |||||
IJT808MsgProducer jT808MsgProducer) | |||||
{ | { | ||||
SessionManager = jT808SessionManager; | SessionManager = jT808SessionManager; | ||||
Logger = loggerFactory.CreateLogger("JT808TcpServer"); | Logger = loggerFactory.CreateLogger("JT808TcpServer"); | ||||
Serializer = jT808Config.GetSerializer(); | Serializer = jT808Config.GetSerializer(); | ||||
MsgProducer = jT808MsgProducer; | MsgProducer = jT808MsgProducer; | ||||
AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); | |||||
Configuration = jT808ConfigurationAccessor.Value; | Configuration = jT808ConfigurationAccessor.Value; | ||||
JT808UseType = JT808UseType.Queue; | JT808UseType = JT808UseType.Queue; | ||||
InitServer(); | InitServer(); | ||||
@@ -82,14 +78,12 @@ namespace JT808.Gateway | |||||
IJT808Config jT808Config, | IJT808Config jT808Config, | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
JT808SessionManager jT808SessionManager, | JT808SessionManager jT808SessionManager, | ||||
JT808NormalReplyMessageHandler replyMessageHandler, | |||||
JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) | |||||
JT808NormalReplyMessageHandler replyMessageHandler) | |||||
{ | { | ||||
SessionManager = jT808SessionManager; | SessionManager = jT808SessionManager; | ||||
Logger = loggerFactory.CreateLogger("JT808TcpServer"); | Logger = loggerFactory.CreateLogger("JT808TcpServer"); | ||||
Serializer = jT808Config.GetSerializer(); | Serializer = jT808Config.GetSerializer(); | ||||
JT808NormalReplyMessageHandler = replyMessageHandler; | JT808NormalReplyMessageHandler = replyMessageHandler; | ||||
AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); | |||||
Configuration = jT808ConfigurationAccessor.Value; | Configuration = jT808ConfigurationAccessor.Value; | ||||
JT808UseType = JT808UseType.Normal; | JT808UseType = JT808UseType.Normal; | ||||
InitServer(); | InitServer(); | ||||
@@ -235,8 +229,6 @@ namespace JT808.Gateway | |||||
if (contentSpan.Length > 14) | if (contentSpan.Length > 14) | ||||
{ | { | ||||
var package = Serializer.HeaderDeserialize(contentSpan, minBufferSize: 10240); | 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()}"); | if (Logger.IsEnabled(LogLevel.Trace)) Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); | ||||
SessionManager.TryLink(package.Header.TerminalPhoneNo, session); | SessionManager.TryLink(package.Header.TerminalPhoneNo, session); | ||||
if(JT808UseType== JT808UseType.Normal) | if(JT808UseType== JT808UseType.Normal) | ||||
@@ -255,8 +247,6 @@ namespace JT808.Gateway | |||||
} | } | ||||
catch (JT808Exception ex) | 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()}"); | Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{contentSpan.ToArray().ToHexString()}"); | ||||
} | } | ||||
totalConsumed += (seqReader.Consumed - totalConsumed); | totalConsumed += (seqReader.Consumed - totalConsumed); | ||||
@@ -34,8 +34,6 @@ namespace JT808.Gateway | |||||
private readonly JT808Serializer Serializer; | private readonly JT808Serializer Serializer; | ||||
private readonly JT808AtomicCounterService AtomicCounterService; | |||||
private readonly JT808Configuration Configuration; | private readonly JT808Configuration Configuration; | ||||
private readonly IPEndPoint LocalIPEndPoint; | private readonly IPEndPoint LocalIPEndPoint; | ||||
@@ -49,14 +47,12 @@ namespace JT808.Gateway | |||||
IJT808Config jT808Config, | IJT808Config jT808Config, | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
JT808SessionManager jT808SessionManager, | JT808SessionManager jT808SessionManager, | ||||
IJT808MsgProducer jT808MsgProducer, | |||||
JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) | |||||
IJT808MsgProducer jT808MsgProducer) | |||||
{ | { | ||||
SessionManager = jT808SessionManager; | SessionManager = jT808SessionManager; | ||||
Logger = loggerFactory.CreateLogger("JT808UdpServer"); | Logger = loggerFactory.CreateLogger("JT808UdpServer"); | ||||
Serializer = jT808Config.GetSerializer(); | Serializer = jT808Config.GetSerializer(); | ||||
MsgProducer = jT808MsgProducer; | MsgProducer = jT808MsgProducer; | ||||
AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); | |||||
Configuration = jT808ConfigurationAccessor.Value; | Configuration = jT808ConfigurationAccessor.Value; | ||||
JT808UseType = JT808UseType.Queue; | JT808UseType = JT808UseType.Queue; | ||||
LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); | LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); | ||||
@@ -69,14 +65,12 @@ namespace JT808.Gateway | |||||
IJT808Config jT808Config, | IJT808Config jT808Config, | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
JT808SessionManager jT808SessionManager, | JT808SessionManager jT808SessionManager, | ||||
JT808NormalReplyMessageHandler replyMessageHandler, | |||||
JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory) | |||||
JT808NormalReplyMessageHandler replyMessageHandler) | |||||
{ | { | ||||
SessionManager = jT808SessionManager; | SessionManager = jT808SessionManager; | ||||
Logger = loggerFactory.CreateLogger("JT808UdpServer"); | Logger = loggerFactory.CreateLogger("JT808UdpServer"); | ||||
Serializer = jT808Config.GetSerializer(); | Serializer = jT808Config.GetSerializer(); | ||||
JT808NormalReplyMessageHandler = replyMessageHandler; | JT808NormalReplyMessageHandler = replyMessageHandler; | ||||
AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); | |||||
Configuration = jT808ConfigurationAccessor.Value; | Configuration = jT808ConfigurationAccessor.Value; | ||||
JT808UseType = JT808UseType.Normal; | JT808UseType = JT808UseType.Normal; | ||||
LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); | LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, Configuration.UdpPort); | ||||
@@ -120,8 +114,6 @@ namespace JT808.Gateway | |||||
try | try | ||||
{ | { | ||||
var package = Serializer.HeaderDeserialize(buffer, minBufferSize: 10240); | 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()}"); | 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); | var session = SessionManager.TryLink(package.Header.TerminalPhoneNo, socket, receiveMessageFromResult.RemoteEndPoint); | ||||
if (Logger.IsEnabled(LogLevel.Information)) | if (Logger.IsEnabled(LogLevel.Information)) | ||||
@@ -143,14 +135,11 @@ namespace JT808.Gateway | |||||
} | } | ||||
catch (JT808Exception ex) | 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()}"); | Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{buffer.ToArray().ToHexString()}"); | ||||
} | } | ||||
#pragma warning disable CA1031 // Do not catch general exception types | #pragma warning disable CA1031 // Do not catch general exception types | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); | |||||
Logger.LogError(ex, $"[ReaderBuffer]:{ buffer.ToArray().ToHexString()}"); | Logger.LogError(ex, $"[ReaderBuffer]:{ buffer.ToArray().ToHexString()}"); | ||||
} | } | ||||
#pragma warning restore CA1031 // Do not catch general exception types | #pragma warning restore CA1031 // Do not catch general exception types | ||||
@@ -1,52 +0,0 @@ | |||||
using JT808.Gateway.Metadata; | |||||
namespace JT808.Gateway.Services | |||||
{ | |||||
/// <summary> | |||||
/// 计数包服务 | |||||
/// </summary> | |||||
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; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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<JT808TransportProtocolType, JT808AtomicCounterService> cache; | |||||
public JT808AtomicCounterServiceFactory() | |||||
{ | |||||
cache = new ConcurrentDictionary<JT808TransportProtocolType, JT808AtomicCounterService>(); | |||||
} | |||||
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; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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<JT808Configuration> ConfigurationOptionsMonitor; | |||||
public JT808GatewayService( | |||||
IOptionsMonitor<JT808Configuration> 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<JT808SessionManager>(); | |||||
this.jT808TcpAtomicCounterService = serviceProvider.GetRequiredService<JT808AtomicCounterServiceFactory>().Create(JT808TransportProtocolType.tcp); | |||||
this.jT808UdpAtomicCounterService = serviceProvider.GetRequiredService<JT808AtomicCounterServiceFactory>().Create(JT808TransportProtocolType.udp); | |||||
this.ConfigurationOptionsMonitor = serviceProvider.GetRequiredService<IOptionsMonitor<JT808Configuration>>(); | |||||
} | |||||
public override Task<TcpSessionInfoReply> 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<SessionInfo> 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<SessionCountReply> GetTcpSessionCount(Empty request, ServerCallContext context) | |||||
{ | |||||
Auth(context); | |||||
return Task.FromResult(new SessionCountReply | |||||
{ | |||||
Count = jT808SessionManager.TcpSessionCount | |||||
}); | |||||
} | |||||
public override Task<SessionRemoveReply> 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<UdpSessionInfoReply> 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<UnificationSendReply> 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<TcpAtomicCounterReply> 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<UdpAtomicCounterReply> 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")); | |||||
} | |||||
} | |||||
} | |||||
} |