Browse Source

1.调整grpc测试

2.将业务整合进新网关库中
tags/v2.2.1
smallchi 5 years ago
parent
commit
8e76fab0bf
98 changed files with 6387 additions and 373 deletions
  1. +6
    -6
      README.md
  2. +19
    -0
      src/JT808.Gateway.CleintBenchmark/Configs/ClientBenchmarkOptions.cs
  3. +3106
    -0
      src/JT808.Gateway.CleintBenchmark/Configs/NLog.xsd
  4. +36
    -0
      src/JT808.Gateway.CleintBenchmark/Configs/nlog.unix.config
  5. +35
    -0
      src/JT808.Gateway.CleintBenchmark/Configs/nlog.win.config
  6. +33
    -0
      src/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj
  7. +51
    -0
      src/JT808.Gateway.CleintBenchmark/Program.cs
  8. +82
    -0
      src/JT808.Gateway.CleintBenchmark/Services/CleintBenchmarkHostedService.cs
  9. +53
    -0
      src/JT808.Gateway.CleintBenchmark/Services/CleintBenchmarkReportHostedService.cs
  10. +15
    -0
      src/JT808.Gateway.Kafka/Configs/JT808ConsumerConfig.cs
  11. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808MsgConsumerConfig.cs
  12. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808MsgProducerConfig.cs
  13. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808MsgReplyConsumerConfig.cs
  14. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808MsgReplyProducerConfig.cs
  15. +15
    -0
      src/JT808.Gateway.Kafka/Configs/JT808ProducerConfig.cs
  16. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808SessionConsumerConfig.cs
  17. +13
    -0
      src/JT808.Gateway.Kafka/Configs/JT808SessionProducerConfig.cs
  18. +39
    -0
      src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj
  19. +24
    -0
      src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs
  20. +66
    -0
      src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs
  21. +82
    -0
      src/JT808.Gateway.Kafka/JT808MsgConsumer.cs
  22. +38
    -0
      src/JT808.Gateway.Kafka/JT808MsgProducer.cs
  23. +82
    -0
      src/JT808.Gateway.Kafka/JT808MsgReplyConsumer.cs
  24. +38
    -0
      src/JT808.Gateway.Kafka/JT808MsgReplyProducer.cs
  25. +48
    -0
      src/JT808.Gateway.Kafka/JT808ServerKafkaExtensions.cs
  26. +82
    -0
      src/JT808.Gateway.Kafka/JT808SessionConsumer.cs
  27. +38
    -0
      src/JT808.Gateway.Kafka/JT808SessionProducer.cs
  28. +8
    -2
      src/JT808.Gateway.SimpleClient/Program.cs
  29. +3
    -3
      src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs
  30. BIN
      src/JT808.Gateway.SimpleServer/Configs/test.cer
  31. +3
    -0
      src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj
  32. +10
    -9
      src/JT808.Gateway.SimpleServer/Program.cs
  33. +24
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/JT808.Gateway.MsgIdHandler.Test.csproj
  34. +44
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs
  35. +39
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/Program.cs
  36. +25
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/JT808.Gateway.MsgLogging.Test.csproj
  37. +52
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/JT808MsgLoggingImpl.cs
  38. +43
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/Program.cs
  39. +25
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/JT808.Gateway.ReplyMessage.Test.csproj
  40. +48
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs
  41. +42
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/Program.cs
  42. +24
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/JT808.Gateway.SessionNotice.Test.csproj
  43. +41
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs
  44. +41
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/Program.cs
  45. +32
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj
  46. +94
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/JT808SessionServiceTest.cs
  47. +75
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/JT808UnificationTcpSendServiceTest.cs
  48. +43
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/TestBase.cs
  49. +92
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/JT808SessionServiceTest.cs
  50. +76
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/JT808UnificationUdpSendServiceTest.cs
  51. +41
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/TestBase.cs
  52. +24
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/JT808.Gateway.Traffic.Test.csproj
  53. +40
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/JT808DotNettyTrafficServiceTest.cs
  54. +44
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/Program.cs
  55. +24
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/JT808.Gateway.Transmit.Test.csproj
  56. +35
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/JT808DotNettyTransmitServiceTest.cs
  57. +43
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/Program.cs
  58. +65
    -0
      src/JT808.Gateway.sln
  59. +14
    -0
      src/JT808.Gateway/BusinessServices/MsgIdHandler/IJT808MsgIdHandler.cs
  60. +18
    -0
      src/JT808.Gateway/BusinessServices/MsgIdHandler/JT808MsgIdHandlerExtensions.cs
  61. +34
    -0
      src/JT808.Gateway/BusinessServices/MsgIdHandler/JT808MsgIdHandlerHostedService.cs
  62. +15
    -0
      src/JT808.Gateway/BusinessServices/MsgLogging/IJT808MsgLogging.cs
  63. +36
    -0
      src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgDownLoggingHostedService.cs
  64. +19
    -0
      src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgLoggingExtensions.cs
  65. +18
    -0
      src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgLoggingType.cs
  66. +36
    -0
      src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgUpLoggingHostedService.cs
  67. +57
    -0
      src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageExtensions.cs
  68. +34
    -0
      src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageHostedService.cs
  69. +165
    -0
      src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageService.cs
  70. +60
    -0
      src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeExtensions.cs
  71. +35
    -0
      src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeHostedService.cs
  72. +24
    -0
      src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeService.cs
  73. +32
    -0
      src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficService.cs
  74. +33
    -0
      src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficServiceExtensions.cs
  75. +38
    -0
      src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficServiceHostedService.cs
  76. +9
    -0
      src/JT808.Gateway/BusinessServices/Traffic/TrafficRedisClient.cs
  77. +13
    -0
      src/JT808.Gateway/BusinessServices/Transmit/Configs/DataTransferOptions.cs
  78. +11
    -0
      src/JT808.Gateway/BusinessServices/Transmit/Configs/RemoteServerOptions.cs
  79. +76
    -0
      src/JT808.Gateway/BusinessServices/Transmit/Handlers/ClientConnectionHandler.cs
  80. +39
    -0
      src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitExtensions.cs
  81. +33
    -0
      src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitHostedService.cs
  82. +236
    -0
      src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitService.cs
  83. +0
    -31
      src/JT808.Gateway/Configurations/JT808ClientConfiguration.cs
  84. +0
    -29
      src/JT808.Gateway/Converters/JsonByteArrayHexConverter.cs
  85. +0
    -26
      src/JT808.Gateway/Converters/JsonIPAddressConverter.cs
  86. +0
    -32
      src/JT808.Gateway/Converters/JsonIPEndPointConverter.cs
  87. +0
    -12
      src/JT808.Gateway/Dtos/JT808AtomicCounterDto.cs
  88. +0
    -15
      src/JT808.Gateway/Dtos/JT808DefaultResultDto.cs
  89. +0
    -37
      src/JT808.Gateway/Dtos/JT808IPAddressDto.cs
  90. +0
    -11
      src/JT808.Gateway/Dtos/JT808UnificationSendRequestDto.cs
  91. +0
    -91
      src/JT808.Gateway/Handlers/JT808MsgIdHttpHandlerBase.cs
  92. +6
    -3
      src/JT808.Gateway/JT808.Gateway.csproj
  93. +3
    -45
      src/JT808.Gateway/JT808GatewayExtensions.cs
  94. +20
    -14
      src/JT808.Gateway/Services/JT808GatewayService.cs
  95. +4
    -4
      src/JT808.Gateway/Services/JT808SessionService.cs
  96. +1
    -1
      src/JT808.Gateway/Services/JT808UnificationSendService.cs
  97. +1
    -1
      src/JT808.Gateway/Simples/JT808SimpleTcpClient.cs
  98. +1
    -1
      src/JT808.Gateway/Simples/JT808SimpleUdpClient.cs

+ 6
- 6
README.md View File

@@ -48,12 +48,12 @@


|服务名称|服务说明|使用场景| |服务名称|服务说明|使用场景|
|:------:|:------|:------| |:------:|:------|:------|
|JT808.DotNetty.MsgIdHandler| 消息处理服务|从队列中消费设备上报数据,再结合自身的业务场景,将数据进行处理并入库 |
|JT808.DotNetty.MsgLogging | 消息日志服务|从队列中消费设备上报和平台应答数据,再将数据存入influxdb等数据库中,便于技术和技术支持排查设备与平台交互的原始数据|
|JT808.DotNetty.ReplyMessage| 消息响应服务| 用于响应设备上报消息,以及下发指令信息到设备|
|JT808.DotNetty.SessionNotice| 会话管理服务| 通知设备上线下线,对于udp设备来说,可以在设备上线时,将指令跟随消息下发到设备|
|JT808.DotNetty.Traffic|流量统计服务 |由于运营商sim卡查询流量滞后,通过流量统计服务可以实时准确的统计设备流量,可以最优配置设备的流量大小,以节省成本
|JT808.DotNetty.Transmit| 原包转发服务|该服务可以将设备上报原始数据转发到第三方,支持全部转发,指定终端号转发|
|MsgIdHandler| 消息处理服务|从队列中消费设备上报数据,再结合自身的业务场景,将数据进行处理并入库 |
|MsgLogging | 消息日志服务|从队列中消费设备上报和平台应答数据,再将数据存入influxdb等数据库中,便于技术和技术支持排查设备与平台交互的原始数据|
|ReplyMessage| 消息响应服务| 用于响应设备上报消息,以及下发指令信息到设备|
|SessionNotice| 会话管理服务| 通知设备上线下线,对于udp设备来说,可以在设备上线时,将指令跟随消息下发到设备|
|Traffic|流量统计服务 |由于运营商sim卡查询流量滞后,通过流量统计服务可以实时准确的统计设备流量,可以最优配置设备的流量大小,以节省成本
|Transmit| 原包转发服务|该服务可以将设备上报原始数据转发到第三方,支持全部转发,指定终端号转发|


## NuGet安装 ## NuGet安装




+ 19
- 0
src/JT808.Gateway.CleintBenchmark/Configs/ClientBenchmarkOptions.cs View File

@@ -0,0 +1,19 @@
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.CleintBenchmark.Configs
{
public class ClientBenchmarkOptions : IOptions<ClientBenchmarkOptions>
{
public string IP { get; set; }
public int Port { get; set; }
public int DeviceCount { get; set; } = 10;
/// <summary>
/// 5000ms毫秒
/// </summary>
public int Interval { get; set; } = 5000;
public ClientBenchmarkOptions Value =>this;
}
}

+ 3106
- 0
src/JT808.Gateway.CleintBenchmark/Configs/NLog.xsd
File diff suppressed because it is too large
View File


+ 36
- 0
src/JT808.Gateway.CleintBenchmark/Configs/nlog.unix.config View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
参考:http://www.cnblogs.com/fuchongjundream/p/3936431.html
autoReload:自动再配置
internalLogFile:可以让NLog把内部的调试和异常信息都写入指定文件里程序没问题了,日志却出了问题。这个该怎么办,到底是哪里不正确了?假如日志本身除了bug该如何解决?这就需要日志排错。把日志的错误信息写入日志。
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />- 设置internalLogFile属性可以让NLog把内部的调试和异常信息都写入指定文件里。
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 决定内部日志的级别,级别越高,输出的日志信息越简洁。
<nlog internalLogToConsole="false|true" /> - 是否把内部日志输出到标准控制台。
<nlog internalLogToConsoleError="false|true" /> - 是否把内部日志输出到标准错误控制台 (stderr)。
设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。
-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="/data/logs/JT808.DotNetty.Hosting/internalLog.txt"
internalLogLevel="Debug" >
<variable name="Directory" value="/data/logs/JT808.DotNetty.Hosting"/>
<targets>
<target name="all" xsi:type="File"
fileName="${Directory}/all/${shortdate}.log"
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level}:${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"/>
<target name="console" xsi:type="ColoredConsole"
useDefaultRowHighlightingRules="false"
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}">
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/>
</rules>
</nlog>

+ 35
- 0
src/JT808.Gateway.CleintBenchmark/Configs/nlog.win.config View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
参考:http://www.cnblogs.com/fuchongjundream/p/3936431.html
autoReload:自动再配置
internalLogFile:可以让NLog把内部的调试和异常信息都写入指定文件里程序没问题了,日志却出了问题。这个该怎么办,到底是哪里不正确了?假如日志本身除了bug该如何解决?这就需要日志排错。把日志的错误信息写入日志。
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />- 设置internalLogFile属性可以让NLog把内部的调试和异常信息都写入指定文件里。
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 决定内部日志的级别,级别越高,输出的日志信息越简洁。
<nlog internalLogToConsole="false|true" /> - 是否把内部日志输出到标准控制台。
<nlog internalLogToConsoleError="false|true" /> - 是否把内部日志输出到标准错误控制台 (stderr)。
设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。
-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="${basedir}/wwwroot/logs/internalLog.txt"
internalLogLevel="Debug" >
<targets>
<target name="all" xsi:type="File"
fileName="${basedir}/wwwroot/logs/all/${shortdate}.log"
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level}:${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"/>
<target name="console" xsi:type="ColoredConsole"
useDefaultRowHighlightingRules="false"
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}">
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/>
</rules>
</nlog>

+ 33
- 0
src/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Configs\nlog.unix.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Configs\nlog.win.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Configs\NLog.xsd">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 51
- 0
src/JT808.Gateway.CleintBenchmark/Program.cs View File

@@ -0,0 +1,51 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
using System.Threading.Tasks;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using JT808.Gateway.CleintBenchmark.Configs;
using JT808.Gateway.Client;
using JT808.Gateway.CleintBenchmark.Services;

namespace JT808.Gateway.CleintBenchmark
{
class Program
{
static async Task Main(string[] args)
{
var serverHostBuilder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
})
.ConfigureLogging((context, logging) =>
{
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
NLog.LogManager.LoadConfiguration("Configs/nlog.unix.config");
}
else
{
NLog.LogManager.LoadConfiguration("Configs/nlog.win.config");
}
logging.AddNLog();
logging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) =>
{
services.Configure<ClientBenchmarkOptions>(hostContext.Configuration.GetSection("ClientBenchmarkOptions"));
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808Client();
services.AddHostedService<CleintBenchmarkHostedService>();
services.AddHostedService<CleintBenchmarkReportHostedService>();
});
await serverHostBuilder.RunConsoleAsync();
}
}
}

+ 82
- 0
src/JT808.Gateway.CleintBenchmark/Services/CleintBenchmarkHostedService.cs View File

@@ -0,0 +1,82 @@
using JT808.Gateway.CleintBenchmark.Configs;
using JT808.Gateway.Client;
using JT808.Protocol.MessageBody;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace JT808.Gateway.CleintBenchmark.Services
{
public class CleintBenchmarkHostedService : IHostedService
{
private readonly ClientBenchmarkOptions clientBenchmarkOptions;

private readonly ILogger logger;

private readonly IJT808TcpClientFactory jT808TcpClientFactory;

private CancellationTokenSource cts=new CancellationTokenSource();

private TaskFactory taskFactory;

public CleintBenchmarkHostedService(
ILoggerFactory loggerFactory,
IJT808TcpClientFactory jT808TcpClientFactory,
IOptions<ClientBenchmarkOptions> clientBenchmarkOptionsAccessor)
{
this.jT808TcpClientFactory = jT808TcpClientFactory;
clientBenchmarkOptions = clientBenchmarkOptionsAccessor.Value;
logger = loggerFactory.CreateLogger("CleintBenchmarkHostedService");
taskFactory = new TaskFactory();
}
public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation("StartAsync...");
ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
logger.LogInformation($"GetMinThreads:{minWorkerThreads}-{minCompletionPortThreads}");
logger.LogInformation($"GetMaxThreads:{maxWorkerThreads}-{maxCompletionPortThreads}");
//ThreadPool.SetMaxThreads(20, 20);
//ThreadPool.GetMaxThreads(out var setMaxWorkerThreads, out var setMaxCompletionPortThreads);
//logger.LogInformation($"SetMaxThreads:{setMaxWorkerThreads}-{setMaxCompletionPortThreads}");
for (int i=0;i< clientBenchmarkOptions.DeviceCount; i++)
{
taskFactory.StartNew((item) =>
{
var client = jT808TcpClientFactory.Create(new DeviceConfig(((int)item).ToString(), clientBenchmarkOptions.IP, clientBenchmarkOptions.Port));
int lat = new Random(1000).Next(100000, 180000);
int Lng = new Random(1000).Next(100000, 180000);
while (!cts.IsCancellationRequested)
{
client.Send(new JT808_0x0200()
{
Lat = lat,
Lng = Lng,
GPSTime = DateTime.Now,
Speed = 50,
Direction = 30,
AlarmFlag = 5,
Altitude = 50,
StatusFlag = 10
});
Thread.Sleep(clientBenchmarkOptions.Interval);
}
}, i,cts.Token);
}
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
cts.Cancel();
logger.LogInformation("StopAsync...");
return Task.CompletedTask;
}
}
}

+ 53
- 0
src/JT808.Gateway.CleintBenchmark/Services/CleintBenchmarkReportHostedService.cs View File

@@ -0,0 +1,53 @@
using JT808.Gateway.Services;
using JT808.Protocol.MessageBody;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace JT808.Gateway.CleintBenchmark.Services
{
public class CleintBenchmarkReportHostedService : IHostedService
{
private readonly JT808ClientReportService jT808ReportService;

private CancellationTokenSource cts=new CancellationTokenSource();

private readonly ILogger logger;
public CleintBenchmarkReportHostedService(
ILoggerFactory loggerFactory,
JT808ClientReportService jT808ReportService)
{
this.jT808ReportService = jT808ReportService;
logger = loggerFactory.CreateLogger("CleintBenchmarkReportHostedService");
}
public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation("StartAsync...");
Task.Run(() => {
while (!cts.IsCancellationRequested)
{
logger.LogInformation(JsonConvert.SerializeObject(jT808ReportService.JT808Reports.LastOrDefault()));
Thread.Sleep(3000);
}
}, cts.Token);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation("StopAsync...");
cts.Cancel();
logger.LogInformation("正在生成报表...");
logger.LogInformation(JsonConvert.SerializeObject(jT808ReportService.JT808Reports,Formatting.Indented));
return Task.CompletedTask;
}
}
}

+ 15
- 0
src/JT808.Gateway.Kafka/Configs/JT808ConsumerConfig.cs View File

@@ -0,0 +1,15 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808ConsumerConfig: ConsumerConfig, IOptions<JT808ConsumerConfig>
{
public string TopicName { get; set; }

public JT808ConsumerConfig Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808MsgConsumerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808MsgConsumerConfig : JT808ConsumerConfig, IOptions<JT808MsgConsumerConfig>
{
JT808MsgConsumerConfig IOptions<JT808MsgConsumerConfig>.Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808MsgProducerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808MsgProducerConfig : JT808ProducerConfig, IOptions<JT808MsgProducerConfig>
{
JT808MsgProducerConfig IOptions<JT808MsgProducerConfig>.Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808MsgReplyConsumerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808MsgReplyConsumerConfig : JT808ConsumerConfig, IOptions<JT808MsgReplyConsumerConfig>
{
JT808MsgReplyConsumerConfig IOptions<JT808MsgReplyConsumerConfig>.Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808MsgReplyProducerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808MsgReplyProducerConfig : JT808ProducerConfig, IOptions<JT808MsgReplyProducerConfig>
{
JT808MsgReplyProducerConfig IOptions<JT808MsgReplyProducerConfig>.Value => this;
}
}

+ 15
- 0
src/JT808.Gateway.Kafka/Configs/JT808ProducerConfig.cs View File

@@ -0,0 +1,15 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808ProducerConfig : ProducerConfig,IOptions<JT808ProducerConfig>
{
public string TopicName { get; set; }

public JT808ProducerConfig Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808SessionConsumerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808SessionConsumerConfig : JT808ConsumerConfig, IOptions<JT808SessionConsumerConfig>
{
JT808SessionConsumerConfig IOptions<JT808SessionConsumerConfig>.Value => this;
}
}

+ 13
- 0
src/JT808.Gateway.Kafka/Configs/JT808SessionProducerConfig.cs View File

@@ -0,0 +1,13 @@
using Confluent.Kafka;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Configs.Kafka
{
public class JT808SessionProducerConfig : JT808ProducerConfig, IOptions<JT808SessionProducerConfig>
{
JT808SessionProducerConfig IOptions<JT808SessionProducerConfig>.Value => this;
}
}

+ 39
- 0
src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj View File

@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Copyright>Copyright 2018.</Copyright>
<Authors>SmallChi(Koike)</Authors>
<RepositoryUrl>https://github.com/SmallChi/JT808DotNetty</RepositoryUrl>
<PackageProjectUrl>https://github.com/SmallChi/JT808DotNetty</PackageProjectUrl>
<licenseUrl>https://github.com/SmallChi/JT808DotNetty/blob/master/LICENSE</licenseUrl>
<license>https://github.com/SmallChi/JT808DotNetty/blob/master/LICENSE</license>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>1.0.0-preview1</Version>
<SignAssembly>false</SignAssembly>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageId>JT808.Gateway.Kafka</PackageId>
<Product>JT808.Gateway.Kafka</Product>
<Description>基于Kafka的JT808消息发布与订阅</Description>
<PackageReleaseNotes>基于Kafka的JT808消息发布与订阅</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Confluent.Kafka" Version="1.2.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>

</Project>

+ 24
- 0
src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs View File

@@ -0,0 +1,24 @@
using JT808.Protocol;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Kafka
{
internal class JT808ClientBuilderDefault : IJT808ClientBuilder
{
public IJT808Builder JT808Builder { get; }

public JT808ClientBuilderDefault(IJT808Builder builder)
{
JT808Builder = builder;
}

public IJT808Builder Builder()
{
return JT808Builder;
}
}
}

+ 66
- 0
src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs View File

@@ -0,0 +1,66 @@
using JJT808.Gateway.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace JT808.Gateway.Kafka
{
public static class JT808ClientKafkaExtensions
{
public static IJT808ClientBuilder AddJT808ClientKafka(this IJT808Builder builder)
{
return new JT808ClientBuilderDefault(builder);
}
/// <summary>
///
/// </summary>
/// <param name="serviceDescriptors"></param>
/// <param name="configuration">GetSection("JT808MsgConsumerConfig")</param>
/// <returns></returns>
public static IJT808ClientBuilder AddMsgConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<JT808MsgConsumerConfig>(configuration.GetSection("JT808MsgConsumerConfig"));
jT808ClientBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgConsumer, JT808MsgConsumer>();
return jT808ClientBuilder;
}
/// <summary>
///
/// </summary>
/// <param name="serviceDescriptors"></param>
/// <param name="configuration">GetSection("JT808MsgReplyProducerConfig")</param>
/// <returns></returns>
public static IJT808ClientBuilder AddMsgReplyProducer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<JT808MsgReplyProducerConfig>(configuration.GetSection("JT808MsgReplyProducerConfig"));
jT808ClientBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyProducer, JT808MsgReplyProducer>();
return jT808ClientBuilder;
}
/// <summary>
///
/// </summary>
/// <param name="jT808NettyBuilder"></param>
/// <param name="configuration">GetSection("JT808MsgReplyConsumerConfig")</param>
/// <returns></returns>
public static IJT808ClientBuilder AddMsgReplyConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<JT808MsgReplyConsumerConfig>(configuration.GetSection("JT808MsgReplyConsumerConfig"));
jT808ClientBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(JT808MsgReplyConsumer), ServiceLifetime.Singleton));
return jT808ClientBuilder;
}
/// <summary>
///
/// </summary>
/// <param name="serviceDescriptors"></param>
/// <param name="configuration">GetSection("JT808SessionConsumerConfig")</param>
/// <returns></returns>
public static IJT808ClientBuilder AddSessionConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<JT808SessionConsumerConfig>(configuration.GetSection("JT808SessionConsumerConfig"));
jT808ClientBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionConsumer, JT808SessionConsumer>();
return jT808ClientBuilder;
}
}
}

+ 82
- 0
src/JT808.Gateway.Kafka/JT808MsgConsumer.cs View File

@@ -0,0 +1,82 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.Kafka
{
public class JT808MsgConsumer : IJT808MsgConsumer
{
public CancellationTokenSource Cts => new CancellationTokenSource();

private readonly IConsumer<string, byte[]> consumer;

private readonly ILogger logger;

public string TopicName { get; }

public JT808MsgConsumer(
IOptions<JT808MsgConsumerConfig> consumerConfigAccessor,
ILoggerFactory loggerFactory)
{
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build();
TopicName = consumerConfigAccessor.Value.TopicName;
logger = loggerFactory.CreateLogger("JT808MsgConsumer");
}

public void OnMessage(Action<(string TerminalNo, byte[] Data)> callback)
{
Task.Run(() =>
{
while (!Cts.IsCancellationRequested)
{
try
{
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据
var data = consumer.Consume(Cts.Token);
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"Topic: {data.Topic} Key: {data.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}");
}
callback((data.Key, data.Value));
}
catch (ConsumeException ex)
{
logger.LogError(ex, TopicName);
}
catch (OperationCanceledException ex)
{
logger.LogError(ex, TopicName);
}
catch (Exception ex)
{
logger.LogError(ex, TopicName);
}
}
}, Cts.Token);
}

public void Subscribe()
{
consumer.Subscribe(TopicName);
}

public void Unsubscribe()
{
consumer.Unsubscribe();
}

public void Dispose()
{
consumer.Close();
consumer.Dispose();
}
}
}

+ 38
- 0
src/JT808.Gateway.Kafka/JT808MsgProducer.cs View File

@@ -0,0 +1,38 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace JT808.Gateway.Kafka
{
public class JT808MsgProducer : IJT808MsgProducer
{
public string TopicName { get; }

private readonly IProducer<string, byte[]> producer;
public JT808MsgProducer(
IOptions<JT808MsgProducerConfig> producerConfigAccessor)
{
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build();
TopicName = producerConfigAccessor.Value.TopicName;
}

public void Dispose()
{
producer.Dispose();
}

public async Task ProduceAsync(string terminalNo, byte[] data)
{
await producer.ProduceAsync(TopicName, new Message<string, byte[]>
{
Key = terminalNo,
Value = data
});
}
}
}

+ 82
- 0
src/JT808.Gateway.Kafka/JT808MsgReplyConsumer.cs View File

@@ -0,0 +1,82 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.Kafka
{
public class JT808MsgReplyConsumer : IJT808MsgReplyConsumer
{
public CancellationTokenSource Cts => new CancellationTokenSource();

private readonly IConsumer<string, byte[]> consumer;

private readonly ILogger logger;

public string TopicName { get; }

public JT808MsgReplyConsumer(
IOptions<JT808MsgReplyConsumerConfig> consumerConfigAccessor,
ILoggerFactory loggerFactory)
{
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build();
TopicName = consumerConfigAccessor.Value.TopicName;
logger = loggerFactory.CreateLogger("JT808MsgReplyConsumer");
}

public void OnMessage(Action<(string TerminalNo, byte[] Data)> callback)
{
Task.Run(() =>
{
while (!Cts.IsCancellationRequested)
{
try
{
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据
var data = consumer.Consume(Cts.Token);
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"Topic: {data.Topic} Key: {data.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}");
}
callback((data.Key, data.Value));
}
catch (ConsumeException ex)
{
logger.LogError(ex, TopicName);
}
catch (OperationCanceledException ex)
{
logger.LogError(ex, TopicName);
}
catch (Exception ex)
{
logger.LogError(ex, TopicName);
}
}
}, Cts.Token);
}

public void Subscribe()
{
consumer.Subscribe(TopicName);
}

public void Unsubscribe()
{
consumer.Unsubscribe();
}

public void Dispose()
{
consumer.Close();
consumer.Dispose();
}
}
}

+ 38
- 0
src/JT808.Gateway.Kafka/JT808MsgReplyProducer.cs View File

@@ -0,0 +1,38 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace JJT808.Gateway.Kafka
{
public class JT808MsgReplyProducer : IJT808MsgReplyProducer
{
public string TopicName { get;}

private IProducer<string, byte[]> producer;
public JT808MsgReplyProducer(
IOptions<JT808MsgReplyProducerConfig> producerConfigAccessor)
{
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build();
TopicName = producerConfigAccessor.Value.TopicName;
}

public void Dispose()
{
producer.Dispose();
}

public async Task ProduceAsync(string terminalNo, byte[] data)
{
await producer.ProduceAsync(TopicName, new Message<string, byte[]>
{
Key = terminalNo,
Value = data
});
}
}
}

+ 48
- 0
src/JT808.Gateway.Kafka/JT808ServerKafkaExtensions.cs View File

@@ -0,0 +1,48 @@
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace JT808.Gateway.Kafka
{
public static class JT808ServerKafkaExtensions
{
/// <summary>
///
/// </summary>
/// <param name="jT808NettyBuilder"></param>
/// <param name="configuration">GetSection("JT808MsgProducerConfig")</param>
/// <returns></returns>
public static IJT808GatewayBuilder AddJT808ServerKafkaMsgProducer(this IJT808GatewayBuilder jT808GatewayBuilder, IConfiguration configuration)
{
jT808GatewayBuilder.JT808Builder.Services.Configure<JT808MsgProducerConfig>(configuration.GetSection("JT808MsgProducerConfig"));
jT808GatewayBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgProducer), typeof(JT808MsgProducer), ServiceLifetime.Singleton));
return jT808GatewayBuilder;
}
/// <summary>
///
/// </summary>
/// <param name="jT808NettyBuilder"></param>
/// <param name="configuration">GetSection("JT808MsgReplyConsumerConfig")</param>
/// <returns></returns>
public static IJT808GatewayBuilder AddJT808ServerKafkaMsgReplyConsumer(this IJT808GatewayBuilder jT808GatewayBuilder, IConfiguration configuration)
{
jT808GatewayBuilder.JT808Builder.Services.Configure<JT808MsgReplyConsumerConfig>(configuration.GetSection("JT808MsgReplyConsumerConfig"));
jT808GatewayBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(JT808MsgReplyConsumer), ServiceLifetime.Singleton));
return jT808GatewayBuilder;
}
/// <summary>
///
/// </summary>
/// <param name="jT808NettyBuilder"></param>
/// <param name="configuration">GetSection("JT808SessionProducerConfig")</param>
/// <returns></returns>
public static IJT808GatewayBuilder AddJT808ServerKafkaSessionProducer(this IJT808GatewayBuilder jT808GatewayBuilder, IConfiguration configuration)
{
jT808GatewayBuilder.JT808Builder.Services.Configure<JT808SessionProducerConfig>(configuration.GetSection("JT808SessionProducerConfig"));
jT808GatewayBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808SessionProducer), typeof(JT808SessionProducer), ServiceLifetime.Singleton));
return jT808GatewayBuilder;
}
}
}

+ 82
- 0
src/JT808.Gateway.Kafka/JT808SessionConsumer.cs View File

@@ -0,0 +1,82 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.Kafka
{
public class JT808SessionConsumer : IJT808SessionConsumer
{
public CancellationTokenSource Cts => new CancellationTokenSource();

private readonly IConsumer<string, string> consumer;

private readonly ILogger logger;

public string TopicName { get; }

public JT808SessionConsumer(
IOptions<JT808SessionConsumerConfig> consumerConfigAccessor,
ILoggerFactory loggerFactory)
{
consumer = new ConsumerBuilder<string, string>(consumerConfigAccessor.Value).Build();
TopicName = consumerConfigAccessor.Value.TopicName;
logger = loggerFactory.CreateLogger("JT808SessionConsumer");
}

public void OnMessage(Action<(string Notice, string TerminalNo)> callback)
{
Task.Run(() =>
{
while (!Cts.IsCancellationRequested)
{
try
{
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据
var data = consumer.Consume(Cts.Token);
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"Topic: {data.Topic} Key: {data.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}");
}
callback((data.Key, data.Value));
}
catch (ConsumeException ex)
{
logger.LogError(ex, TopicName);
}
catch (OperationCanceledException ex)
{
logger.LogError(ex, TopicName);
}
catch (Exception ex)
{
logger.LogError(ex, TopicName);
}
}
}, Cts.Token);
}

public void Subscribe()
{
consumer.Subscribe(TopicName);
}

public void Unsubscribe()
{
consumer.Unsubscribe();
}

public void Dispose()
{
consumer.Close();
consumer.Dispose();
}
}
}

+ 38
- 0
src/JT808.Gateway.Kafka/JT808SessionProducer.cs View File

@@ -0,0 +1,38 @@
using Confluent.Kafka;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace JT808.Gateway.Kafka
{
public class JT808SessionProducer : IJT808SessionProducer
{
public string TopicName { get; }

private readonly IProducer<string, string> producer;
public JT808SessionProducer(
IOptions<JT808SessionProducerConfig> producerConfigAccessor)
{
producer = new ProducerBuilder<string, string>(producerConfigAccessor.Value).Build();
TopicName = producerConfigAccessor.Value.TopicName;
}

public void Dispose()
{
producer.Dispose();
}

public async Task ProduceAsync(string notice,string terminalNo)
{
await producer.ProduceAsync(TopicName, new Message<string, string>
{
Key = notice,
Value = terminalNo
});
}
}
}

+ 8
- 2
src/JT808.Gateway.SimpleClient/Program.cs View File

@@ -8,6 +8,7 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Grpc.Net.Client; using Grpc.Net.Client;
using JT808.Gateway.GrpcService; using JT808.Gateway.GrpcService;
using System.Net;


namespace JT808.Gateway.SimpleClient namespace JT808.Gateway.SimpleClient
{ {
@@ -16,7 +17,12 @@ namespace JT808.Gateway.SimpleClient
static async Task Main(string[] args) static async Task Main(string[] args)
{ {
//ref https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client //ref https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
//ref https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0

//先执行 dotnet dev-certs https --trust 命令生成开发证书
//使用 certmgr.msc 导出证书在服务端配置对应证书文件
//Uri "https://localhost:5001"

var serverHostBuilder = new HostBuilder() var serverHostBuilder = new HostBuilder()
.ConfigureLogging((context, logging) => .ConfigureLogging((context, logging) =>
{ {
@@ -27,7 +33,7 @@ namespace JT808.Gateway.SimpleClient
{ {
services.AddGrpcClient<JT808Gateway.JT808GatewayClient>(o => services.AddGrpcClient<JT808Gateway.JT808GatewayClient>(o =>
{ {
o.Address = new Uri("https://127.0.0.1:5001");
o.Address = new Uri("https://localhost:5001");
}); });
services.AddSingleton<ILoggerFactory, LoggerFactory>(); services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));


+ 3
- 3
src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs View File

@@ -32,8 +32,8 @@ namespace JT808.Gateway.SimpleClient.Services
public Task StartAsync(CancellationToken cancellationToken) public Task StartAsync(CancellationToken cancellationToken)
{ {
Task.Run(() => { Task.Run(() => {
while (!cancellationToken.IsCancellationRequested)
{
//while (!cancellationToken.IsCancellationRequested)
//{
Thread.Sleep(1000 * 10); Thread.Sleep(1000 * 10);
var result1 = client.GetTcpAtomicCounter(new Empty()); var result1 = client.GetTcpAtomicCounter(new Empty());
var result2 = client.GetUdpAtomicCounter(new Empty()); var result2 = client.GetUdpAtomicCounter(new Empty());
@@ -55,7 +55,7 @@ namespace JT808.Gateway.SimpleClient.Services
logger.LogDebug(JsonSerializer.Serialize(result4)); logger.LogDebug(JsonSerializer.Serialize(result4));
logger.LogDebug(JsonSerializer.Serialize(result5)); logger.LogDebug(JsonSerializer.Serialize(result5));
logger.LogDebug(JsonSerializer.Serialize(result6)); logger.LogDebug(JsonSerializer.Serialize(result6));
}
//}
}, cancellationToken); }, cancellationToken);
return Task.CompletedTask; return Task.CompletedTask;
} }


BIN
src/JT808.Gateway.SimpleServer/Configs/test.cer View File


+ 3
- 0
src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj View File

@@ -30,6 +30,9 @@
<None Update="Configs\NLog.xsd"> <None Update="Configs\NLog.xsd">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="Configs\test.cer">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>


</Project> </Project>


+ 10
- 9
src/JT808.Gateway.SimpleServer/Program.cs View File

@@ -11,6 +11,7 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
using System; using System;
using System.IO;
using System.Net; using System.Net;


namespace JT808.Gateway.SimpleServer namespace JT808.Gateway.SimpleServer
@@ -31,17 +32,17 @@ namespace JT808.Gateway.SimpleServer
configLogging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); configLogging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true });
configLogging.SetMinimumLevel(LogLevel.Trace); configLogging.SetMinimumLevel(LogLevel.Trace);
}) })

.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
{ {
webBuilder webBuilder
//.ConfigureKestrel(options =>
//{
// options.Listen(IPAddress.Any, 5001, listenOptions =>
// {
// listenOptions.Protocols = HttpProtocols.Http2;
// });
//})
.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps($"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", "test.cer")}", "");
});
})
.Configure(app => .Configure(app =>
{ {
app.UseRouting(); app.UseRouting();
@@ -53,7 +54,7 @@ namespace JT808.Gateway.SimpleServer
}) })
.ConfigureServices((hostContext,services) => .ConfigureServices((hostContext,services) =>
{ {
services.Configure<KestrelServerOptions>(hostContext.Configuration.GetSection("Kestrel"));
//services.Configure<KestrelServerOptions>(hostContext.Configuration.GetSection("Kestrel"));
services.AddGrpc(); services.AddGrpc();
services.AddSingleton<ILoggerFactory, LoggerFactory>(); services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));


+ 24
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/JT808.Gateway.MsgIdHandler.Test.csproj View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
<ProjectReference Include="..\..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 44
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs View File

@@ -0,0 +1,44 @@
using JT808.Gateway.BusinessServices.MsgIdHandler;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol;
using JT808.Protocol.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.MsgIdHandler.Test
{
public class JT808DotNettyMsgIdHandlerDefaultImpl : IJT808MsgIdHandler
{
public readonly ILogger<JT808DotNettyMsgIdHandlerDefaultImpl> logger;
public JT808DotNettyMsgIdHandlerDefaultImpl(ILoggerFactory loggerFactory,
IServiceProvider serviceProvider) {
logger = loggerFactory.CreateLogger<JT808DotNettyMsgIdHandlerDefaultImpl>();
Task.Run(()=> {
while (true)
{
Thread.Sleep(5000);
using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(new JT808MsgProducerConfig
{
BootstrapServers = "127.0.0.1:9092",
TopicName = "JT808Msg"
}))
{
jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait();
}
}
});
}

public void Processor((string TerminalNo, byte[] Data) parameter)
{
logger.LogDebug($"{parameter.TerminalNo}:{parameter.Data.ToHexString()}");
}
}
}

+ 39
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgIdHandler.Test/Program.cs View File

@@ -0,0 +1,39 @@
using JT808.Gateway.BusinessServices.MsgIdHandler;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.MsgIdHandler.Test
{
class Program
{
async static Task Main(string[] args)
{
var serverHostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostingContext,config) => {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{ hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging(configLogging => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddMsgConsumer(hostContext.Configuration)
.AddJT808MsgIdHandler<JT808DotNettyMsgIdHandlerDefaultImpl>();
});
await serverHostBuilder.RunConsoleAsync();
}
}
}

+ 25
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/JT808.Gateway.MsgLogging.Test.csproj View File

@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
<ProjectReference Include="..\..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 52
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/JT808MsgLoggingImpl.cs View File

@@ -0,0 +1,52 @@
using JJT808.Gateway.Kafka;
using JT808.Gateway.BusinessServices.MsgLogging;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol.Extensions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.MsgLogging.Test
{
public class JT808MsgLoggingImpl : IJT808MsgLogging
{
public readonly ILogger<JT808MsgLoggingImpl> logger;
public JT808MsgLoggingImpl(ILoggerFactory loggerFactory) {
logger = loggerFactory.CreateLogger<JT808MsgLoggingImpl>();
Task.Run(() => {
while (true)
{
Thread.Sleep(5000);
using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(new JT808MsgProducerConfig
{
BootstrapServers = "127.0.0.1:9092",
TopicName = "JT808Msg"
}))
{
jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0,0,0,0, 0x7E }).Wait();
}

JT808MsgReplyProducerConfig JT808MsgProducerConfig = new JT808MsgReplyProducerConfig
{
TopicName = "JT808MsgReply",
BootstrapServers = "127.0.0.1:9092",
};
using (IJT808MsgReplyProducer jT808MsgProducer = new JT808MsgReplyProducer(JT808MsgProducerConfig))
{
jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E,1,1,1,1, 0x7E }).Wait();
}
}
});
}

public void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType)
{
logger.LogDebug($"{parameter.TerminalNo}:{parameter.Data.ToHexString()},方向:{jT808MsgLoggingType.ToString()}");
}
}
}

+ 43
- 0
src/JT808.Gateway.Tests/JT808.Gateway.MsgLogging.Test/Program.cs View File

@@ -0,0 +1,43 @@
using JT808.Gateway.BusinessServices.MsgLogging;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.MsgLogging.Test
{
class Program
{
async static Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostContext,config)=> {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostContext, configLogging) => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddMsgConsumer(hostContext.Configuration)
.AddMsgReplyConsumer(hostContext.Configuration)
.AddJT808MsgLogging<JT808MsgLoggingImpl>();
})
;

await hostBuilder.RunConsoleAsync();
}
}
}

+ 25
- 0
src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/JT808.Gateway.ReplyMessage.Test.csproj View File

@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
<ProjectReference Include="..\..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 48
- 0
src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using JT808.Gateway.BusinessServices.ReplyMessage;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol;
using JT808.Protocol.Extensions;
using Microsoft.Extensions.Logging;

namespace JT808.Gateway.ReplyMessage.Test
{
public class JT808DotNettyReplyMessageServiceInherited : JT808ReplyMessageService
{
public readonly ILogger<JT808DotNettyReplyMessageServiceInherited> logger;

public JT808DotNettyReplyMessageServiceInherited(IJT808Config jT808Config,
IJT808MsgReplyProducer jT808MsgReplyProducer,
ILoggerFactory loggerFactory)
: base(jT808Config, jT808MsgReplyProducer)
{
logger = loggerFactory.CreateLogger<JT808DotNettyReplyMessageServiceInherited>();
Task.Run(() => {
while (true)
{
Thread.Sleep(5000);
using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(new JT808MsgProducerConfig
{
BootstrapServers = "127.0.0.1:9092",
TopicName = "JT808Msg"
}))
{
jT808MsgProducer.ProduceAsync("011111111111", "7E02000032011111111111012E00000000000C00000160E42506C30C82002C00000000180914142057010400001DC003020000250400000000300115310100977E".ToHexBytes()).Wait();
}
}
});
}

public override void Processor((string TerminalNo, byte[] Data) parameter)
{
logger.LogDebug($"{parameter.TerminalNo}:{parameter.Data.ToHexString()}");
base.Processor(parameter);
}
}
}

+ 42
- 0
src/JT808.Gateway.Tests/JT808.Gateway.ReplyMessage.Test/Program.cs View File

@@ -0,0 +1,42 @@
using JT808.Gateway.BusinessServices.ReplyMessage;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.ReplyMessage.Test
{
class Program
{
async static Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostContext, config) => {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostContext, configLogging) => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddMsgConsumer(hostContext.Configuration)
.AddMsgReplyProducer(hostContext.Configuration)
.AddInprocJT808ReplyMessage<JT808DotNettyReplyMessageServiceInherited>();
})
;

await hostBuilder.RunConsoleAsync();
}
}
}

+ 24
- 0
src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/JT808.Gateway.SessionNotice.Test.csproj View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 41
- 0
src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using JT808.Gateway.BusinessServices.SessionNotice;
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using Microsoft.Extensions.Logging;

namespace JT808.Gateway.SessionNotice.Test
{
public class JT808DotNettySessionNoticeServiceInherited : JT808SessionNoticeService
{
public JT808DotNettySessionNoticeServiceInherited(ILoggerFactory loggerFactory) : base(loggerFactory)
{
Task.Run(()=> {
while (true)
{
Thread.Sleep(5000);
JT808SessionProducerConfig JT808ProducerConfig = new JT808SessionProducerConfig
{
TopicName = "JT808Session",
BootstrapServers = "127.0.0.1:9092"
};
using (IJT808SessionProducer jT808MsgProducer = new JT808SessionProducer(JT808ProducerConfig))
{
jT808MsgProducer.ProduceAsync("online", "123456").Wait();
jT808MsgProducer.ProduceAsync("offline", "123457").Wait();
}
}
});
}

public override void Processor((string Notice, string TerminalNo) parameter)
{
base.Processor(parameter);
}
}
}

+ 41
- 0
src/JT808.Gateway.Tests/JT808.Gateway.SessionNotice.Test/Program.cs View File

@@ -0,0 +1,41 @@
using JT808.Gateway.BusinessServices.SessionNotice;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.SessionNotice.Test
{
class Program
{
async static Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostContext, config) => {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostContext, configLogging) => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddSessionConsumer(hostContext.Configuration)
.AddInprocJT808SessionNotice<JT808DotNettySessionNoticeServiceInherited>();
})
;

await hostBuilder.RunConsoleAsync();
}
}
}

+ 32
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj View File

@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Tcp\appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Udp\appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 94
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/JT808SessionServiceTest.cs View File

@@ -0,0 +1,94 @@
using JT808.Protocol;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using JT808.Protocol.Extensions;
using Xunit;
using JT808.Gateway.Interfaces;
using JT808.Gateway.Session;
using JT808.Gateway.Simples;

namespace JT808.Gateway.Test.Tcp
{
public class JT808SessionServiceTest:TestBase,IDisposable
{
static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6565);

JT808SimpleTcpClient SimpleTcpClient1;
JT808SimpleTcpClient SimpleTcpClient2;
JT808SimpleTcpClient SimpleTcpClient3;
JT808SimpleTcpClient SimpleTcpClient4;
JT808SimpleTcpClient SimpleTcpClient5;

public JT808SessionServiceTest()
{
SimpleTcpClient1 = new JT808SimpleTcpClient(endPoint);
SimpleTcpClient2 = new JT808SimpleTcpClient(endPoint);
SimpleTcpClient3 = new JT808SimpleTcpClient(endPoint);
SimpleTcpClient4 = new JT808SimpleTcpClient(endPoint);
SimpleTcpClient5 = new JT808SimpleTcpClient(endPoint);
// 心跳会话包
JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001");
SimpleTcpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1));

// 心跳会话包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002");
SimpleTcpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2));

// 心跳会话包
JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003");
SimpleTcpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3));

// 心跳会话包
JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004");
SimpleTcpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4));

// 心跳会话包
JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005");
SimpleTcpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5));
Thread.Sleep(1000);
}

public void Dispose()
{
SimpleTcpClient1.Down();
SimpleTcpClient2.Down();
SimpleTcpClient3.Down();
SimpleTcpClient4.Down();
SimpleTcpClient5.Down();
}

[Fact]
public void Test1()
{
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
var result = jT808SessionServiceDefaultImpl.GetTcpAll();
Thread.Sleep(5000);
}

[Fact]
public void Test2()
{
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
var result1 = jT808SessionServiceDefaultImpl.GetTcpAll();
var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001");
var result3 = jT808SessionServiceDefaultImpl.GetTcpAll();
}

[Fact]
public void Test3()
{
// 判断通道是否关闭
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
JT808SessionManager jT808TcpSessionManager = ServiceProvider.GetService<JT808SessionManager>();
var result1 = jT808SessionServiceDefaultImpl.GetTcpAll();
SimpleTcpClient1.Down();
Thread.Sleep(5000);
var session = jT808TcpSessionManager.GetSessionByTerminalPhoneNo("123456789001");
Thread.Sleep(100000);
}
}
}

+ 75
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/JT808UnificationTcpSendServiceTest.cs View File

@@ -0,0 +1,75 @@
using JT808.Protocol;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using JT808.Protocol.Extensions;
using JT808.Protocol.MessageBody;
using JT808.Gateway.Interfaces;
using JT808.Gateway.Simples;
using Xunit;
using JT808.Gateway.Dtos;

namespace JT808.Gateway.Test.Tcp
{
public class JT808UnificationTcpSendServiceTest: TestBase
{
static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6565);

private IJT808UnificationSendService jT808UnificationSendService;
private IJT808SessionService jT808SessionServiceDefaultImpl;

public JT808UnificationTcpSendServiceTest()
{
JT808SimpleTcpClient SimpleTcpClient1 = new JT808SimpleTcpClient(endPoint);
JT808SimpleTcpClient SimpleTcpClient2 = new JT808SimpleTcpClient(endPoint);
JT808SimpleTcpClient SimpleTcpClient3 = new JT808SimpleTcpClient(endPoint);
JT808SimpleTcpClient SimpleTcpClient4 = new JT808SimpleTcpClient(endPoint);
JT808SimpleTcpClient SimpleTcpClient5 = new JT808SimpleTcpClient(endPoint);
// 心跳会话包
JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001");
SimpleTcpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1));

// 心跳会话包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002");
SimpleTcpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2));

// 心跳会话包
JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003");
SimpleTcpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3));

// 心跳会话包
JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004");
SimpleTcpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4));

// 心跳会话包
JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005");
SimpleTcpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5));

Thread.Sleep(300);
}

[Fact]
public void Test1()
{
jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
jT808UnificationSendService = ServiceProvider.GetService<IJT808UnificationSendService>();
jT808SessionServiceDefaultImpl.GetTcpAll();
string no = "123456789001";
// 文本信息包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.文本信息下发.Create(no, new JT808_0x8300
{
TextFlag = 5,
TextInfo = "smallchi 518"
});
var data = JT808Serializer.Serialize(jT808Package2);
JT808ResultDto<bool> jt808Result = jT808UnificationSendService.Send(no, data);
Thread.Sleep(1000);
Assert.Equal(200, jt808Result.Code);
Assert.True(jt808Result.Data);
}
}
}

+ 43
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Tcp/TestBase.cs View File

@@ -0,0 +1,43 @@
using JT808.Gateway.Tcp;
using JT808.Protocol;
using JT808.Protocol.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace JT808.Gateway.Test.Tcp
{
public class TestBase
{
public static IServiceProvider ServiceProvider;
public static JT808Serializer JT808Serializer;
static TestBase()
{
var serverHostBuilder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tcp"));
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808Gateway(hostContext.Configuration)
.AddJT808GatewayTcpHost()
.Builder();
//.Replace<>;
});
var build = serverHostBuilder.Build();
build.Start();
ServiceProvider = build.Services;
JT808Serializer = ServiceProvider.GetRequiredService<IJT808Config>().GetSerializer();
}
}
}

+ 92
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/JT808SessionServiceTest.cs View File

@@ -0,0 +1,92 @@
using JT808.Protocol;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using JT808.Protocol.Extensions;
using Xunit;
using JT808.Gateway.Simples;
using JT808.Gateway.Interfaces;
using JT808.Gateway.Session;

namespace JT808.Gateway.Test.Udp
{
public class JT808SessionServiceTest:TestBase,IDisposable
{
static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 818);
JT808SimpleUdpClient SimpleUdpClient1;
JT808SimpleUdpClient SimpleUdpClient2;
JT808SimpleUdpClient SimpleUdpClient3;
JT808SimpleUdpClient SimpleUdpClient4;
JT808SimpleUdpClient SimpleUdpClient5;

public void Dispose()
{
SimpleUdpClient1.Down();
SimpleUdpClient2.Down();
SimpleUdpClient3.Down();
SimpleUdpClient4.Down();
SimpleUdpClient5.Down();
}

public JT808SessionServiceTest()
{
SimpleUdpClient1 = new JT808SimpleUdpClient(endPoint);
SimpleUdpClient2 = new JT808SimpleUdpClient(endPoint);
SimpleUdpClient3 = new JT808SimpleUdpClient(endPoint);
SimpleUdpClient4 = new JT808SimpleUdpClient(endPoint);
SimpleUdpClient5 = new JT808SimpleUdpClient(endPoint);
// 心跳会话包
JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001");
SimpleUdpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1));

// 心跳会话包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002");
SimpleUdpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2));

// 心跳会话包
JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003");
SimpleUdpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3));

// 心跳会话包
JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004");
SimpleUdpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4));

// 心跳会话包
JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005");
SimpleUdpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5));
Thread.Sleep(1000);
}

[Fact]
public void Test1()
{
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
var result = jT808SessionServiceDefaultImpl.GetUdpAll();
}

[Fact]
public void Test2()
{
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
var result1 = jT808SessionServiceDefaultImpl.GetUdpAll();
var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001");
var result3 = jT808SessionServiceDefaultImpl.GetUdpAll();
}

[Fact]
public void Test3()
{
// 判断通道是否关闭
IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
JT808SessionManager jT808UdpSessionManager = ServiceProvider.GetService<JT808SessionManager>();
var result1 = jT808SessionServiceDefaultImpl.GetUdpAll();
SimpleUdpClient1.Down();
var session = jT808UdpSessionManager.GetSessionByTerminalPhoneNo("123456789001");
var result3 = jT808UdpSessionManager.GetUdpAll();
Thread.Sleep(100000);
}
}
}

+ 76
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/JT808UnificationUdpSendServiceTest.cs View File

@@ -0,0 +1,76 @@
using JT808.Protocol;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using JT808.Protocol.Extensions;
using JT808.Protocol.MessageBody;
using JT808.Gateway.Interfaces;
using JT808.Gateway.Simples;
using JT808.Gateway.Dtos;
using Xunit;

namespace JT808.Gateway.Test.Udp
{

public class JT808UnificationUdpSendServiceTest : TestBase
{
static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 818);

private IJT808UnificationSendService jT808UnificationSendService;
private IJT808SessionService jT808SessionServiceDefaultImpl;

public JT808UnificationUdpSendServiceTest()
{
JT808SimpleUdpClient SimpleUdpClient1 = new JT808SimpleUdpClient(endPoint);
JT808SimpleUdpClient SimpleUdpClient2 = new JT808SimpleUdpClient(endPoint);
JT808SimpleUdpClient SimpleUdpClient3 = new JT808SimpleUdpClient(endPoint);
JT808SimpleUdpClient SimpleUdpClient4 = new JT808SimpleUdpClient(endPoint);
JT808SimpleUdpClient SimpleUdpClient5 = new JT808SimpleUdpClient(endPoint);
// 心跳会话包
JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001");
SimpleUdpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1));

// 心跳会话包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002");
SimpleUdpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2));

// 心跳会话包
JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003");
SimpleUdpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3));

// 心跳会话包
JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004");
SimpleUdpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4));

// 心跳会话包
JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005");
SimpleUdpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5));

Thread.Sleep(300);
}

[Fact]
public void Test1()
{
//"126 131 0 0 13 18 52 86 120 144 1 0 11 5 115 109 97 108 108 99 104 105 32 53 49 56 24 126"
jT808SessionServiceDefaultImpl = ServiceProvider.GetService<IJT808SessionService>();
jT808UnificationSendService = ServiceProvider.GetService<IJT808UnificationSendService>();
jT808SessionServiceDefaultImpl.GetUdpAll();
string no = "123456789001";
// 文本信息包
JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.文本信息下发.Create(no, new JT808_0x8300
{
TextFlag = 5,
TextInfo = "smallchi 518"
});
var data = JT808Serializer.Serialize(jT808Package2);
JT808ResultDto<bool> jt808Result = jT808UnificationSendService.Send(no, data);
Thread.Sleep(1000);
Assert.Equal(200, jt808Result.Code);
Assert.True(jt808Result.Data);
}
}
}

+ 41
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/Udp/TestBase.cs View File

@@ -0,0 +1,41 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using JT808.Protocol;
using JT808.Protocol.Interfaces;
using JT808.Gateway.Udp;
using System.IO;

namespace JT808.Gateway.Test.Udp
{
public class TestBase
{
public static IServiceProvider ServiceProvider;
public static JT808Serializer JT808Serializer;
static TestBase()
{
var serverHostBuilder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Udp"));
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddJT808Configure()
.AddJT808Gateway(hostContext.Configuration)
.AddJT808GatewayUdpHost();
});
var build = serverHostBuilder.Build();
build.Start();
ServiceProvider = build.Services;
JT808Serializer = ServiceProvider.GetRequiredService<IJT808Config>().GetSerializer();
}
}
}

+ 24
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/JT808.Gateway.Traffic.Test.csproj View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 40
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/JT808DotNettyTrafficServiceTest.cs View File

@@ -0,0 +1,40 @@
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol.Extensions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.Traffic.Test
{
public class JT808DotNettyTrafficServiceTest
{
private readonly CSRedis.CSRedisClient redisClien;
public readonly ILogger<JT808DotNettyTrafficServiceTest> logger;
public JT808DotNettyTrafficServiceTest(ILoggerFactory loggerFactory) {
redisClien = new CSRedis.CSRedisClient("127.0.0.1:6379,password=smallchi");
RedisHelper.Initialization(redisClien);
logger = loggerFactory.CreateLogger<JT808DotNettyTrafficServiceTest>();
Task.Run(() => {
while (true)
{
Thread.Sleep(5000);
using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(new JT808MsgProducerConfig
{
BootstrapServers = "127.0.0.1:9092",
TopicName = "JT808Msg"
}))
{
jT808MsgProducer.ProduceAsync("011111111111", "7E02000032011111111111012E00000000000C00000160E42506C30C82002C00000000180914142057010400001DC003020000250400000000300115310100977E".ToHexBytes()).Wait();
}
var length= RedisHelper.HGet("011111111111", DateTime.Now.ToString("yyyyMMdd"));
logger.LogDebug($"{011111111111}:{length}");
}
});
}
}
}

+ 44
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Traffic.Test/Program.cs View File

@@ -0,0 +1,44 @@
using JT808.Gateway.BusinessServices.Traffic;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.Traffic.Test
{
class Program
{
async static Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostContext, config) => {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostContext, configLogging) => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddSingleton<JT808DotNettyTrafficServiceTest>();
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddMsgConsumer(hostContext.Configuration)
.AddInprocJT808Traffic();

services.BuildServiceProvider().GetRequiredService<JT808DotNettyTrafficServiceTest>();
})
;

await hostBuilder.RunConsoleAsync();
}
}
}

+ 24
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/JT808.Gateway.Transmit.Test.csproj View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 35
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/JT808DotNettyTransmitServiceTest.cs View File

@@ -0,0 +1,35 @@
using JT808.Gateway.Configs.Kafka;
using JT808.Gateway.Kafka;
using JT808.Gateway.PubSub;
using JT808.Protocol.Extensions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JT808.Gateway.Transmit.Test
{
public class JT808DotNettyTransmitServiceTest
{
public readonly ILogger<JT808DotNettyTransmitServiceTest> logger;
public JT808DotNettyTransmitServiceTest(ILoggerFactory loggerFactory) {
logger = loggerFactory.CreateLogger<JT808DotNettyTransmitServiceTest>();
Task.Run(() => {
while (true)
{
Thread.Sleep(5000);
using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(new JT808MsgProducerConfig
{
BootstrapServers = "127.0.0.1:9092",
TopicName = "JT808Msg"
}))
{
jT808MsgProducer.ProduceAsync("011111111111", "7E02000032011111111111012E00000000000C00000160E42506C30C82002C00000000180914142057010400001DC003020000250400000000300115310100977E".ToHexBytes()).Wait();
}
}
});
}
}
}

+ 43
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Transmit.Test/Program.cs View File

@@ -0,0 +1,43 @@
using JT808.Gateway.BusinessServices.Transmit;
using JT808.Gateway.Kafka;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JT808.Gateway.Transmit.Test
{
class Program
{
async static Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostContext, config) => {
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostContext, configLogging) => {
configLogging.AddConsole();
configLogging.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) => {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddSingleton<JT808DotNettyTransmitServiceTest>();
services.AddJT808Configure()
.AddJT808ClientKafka()
.AddMsgConsumer(hostContext.Configuration)
.AddInprocJT808Transmit(hostContext.Configuration);
services.BuildServiceProvider().GetRequiredService<JT808DotNettyTransmitServiceTest>();
})
;

await hostBuilder.RunConsoleAsync();
}
}
}

+ 65
- 0
src/JT808.Gateway.sln View File

@@ -9,6 +9,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.SimpleServer"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.SimpleClient", "JT808.Gateway.SimpleClient\JT808.Gateway.SimpleClient.csproj", "{886D4937-7265-40DC-87CC-85CE35553214}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.SimpleClient", "JT808.Gateway.SimpleClient\JT808.Gateway.SimpleClient.csproj", "{886D4937-7265-40DC-87CC-85CE35553214}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.Kafka", "JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj", "{790E132C-7D92-4A6A-8CF0-2C181331FB31}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.CleintBenchmark", "JT808.Gateway.CleintBenchmark\JT808.Gateway.CleintBenchmark.csproj", "{1A925C08-2590-4E55-84F2-96F01306D34D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{DC0E0AC1-C4BD-4291-AD16-744080411C3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Traffic.Test", "JT808.Gateway.Tests\JT808.Gateway.Traffic.Test\JT808.Gateway.Traffic.Test.csproj", "{D4DF5285-612A-417D-BDE4-690BDF0C07C6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Transmit.Test", "JT808.Gateway.Tests\JT808.Gateway.Transmit.Test\JT808.Gateway.Transmit.Test.csproj", "{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.SessionNotice.Test", "JT808.Gateway.Tests\JT808.Gateway.SessionNotice.Test\JT808.Gateway.SessionNotice.Test.csproj", "{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ReplyMessage.Test", "JT808.Gateway.Tests\JT808.Gateway.ReplyMessage.Test\JT808.Gateway.ReplyMessage.Test.csproj", "{CDE064DE-0E8E-4165-8F6A-6C03A8783506}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.MsgLogging.Test", "JT808.Gateway.Tests\JT808.Gateway.MsgLogging.Test\JT808.Gateway.MsgLogging.Test.csproj", "{8BD638B1-1F16-4BA8-8506-1B83DA4A884E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.MsgIdHandler.Test", "JT808.Gateway.Tests\JT808.Gateway.MsgIdHandler.Test\JT808.Gateway.MsgIdHandler.Test.csproj", "{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.Test", "JT808.Gateway.Tests\JT808.Gateway.Test\JT808.Gateway.Test.csproj", "{F1031636-69CF-4C44-AF0B-F8BE8DE03864}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -27,10 +47,55 @@ Global
{886D4937-7265-40DC-87CC-85CE35553214}.Debug|Any CPU.Build.0 = Debug|Any CPU {886D4937-7265-40DC-87CC-85CE35553214}.Debug|Any CPU.Build.0 = Debug|Any CPU
{886D4937-7265-40DC-87CC-85CE35553214}.Release|Any CPU.ActiveCfg = Release|Any CPU {886D4937-7265-40DC-87CC-85CE35553214}.Release|Any CPU.ActiveCfg = Release|Any CPU
{886D4937-7265-40DC-87CC-85CE35553214}.Release|Any CPU.Build.0 = Release|Any CPU {886D4937-7265-40DC-87CC-85CE35553214}.Release|Any CPU.Build.0 = Release|Any CPU
{790E132C-7D92-4A6A-8CF0-2C181331FB31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{790E132C-7D92-4A6A-8CF0-2C181331FB31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{790E132C-7D92-4A6A-8CF0-2C181331FB31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{790E132C-7D92-4A6A-8CF0-2C181331FB31}.Release|Any CPU.Build.0 = Release|Any CPU
{1A925C08-2590-4E55-84F2-96F01306D34D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A925C08-2590-4E55-84F2-96F01306D34D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A925C08-2590-4E55-84F2-96F01306D34D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A925C08-2590-4E55-84F2-96F01306D34D}.Release|Any CPU.Build.0 = Release|Any CPU
{D4DF5285-612A-417D-BDE4-690BDF0C07C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4DF5285-612A-417D-BDE4-690BDF0C07C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4DF5285-612A-417D-BDE4-690BDF0C07C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4DF5285-612A-417D-BDE4-690BDF0C07C6}.Release|Any CPU.Build.0 = Release|Any CPU
{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB}.Release|Any CPU.Build.0 = Release|Any CPU
{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE}.Release|Any CPU.Build.0 = Release|Any CPU
{CDE064DE-0E8E-4165-8F6A-6C03A8783506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDE064DE-0E8E-4165-8F6A-6C03A8783506}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDE064DE-0E8E-4165-8F6A-6C03A8783506}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDE064DE-0E8E-4165-8F6A-6C03A8783506}.Release|Any CPU.Build.0 = Release|Any CPU
{8BD638B1-1F16-4BA8-8506-1B83DA4A884E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BD638B1-1F16-4BA8-8506-1B83DA4A884E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BD638B1-1F16-4BA8-8506-1B83DA4A884E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8BD638B1-1F16-4BA8-8506-1B83DA4A884E}.Release|Any CPU.Build.0 = Release|Any CPU
{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E}.Release|Any CPU.Build.0 = Release|Any CPU
{F1031636-69CF-4C44-AF0B-F8BE8DE03864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1031636-69CF-4C44-AF0B-F8BE8DE03864}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1031636-69CF-4C44-AF0B-F8BE8DE03864}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1031636-69CF-4C44-AF0B-F8BE8DE03864}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D4DF5285-612A-417D-BDE4-690BDF0C07C6} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{5E2C290C-637B-4F8B-AE03-1A4B669F7FFB} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{562B16BD-1D4C-40FD-86CF-7845DBC9C1EE} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{CDE064DE-0E8E-4165-8F6A-6C03A8783506} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{8BD638B1-1F16-4BA8-8506-1B83DA4A884E} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{CC2ABC8E-CC78-4B68-8670-90C2BCAB434E} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
{F1031636-69CF-4C44-AF0B-F8BE8DE03864} = {DC0E0AC1-C4BD-4291-AD16-744080411C3D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F5671BD2-B44A-4A7C-80EA-E060A512992D} SolutionGuid = {F5671BD2-B44A-4A7C-80EA-E060A512992D}
EndGlobalSection EndGlobalSection


+ 14
- 0
src/JT808.Gateway/BusinessServices/MsgIdHandler/IJT808MsgIdHandler.cs View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.MsgIdHandler
{
/// <summary>
/// JT808消息Id处理程序
/// </summary>
public interface IJT808MsgIdHandler
{
void Processor((string TerminalNo, byte[] Data) parameter);
}
}

+ 18
- 0
src/JT808.Gateway/BusinessServices/MsgIdHandler/JT808MsgIdHandlerExtensions.cs View File

@@ -0,0 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.MsgIdHandler
{
public static class JT808MsgIdHandlerExtensions
{
public static IJT808ClientBuilder AddJT808MsgIdHandler<TJT808MsgIdHandler>(this IJT808ClientBuilder jT808ClientBuilder)
where TJT808MsgIdHandler: IJT808MsgIdHandler
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton(typeof(IJT808MsgIdHandler),typeof(TJT808MsgIdHandler));
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808MsgIdHandlerHostedService>();
return jT808ClientBuilder;
}
}
}

+ 34
- 0
src/JT808.Gateway/BusinessServices/MsgIdHandler/JT808MsgIdHandlerHostedService.cs View File

@@ -0,0 +1,34 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.MsgIdHandler
{
public class JT808MsgIdHandlerHostedService : IHostedService
{
private readonly IJT808MsgConsumer jT808MsgConsumer;

private readonly IJT808MsgIdHandler jT808MsgIdHandler;
public JT808MsgIdHandlerHostedService(
IJT808MsgIdHandler jT808DotNettyMsgIdHandler,
IJT808MsgConsumer jT808MsgConsumer)
{
this.jT808MsgIdHandler = jT808DotNettyMsgIdHandler;
this.jT808MsgConsumer = jT808MsgConsumer;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Subscribe();
jT808MsgConsumer.OnMessage(jT808MsgIdHandler.Processor);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 15
- 0
src/JT808.Gateway/BusinessServices/MsgLogging/IJT808MsgLogging.cs View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace JT808.Gateway.BusinessServices.MsgLogging
{
/// <summary>
/// 808数据上下行日志接口
/// </summary>
public interface IJT808MsgLogging
{
void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType);
}
}

+ 36
- 0
src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgDownLoggingHostedService.cs View File

@@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.MsgLogging
{
public class JT808MsgDownLoggingHostedService : IHostedService
{
private readonly IJT808MsgReplyConsumer jT808MsgReplyConsumer;
private readonly IJT808MsgLogging jT808MsgLogging;
public JT808MsgDownLoggingHostedService(
IJT808MsgLogging jT808MsgLogging,
IJT808MsgReplyConsumer jT808MsgReplyConsumer)
{
this.jT808MsgReplyConsumer = jT808MsgReplyConsumer;
this.jT808MsgLogging = jT808MsgLogging;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgReplyConsumer.Subscribe();
jT808MsgReplyConsumer.OnMessage(item=>
{
jT808MsgLogging.Processor(item, JT808MsgLoggingType.down);
});
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgReplyConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 19
- 0
src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgLoggingExtensions.cs View File

@@ -0,0 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.MsgLogging
{
public static class JT808MsgLoggingExtensions
{
public static IJT808ClientBuilder AddJT808MsgLogging<TJT808MsgLogging>(this IJT808ClientBuilder jT808ClientBuilder)
where TJT808MsgLogging: IJT808MsgLogging
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton(typeof(IJT808MsgLogging),typeof(TJT808MsgLogging));
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808MsgDownLoggingHostedService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808MsgUpLoggingHostedService>();
return jT808ClientBuilder;
}
}
}

+ 18
- 0
src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgLoggingType.cs View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.MsgLogging
{
public enum JT808MsgLoggingType
{
/// <summary>
/// 数据上行
/// </summary>
up,
/// <summary>
/// 数据下行
/// </summary>
down
}
}

+ 36
- 0
src/JT808.Gateway/BusinessServices/MsgLogging/JT808MsgUpLoggingHostedService.cs View File

@@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.MsgLogging
{
public class JT808MsgUpLoggingHostedService : IHostedService
{
private readonly IJT808MsgConsumer jT808MsgConsumer;
private readonly IJT808MsgLogging jT808MsgLogging;
public JT808MsgUpLoggingHostedService(
IJT808MsgLogging jT808MsgLogging,
IJT808MsgConsumer jT808MsgConsumer)
{
this.jT808MsgConsumer = jT808MsgConsumer;
this.jT808MsgLogging = jT808MsgLogging;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Subscribe();
jT808MsgConsumer.OnMessage(item=>
{
jT808MsgLogging.Processor(item, JT808MsgLoggingType.up);
});
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 57
- 0
src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageExtensions.cs View File

@@ -0,0 +1,57 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.ReplyMessage
{
public static class JT808ReplyMessageExtensions
{
/// <summary>
/// 独享消息应答服务(不同的消费者实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808ReplyMessageService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808ReplyMessageHostedService>();
return jT808ClientBuilder;
}
/// <summary>
/// 独享消息应答服务(不同的消费者实例)
/// </summary>
/// <typeparam name="TReplyMessageService">自定义消息回复服务</typeparam>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808ReplyMessage<TReplyMessageService>(this IJT808ClientBuilder jT808ClientBuilder)
where TReplyMessageService : JT808ReplyMessageService
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808ReplyMessageService,TReplyMessageService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808ReplyMessageHostedService>();
return jT808ClientBuilder;
}
/// <summary>
/// 共享消息应答服务(消费者单实例)
/// </summary>
/// <typeparam name="TReplyMessageService">自定义消息回复服务</typeparam>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808ReplyMessage<TReplyMessageService>(this IJT808ClientBuilder jT808ClientBuilder)
where TReplyMessageService : JT808ReplyMessageService
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808ReplyMessageService, TReplyMessageService>();
return jT808ClientBuilder;
}
/// <summary>
/// 共享消息应答服务(消费者单实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808ReplyMessageService>();
return jT808ClientBuilder;
}
}
}

+ 34
- 0
src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageHostedService.cs View File

@@ -0,0 +1,34 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.ReplyMessage
{
public class JT808ReplyMessageHostedService : IHostedService
{
private readonly IJT808MsgConsumer jT808MsgConsumer;
private readonly JT808ReplyMessageService jT808DotNettyReplyMessageService;

public JT808ReplyMessageHostedService(
JT808ReplyMessageService jT808DotNettyReplyMessageService,
IJT808MsgConsumer jT808MsgConsumer)
{
this.jT808MsgConsumer = jT808MsgConsumer;
this.jT808DotNettyReplyMessageService = jT808DotNettyReplyMessageService;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Subscribe();
jT808MsgConsumer.OnMessage(jT808DotNettyReplyMessageService.Processor);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 165
- 0
src/JT808.Gateway/BusinessServices/ReplyMessage/JT808ReplyMessageService.cs View File

@@ -0,0 +1,165 @@
using JT808.Gateway.PubSub;
using JT808.Protocol;
using JT808.Protocol.Enums;
using JT808.Protocol.Extensions;
using JT808.Protocol.MessageBody;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.ReplyMessage
{
public class JT808ReplyMessageService
{
protected Dictionary<ushort, Func<JT808HeaderPackage, byte[]>> HandlerDict { get; }

protected JT808Serializer JT808Serializer { get; }
protected IJT808MsgReplyProducer JT808MsgReplyProducer { get; }
public JT808ReplyMessageService(
IJT808Config jT808Config,
IJT808MsgReplyProducer jT808MsgReplyProducer)
{
this.JT808Serializer = jT808Config.GetSerializer();
this.JT808MsgReplyProducer = jT808MsgReplyProducer;
HandlerDict = new Dictionary<ushort, Func<JT808HeaderPackage, byte[]>> {
{JT808MsgId.终端通用应答.ToUInt16Value(), Msg0x0001},
{JT808MsgId.终端鉴权.ToUInt16Value(), Msg0x0102},
{JT808MsgId.终端心跳.ToUInt16Value(), Msg0x0002},
{JT808MsgId.终端注销.ToUInt16Value(), Msg0x0003},
{JT808MsgId.终端注册.ToUInt16Value(), Msg0x0100},
{JT808MsgId.位置信息汇报.ToUInt16Value(),Msg0x0200 },
{JT808MsgId.定位数据批量上传.ToUInt16Value(),Msg0x0704 },
{JT808MsgId.数据上行透传.ToUInt16Value(),Msg0x0900 }
};
}

public virtual void Processor((string TerminalNo, byte[] Data) parameter)
{
try
{
var request = JT808Serializer.HeaderDeserialize(parameter.Data);
if (HandlerDict.TryGetValue(request.Header.MsgId, out var func))
{
var buffer = func(request);
if (buffer != null)
{
JT808MsgReplyProducer.ProduceAsync(parameter.TerminalNo, buffer);
}
}
}
catch
{
}
}

/// <summary>
/// 终端通用应答
/// 平台无需回复
/// 实现自己的业务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0001(JT808HeaderPackage request)
{
return null;
}
/// <summary>
/// 终端心跳
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0002(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 终端注销
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0003(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 终端注册
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0100(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.终端注册应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8100()
{
Code = "J" + request.Header.TerminalPhoneNo,
JT808TerminalRegisterResult = JT808TerminalRegisterResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 终端鉴权
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0102(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 位置信息汇报
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0200(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 定位数据批量上传
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0704(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
/// <summary>
/// 数据上行透传
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public virtual byte[] Msg0x0900(JT808HeaderPackage request)
{
return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001()
{
MsgId = request.Header.MsgId,
JT808PlatformResult = JT808PlatformResult.成功,
MsgNum = request.Header.MsgNum
}));
}
}
}

+ 60
- 0
src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeExtensions.cs View File

@@ -0,0 +1,60 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.SessionNotice
{
public static class JT808SessionNoticeExtensions
{
/// <summary>
/// 独享消息会话通知服务(不同的消费者实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808SessionNoticeService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808SessionNoticeHostedService>();
return jT808ClientBuilder;
}

/// <summary>
/// 独享消息会话通知服务(不同的消费者实例)
/// </summary>
/// <typeparam name="TSessionNoticeService">自定义会话通知服务</typeparam>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808SessionNotice<TSessionNoticeService>(this IJT808ClientBuilder jT808ClientBuilder)
where TSessionNoticeService : JT808SessionNoticeService
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808SessionNoticeService,TSessionNoticeService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808SessionNoticeHostedService>();
return jT808ClientBuilder;
}

/// <summary>
/// 共享消息会话通知服务(消费者单实例)
/// </summary>
/// <typeparam name="TSessionNoticeService">自定义会话通知服务</typeparam>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808SessionNotice<TSessionNoticeService>(this IJT808ClientBuilder jT808ClientBuilder)
where TSessionNoticeService : JT808SessionNoticeService
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808SessionNoticeService, TSessionNoticeService>();
return jT808ClientBuilder;
}

/// <summary>
/// 共享消息会话通知服务(消费者单实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808SessionNoticeService>();
return jT808ClientBuilder;
}
}
}

+ 35
- 0
src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeHostedService.cs View File

@@ -0,0 +1,35 @@
using System.Threading.Tasks;
using JT808.Protocol;
using JT808.Protocol.Interfaces;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.SessionNotice
{
public class JT808SessionNoticeHostedService : IHostedService
{
private readonly JT808SessionNoticeService jT808DotNettySessionNoticeService;
private readonly IJT808SessionConsumer jT808SessionConsumer;
public JT808SessionNoticeHostedService(
IJT808SessionConsumer jT808SessionConsumer,
JT808SessionNoticeService jT808DotNettySessionNoticeService)
{
this.jT808DotNettySessionNoticeService = jT808DotNettySessionNoticeService;
this.jT808SessionConsumer = jT808SessionConsumer;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808SessionConsumer.Subscribe();
jT808SessionConsumer.OnMessage(jT808DotNettySessionNoticeService.Processor);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808SessionConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 24
- 0
src/JT808.Gateway/BusinessServices/SessionNotice/JT808SessionNoticeService.cs View File

@@ -0,0 +1,24 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.SessionNotice
{
public class JT808SessionNoticeService
{
protected ILogger logger { get; }
public JT808SessionNoticeService(ILoggerFactory loggerFactory)
{
logger = loggerFactory.CreateLogger("JT808DotNettySessionNoticeService");
}
public virtual void Processor((string Notice, string TerminalNo) parameter)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"{parameter.Notice}-{parameter.TerminalNo}");
}
}
}
}

+ 32
- 0
src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficService.cs View File

@@ -0,0 +1,32 @@
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.Traffic
{
public class JT808TrafficService:IDisposable
{
private readonly CSRedis.CSRedisClient redisClien;
public JT808TrafficService(IConfiguration configuration)
{
redisClien = new CSRedis.CSRedisClient(configuration.GetConnectionString("TrafficRedisHost"));
TrafficRedisClient.Initialization(redisClien);
}

public void Dispose()
{
redisClien.Dispose();
}

/// <summary>
/// 按设备每天统计sim卡流量
/// </summary>
/// <param name="terminalNo"></param>
/// <param name="len"></param>
public void Processor(string terminalNo,int len)
{
TrafficRedisClient.HIncrBy(terminalNo, DateTime.Now.ToString("yyyyMMdd"), len);
}
}
}

+ 33
- 0
src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficServiceExtensions.cs View File

@@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.Traffic
{
public static class JT808TrafficServiceExtensions
{
/// <summary>
/// 独享消息流量统计服务(不同的消费者实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808Traffic(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808TrafficService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808TrafficServiceHostedService>();
return jT808ClientBuilder;
}
/// <summary>
/// 共享消息流量统计服务(消费者单实例)
/// </summary>
/// <typeparam name="TReplyMessageService"></typeparam>
/// <param name="jT808ClientBuilder"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808Traffic(this IJT808ClientBuilder jT808ClientBuilder)
{
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808TrafficService>();
return jT808ClientBuilder;
}
}
}

+ 38
- 0
src/JT808.Gateway/BusinessServices/Traffic/JT808TrafficServiceHostedService.cs View File

@@ -0,0 +1,38 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Protocol.Extensions;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.Traffic
{
public class JT808TrafficServiceHostedService : IHostedService
{
private readonly IJT808MsgConsumer jT808MsgConsumer;
private readonly JT808TrafficService jT808DotNettyTrafficService;

public JT808TrafficServiceHostedService(
JT808TrafficService jT808DotNettyTrafficService,
IJT808MsgConsumer jT808MsgConsumer)
{
this.jT808MsgConsumer = jT808MsgConsumer;
this.jT808DotNettyTrafficService = jT808DotNettyTrafficService;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Subscribe();
jT808MsgConsumer.OnMessage((item)=> {
string str = item.Data.ToHexString();
jT808DotNettyTrafficService.Processor(item.TerminalNo, item.Data.Length);
});
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 9
- 0
src/JT808.Gateway/BusinessServices/Traffic/TrafficRedisClient.cs View File

@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.Traffic
{
class TrafficRedisClient: RedisHelper<TrafficRedisClient>
{ }
}

+ 13
- 0
src/JT808.Gateway/BusinessServices/Transmit/Configs/DataTransferOptions.cs View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.Transmit.Configs
{
public class DataTransferOptions
{
public string Host { get; set; }

public List<string> TerminalNos { get; set; }
}
}

+ 11
- 0
src/JT808.Gateway/BusinessServices/Transmit/Configs/RemoteServerOptions.cs View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.BusinessServices.Transmit.Configs
{
public class RemoteServerOptions
{
public List<DataTransferOptions> DataTransfer { get; set; }
}
}

+ 76
- 0
src/JT808.Gateway/BusinessServices/Transmit/Handlers/ClientConnectionHandler.cs View File

@@ -0,0 +1,76 @@
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using Polly;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Microsoft.Extensions.Logging;

namespace JT808.Gateway.BusinessServices.Transmit.Handlers
{
public class ClientConnectionHandler : ChannelHandlerAdapter
{
private readonly Bootstrap bootstrap;
public Dictionary<string, IChannel> channeldic;
private readonly ILogger<ClientConnectionHandler> logger;
public ClientConnectionHandler(Bootstrap bootstrap,
Dictionary<string, IChannel> channeldic,
ILoggerFactory loggerFactory)
{
this.bootstrap = bootstrap;
this.channeldic = channeldic;
logger = loggerFactory.CreateLogger<ClientConnectionHandler>();
}
public override void ChannelInactive(IChannelHandlerContext context)
{
Policy.HandleResult<bool>(context.Channel.Open)
.WaitAndRetryForeverAsync(retryAttempt =>
{
return retryAttempt > 20 ? TimeSpan.FromSeconds(Math.Pow(2, 50)) : TimeSpan.FromSeconds(Math.Pow(2, retryAttempt));//超过重试20次,之后重试都是接近12个小时重试一次
},
(exception, timespan, ctx) =>
{
logger.LogError($"服务端断开{context.Channel.RemoteAddress},重试结果{exception.Result},重试次数{timespan},下次重试间隔(s){ctx.TotalSeconds}");
})
.ExecuteAsync(async () =>
{
try
{
var oldChannel = channeldic.FirstOrDefault(m => m.Value == context.Channel);
if (default(KeyValuePair<string, IChannel>).Equals(oldChannel))
{
if(logger.IsEnabled( LogLevel.Debug))
logger.LogDebug($"服务器已经删除了{oldChannel.Key}远程服务器配置");
return true;
}
var channel = await bootstrap.ConnectAsync(context.Channel.RemoteAddress);
channeldic.Remove(oldChannel.Key);
channeldic.Add(oldChannel.Key, channel);
return channel.Open;
}
catch (Exception ex)
{
logger.LogError($"服务端断开后{context.Channel.RemoteAddress},重连异常:{ex}");
return false;
}
});
}

public override void ChannelRead(IChannelHandlerContext context, object message)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogError($"服务端返回消息{message}");
}
}

public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
logger.LogError($"服务端Exception: {exception}");
context.CloseAsync();
}
}
}

+ 39
- 0
src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitExtensions.cs View File

@@ -0,0 +1,39 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
using JT808.Protocol;
using Microsoft.Extensions.Configuration;
using JT808.Gateway.BusinessServices.Transmit.Configs;

namespace JT808.Gateway.BusinessServices.Transmit
{
public static class JT808DotNettyTransmitExtensions
{
/// <summary>
/// 独享转发服务(不同的消费者实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddInprocJT808Transmit(this IJT808ClientBuilder jT808ClientBuilder,IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<RemoteServerOptions>(configuration.GetSection("RemoteServerOptions"));
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808DotNettyTransmitService>();
jT808ClientBuilder.JT808Builder.Services.AddHostedService<JT808DotNettyTransmitHostedService>();
return jT808ClientBuilder;
}
/// <summary>
/// 共享转发服务(消费者单实例)
/// </summary>
/// <param name="jT808ClientBuilder"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static IJT808ClientBuilder AddShareJT808Transmit(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration)
{
jT808ClientBuilder.JT808Builder.Services.Configure<RemoteServerOptions>(configuration.GetSection("RemoteServerOptions"));
jT808ClientBuilder.JT808Builder.Services.AddSingleton<JT808DotNettyTransmitService>();
return jT808ClientBuilder;
}
}
}

+ 33
- 0
src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitHostedService.cs View File

@@ -0,0 +1,33 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using System.Threading;
using JT808.Gateway.PubSub;

namespace JT808.Gateway.BusinessServices.Transmit
{
public class JT808DotNettyTransmitHostedService:IHostedService
{
private readonly JT808DotNettyTransmitService jT808DotNettyTransmitService;
private readonly IJT808MsgConsumer jT808MsgConsumer;
public JT808DotNettyTransmitHostedService(
IJT808MsgConsumer jT808MsgConsumer,
JT808DotNettyTransmitService jT808DotNettyTransmitService)
{
this.jT808DotNettyTransmitService = jT808DotNettyTransmitService;
this.jT808MsgConsumer = jT808MsgConsumer;
}

public Task StartAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Subscribe();
jT808MsgConsumer.OnMessage(jT808DotNettyTransmitService.Send);
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
jT808MsgConsumer.Unsubscribe();
return Task.CompletedTask;
}
}
}

+ 236
- 0
src/JT808.Gateway/BusinessServices/Transmit/JT808DotNettyTransmitService.cs View File

@@ -0,0 +1,236 @@
using DotNetty.Buffers;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Linq;
using JT808.Gateway.BusinessServices.Transmit.Configs;
using JT808.Gateway.BusinessServices.Transmit.Handlers;

namespace JT808.Gateway.BusinessServices.Transmit
{
public class JT808DotNettyTransmitService
{
private readonly ILogger logger;
private readonly ILoggerFactory loggerFactory;
private IOptionsMonitor<RemoteServerOptions> optionsMonitor;
public Dictionary<string, IChannel> channeldic = new Dictionary<string, IChannel>();
public JT808DotNettyTransmitService(ILoggerFactory loggerFactory,
IOptionsMonitor<RemoteServerOptions> optionsMonitor)
{
this.loggerFactory = loggerFactory;
logger = loggerFactory.CreateLogger("JT808DotNettyTransmitService");
this.optionsMonitor = optionsMonitor;
InitialDispatcherClient();
}
public void Send((string TerminalNo, byte[] Data) parameter)
{
if (optionsMonitor.CurrentValue.DataTransfer != null)
{
foreach (var item in optionsMonitor.CurrentValue.DataTransfer)
{
if (channeldic.TryGetValue($"all_{item.Host}", out var allClientChannel))
{
try
{
if (allClientChannel.Open)
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug($"转发所有数据到该网关{item.Host}");
}
allClientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(parameter.Data));
}
else
{
logger.LogError($"{item.Host}链接已关闭");
}
}
catch (Exception ex)
{
logger.LogError($"{item.Host}发送数据出现异常:{ex}");
}
}
else
{
if (item.TerminalNos.Contains(parameter.TerminalNo) && channeldic.TryGetValue($"{parameter.TerminalNo}_{item.Host}", out var clientChannel))
{
try
{
if (clientChannel.Open)
{
if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
logger.LogDebug($"转发{parameter.TerminalNo}到该网关{item.Host}");
clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(parameter.Data));
}
else
{
logger.LogError($"{item.Host},{parameter.TerminalNo}链接已关闭");
}
}
catch (Exception ex)
{
logger.LogError($"{item.Host},{parameter.TerminalNo}发送数据出现异常:{ex}");
}
}
}
}
}
}

public void InitialDispatcherClient()
{
Task.Run(async () =>
{
var group = new MultithreadEventLoopGroup();
var bootstrap = new Bootstrap();
bootstrap.Group(group)
.Channel<TcpSocketChannel>()
.Option(ChannelOption.TcpNodelay, true)
.Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
{
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast(new ClientConnectionHandler(bootstrap, channeldic, loggerFactory));
}));
optionsMonitor.OnChange(options =>
{
List<string> lastRemoteServers = new List<string>();
if (options.DataTransfer != null)
{
if (options.DataTransfer.Any())
{
foreach (var item in options.DataTransfer)
{
if (item.TerminalNos != null)
{
if (item.TerminalNos.Any())
{
foreach (var terminal in item.TerminalNos)
{
lastRemoteServers.Add($"{terminal}_{item.Host}");
}
}
else
{
lastRemoteServers.Add($"all_{item.Host}");
}
}
else
{
lastRemoteServers.Add($"all_{item.Host}");
}
}
}
}
DelRemoteServsers(lastRemoteServers);
AddRemoteServsers(bootstrap, lastRemoteServers);
});
await InitRemoteServsers(bootstrap);
});
}
/// <summary>
/// 初始化远程服务器
/// </summary>
/// <param name="bootstrap"></param>
/// <param name="remoteServers"></param>
/// <returns></returns>
private async Task InitRemoteServsers(Bootstrap bootstrap)
{
List<string> remoteServers = new List<string>();
if (optionsMonitor.CurrentValue.DataTransfer != null)
{
if (optionsMonitor.CurrentValue.DataTransfer.Any())
{
foreach (var item in optionsMonitor.CurrentValue.DataTransfer)
{
if (item.TerminalNos != null)
{
if (item.TerminalNos.Any())
{
foreach (var terminal in item.TerminalNos)
{
remoteServers.Add($"{terminal}_{item.Host}");
}
}
else
{
remoteServers.Add($"all_{item.Host}");
}
}
else
{
remoteServers.Add($"all_{item.Host}");
}
}
}
}
foreach (var item in remoteServers)
{
try
{
string ip_port = item.Split('_')[1];
IChannel clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip_port.Split(':')[0]), int.Parse(ip_port.Split(':')[1])));
channeldic.Add(item, clientChannel);
if (clientChannel.Open)
{
if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
logger.LogDebug($"该终端{item.Replace("_", "已连接上该服务器")}");
}
}
}
catch (Exception ex)
{
logger.LogError($"初始化配置链接远程服务端{item},链接异常:{ex}");
}
}
await Task.CompletedTask;
}
/// <summary>
/// 动态删除远程服务器
/// </summary>
/// <param name="lastRemoteServers"></param>
private void DelRemoteServsers(List<string> lastRemoteServers)
{
var delChannels = channeldic.Keys.Except(lastRemoteServers).ToList();
foreach (var item in delChannels)
{
channeldic[item].CloseAsync();
channeldic.Remove(item);
}
}
/// <summary>
/// 动态添加远程服务器
/// </summary>
/// <param name="bootstrap"></param>
/// <param name="lastRemoteServers"></param>
private void AddRemoteServsers(Bootstrap bootstrap, List<string> lastRemoteServers)
{
var addChannels = lastRemoteServers.Except(channeldic.Keys).ToList();
foreach (var item in addChannels)
{
try
{
var ip_port = item.Split('_')[1];
IChannel clientChannel = bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip_port.Split(':')[0]), int.Parse(ip_port.Split(':')[1]))).Result;
channeldic.Add(item, clientChannel);
if (clientChannel.Open) {
if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
logger.LogDebug($"该终端{item.Replace("_", "已连接上该服务器")}");
}
}
}
catch (Exception ex)
{
logger.LogError($"变更配置后链接远程服务端{item},重连异常:{ex}");
}
}
}
}
}

+ 0
- 31
src/JT808.Gateway/Configurations/JT808ClientConfiguration.cs View File

@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace JT808.Gateway.Configurations
{
public class JT808ClientConfiguration
{
public string Host { get; set; }

public int Port { get; set; }

private EndPoint endPoint;

public EndPoint EndPoint
{
get
{
if (endPoint == null)
{
if (IPAddress.TryParse(Host, out IPAddress ip))
{
endPoint = new IPEndPoint(ip, Port);
}
}
return endPoint;
}
}
}
}

+ 0
- 29
src/JT808.Gateway/Converters/JsonByteArrayHexConverter.cs View File

@@ -1,29 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JT808.Gateway.Converters
{
class ByteArrayHexConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(byte[]);

public override bool CanRead => false;
public override bool CanWrite => true;

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException();

private readonly string _separator;

public ByteArrayHexConverter(string separator = " ") => _separator = separator;

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var hexString = string.Join(_separator, ((byte[])value).Select(p => p.ToString("X2")));
writer.WriteValue(hexString);
}
}
}

+ 0
- 26
src/JT808.Gateway/Converters/JsonIPAddressConverter.cs View File

@@ -1,26 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace JT808.Gateway.Converters
{
public class JsonIPAddressConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IPAddress));
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return IPAddress.Parse((string)reader.Value);
}
}
}

+ 0
- 32
src/JT808.Gateway/Converters/JsonIPEndPointConverter.cs View File

@@ -1,32 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net;

namespace JT808.Gateway.Converters
{
public class JsonIPEndPointConverter: JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IPEndPoint));
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IPEndPoint ep = (IPEndPoint)value;
JObject jo = new JObject();
jo.Add("Host", JToken.FromObject(ep.Address, serializer));
jo.Add("Port", ep.Port);
jo.WriteTo(writer);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
IPAddress address = jo["Host"].ToObject<IPAddress>(serializer);
int port = (int)jo["Port"];
return new IPEndPoint(address, port);
}
}
}

+ 0
- 12
src/JT808.Gateway/Dtos/JT808AtomicCounterDto.cs View File

@@ -1,12 +0,0 @@
namespace JT808.Gateway.Dtos
{
/// <summary>
/// 包计数器服务
/// </summary>
public class JT808AtomicCounterDto
{
public long MsgSuccessCount { get; set; }

public long MsgFailCount { get; set; }
}
}

+ 0
- 15
src/JT808.Gateway/Dtos/JT808DefaultResultDto.cs View File

@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT808.Gateway.Dtos
{
public class JT808DefaultResultDto: JT808ResultDto<string>
{
public JT808DefaultResultDto()
{
Data = "Hello,JT808 WebAPI";
Code = JT808ResultCode.Ok;
}
}
}

+ 0
- 37
src/JT808.Gateway/Dtos/JT808IPAddressDto.cs View File

@@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.Serialization;
using System.Text;

namespace JT808.Gateway.Dtos
{
public class JT808IPAddressDto
{
public string Host { get; set; }

public int Port { get; set; }

public EndPoint endPoint;

public EndPoint EndPoint
{
get
{
if (endPoint == null)
{
if (IPAddress.TryParse(Host, out IPAddress ip))
{
endPoint = new IPEndPoint(ip, Port);
}
else
{
endPoint = new DnsEndPoint(Host, Port);
}
}
return endPoint;
}
set { }
}
}
}

+ 0
- 11
src/JT808.Gateway/Dtos/JT808UnificationSendRequestDto.cs View File

@@ -1,11 +0,0 @@
namespace JT808.Gateway.Dtos
{
/// <summary>
/// 统一下发请求参数
/// </summary>
public class JT808UnificationSendRequestDto
{
public string TerminalPhoneNo { get; set; }
public byte[] Data { get; set; }
}
}

+ 0
- 91
src/JT808.Gateway/Handlers/JT808MsgIdHttpHandlerBase.cs View File

@@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using JT808.Gateway.Dtos;
using JT808.Gateway.Metadata;
using Newtonsoft.Json;

namespace JT808.Gateway.Handlers
{
/// <summary>
/// 基于webapi http模式抽象消息处理业务
/// 自定义消息处理业务
/// 注意:
/// 1.ConfigureServices:
/// services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHttpHandlerBase),typeof(JT808MsgIdCustomHttpHandlerImpl),ServiceLifetime.Singleton));
/// 2.解析具体的消息体,具体消息调用具体的JT808Serializer.Deserialize<T>
/// </summary>
public abstract class JT808MsgIdHttpHandlerBase
{
/// <summary>
/// 初始化消息处理业务
/// </summary>
protected JT808MsgIdHttpHandlerBase()
{
HandlerDict = new Dictionary<string, Func<JT808HttpRequest, JT808HttpResponse>>();
}

protected void CreateRoute(string url, Func<JT808HttpRequest, JT808HttpResponse> func)
{
if (!HandlerDict.ContainsKey(url))
{
HandlerDict.Add(url, func);
}
else
{
// 替换
HandlerDict[url] = func;
}
}

public Dictionary<string, Func<JT808HttpRequest, JT808HttpResponse>> HandlerDict { get; }

protected JT808HttpResponse CreateJT808HttpResponse(dynamic dynamicObject)
{
byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(dynamicObject));
return new JT808HttpResponse()
{
Data = data
};
}

public JT808HttpResponse DefaultHttpResponse()
{
byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808DefaultResultDto()));
return new JT808HttpResponse(json);
}

public JT808HttpResponse EmptyHttpResponse()
{
byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto<string>()
{
Code = JT808ResultCode.Empty,
Message = "内容为空",
Data = "Content Empty"
}));
return new JT808HttpResponse(json);
}

public JT808HttpResponse NotFoundHttpResponse()
{
byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto<string>()
{
Code = JT808ResultCode.NotFound,
Message = "没有该服务",
Data = "没有该服务"
}));
return new JT808HttpResponse(json);
}

public JT808HttpResponse ErrorHttpResponse(Exception ex)
{
byte[] json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new JT808ResultDto<string>()
{
Code = JT808ResultCode.Error,
Message = JsonConvert.SerializeObject(ex),
Data = ex.Message
}));
return new JT808HttpResponse(json);
}
}
}

+ 6
- 3
src/JT808.Gateway/JT808.Gateway.csproj View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
<Copyright>Copyright 2018.</Copyright> <Copyright>Copyright 2018.</Copyright>
<Authors>SmallChi(Koike)</Authors> <Authors>SmallChi(Koike)</Authors>
@@ -14,12 +14,15 @@
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<PackageLicenseFile>LICENSE</PackageLicenseFile> <PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageId>JT808.Gateway</PackageId>
<Product>JT808.Gateway</Product>
</PropertyGroup> </PropertyGroup>


<ItemGroup> <ItemGroup>
<Protobuf Include="Protos\JT808Gateway.proto"/>
<Protobuf Include="Protos\JT808Gateway.proto" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CSRedisCore" Version="3.1.10" />
<PackageReference Include="Google.Protobuf" Version="3.10.0" /> <PackageReference Include="Google.Protobuf" Version="3.10.0" />
<PackageReference Include="Grpc.Core" Version="2.24.0" /> <PackageReference Include="Grpc.Core" Version="2.24.0" />
<PackageReference Include="Grpc.Tools" Version="2.24.0"> <PackageReference Include="Grpc.Tools" Version="2.24.0">
@@ -32,8 +35,8 @@
<PackageReference Include="DotNetty.Codecs" Version="0.6.0" /> <PackageReference Include="DotNetty.Codecs" Version="0.6.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Microsoft.Extensions.Options" Version="3.0.0" /> <PackageReference Include="Microsoft.Extensions.Options" Version="3.0.0" />
<PackageReference Include="Polly" Version="7.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> <None Include="..\..\LICENSE" Pack="true" PackagePath="" />


+ 3
- 45
src/JT808.Gateway/JT808GatewayExtensions.cs View File

@@ -1,6 +1,5 @@
using JT808.Gateway; using JT808.Gateway;
using JT808.Gateway.Configurations; using JT808.Gateway.Configurations;
using JT808.Gateway.Converters;
using JT808.Gateway.Impls; using JT808.Gateway.Impls;
using JT808.Gateway.Interfaces; using JT808.Gateway.Interfaces;
using JT808.Gateway.PubSub; using JT808.Gateway.PubSub;
@@ -11,47 +10,17 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;


//[assembly: InternalsVisibleTo("JT808.DotNetty.Core.Test")]
[assembly: InternalsVisibleTo("JT808.Gateway.Test")]


namespace JT808.Gateway namespace JT808.Gateway
{ {
public static class JT808GatewayExtensions public static class JT808GatewayExtensions
{ {
static JT808GatewayExtensions()
public static IJT808GatewayBuilder AddJT808Gateway(this IJT808Builder jt808Builder, IConfiguration configuration)
{ {
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings();
//日期类型默认格式化处理
settings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
settings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//空值处理
settings.NullValueHandling = NullValueHandling.Ignore;
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.Converters.Add(new JsonIPAddressConverter());
settings.Converters.Add(new JsonIPEndPointConverter());
settings.Converters.Add(new ByteArrayHexConverter());
return settings;
});
}

public static IJT808GatewayBuilder AddJT808Gateway(this IJT808Builder jt808Builder, IConfiguration configuration, Newtonsoft.Json.JsonSerializerSettings settings=null)
{
if (settings != null)
{
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
settings.Converters.Add(new JsonIPAddressConverter());
settings.Converters.Add(new JsonIPEndPointConverter());
settings.Converters.Add(new ByteArrayHexConverter());
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
return settings;
});
}
IJT808GatewayBuilder nettyBuilder = new JT808GatewayBuilderDefault(jt808Builder); IJT808GatewayBuilder nettyBuilder = new JT808GatewayBuilderDefault(jt808Builder);
nettyBuilder.JT808Builder.Services.Configure<JT808Configuration>(configuration.GetSection("JT808Configuration")); nettyBuilder.JT808Builder.Services.Configure<JT808Configuration>(configuration.GetSection("JT808Configuration"));
nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808AtomicCounterServiceFactory>(); nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808AtomicCounterServiceFactory>();
@@ -66,19 +35,8 @@ namespace JT808.Gateway
return nettyBuilder; return nettyBuilder;
} }


public static IJT808GatewayBuilder AddJT808Gateway(this IJT808Builder jt808Builder, Action<JT808Configuration> jt808Options, Newtonsoft.Json.JsonSerializerSettings settings = null)
public static IJT808GatewayBuilder AddJT808Gateway(this IJT808Builder jt808Builder, Action<JT808Configuration> jt808Options)
{ {
if (settings != null)
{
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
settings.Converters.Add(new JsonIPAddressConverter());
settings.Converters.Add(new JsonIPEndPointConverter());
settings.Converters.Add(new ByteArrayHexConverter());
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
return settings;
});
}
IJT808GatewayBuilder nettyBuilder = new JT808GatewayBuilderDefault(jt808Builder); IJT808GatewayBuilder nettyBuilder = new JT808GatewayBuilderDefault(jt808Builder);
nettyBuilder.JT808Builder.Services.Configure(jt808Options); nettyBuilder.JT808Builder.Services.Configure(jt808Options);
nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808AtomicCounterServiceFactory>(); nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808AtomicCounterServiceFactory>();


+ 20
- 14
src/JT808.Gateway/Services/JT808GatewayService.cs View File

@@ -35,15 +35,18 @@ namespace JT808.Gateway.Services
{ {
var result = jT808SessionService.GetTcpAll(); var result = jT808SessionService.GetTcpAll();
TcpSessionInfoReply reply = new TcpSessionInfoReply(); TcpSessionInfoReply reply = new TcpSessionInfoReply();
foreach(var item in result.Data)
if (result.Data != null)
{ {
reply.TcpSessions.Add(new SessionInfo
foreach (var item in result.Data)
{ {
LastActiveTime= item.LastActiveTime.ToString("yyyy-MM-dd HH:mm:ss"),
StartTime= item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
RemoteAddressIP= item.RemoteAddressIP,
TerminalPhoneNo=item.TerminalPhoneNo
});
reply.TcpSessions.Add(new SessionInfo
{
LastActiveTime = item.LastActiveTime.ToString("yyyy-MM-dd HH:mm:ss"),
StartTime = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
RemoteAddressIP = item.RemoteAddressIP,
TerminalPhoneNo = item.TerminalPhoneNo
});
}
} }
return Task.FromResult(reply); return Task.FromResult(reply);
} }
@@ -58,15 +61,18 @@ namespace JT808.Gateway.Services
{ {
var result = jT808SessionService.GetUdpAll(); var result = jT808SessionService.GetUdpAll();
UdpSessionInfoReply reply = new UdpSessionInfoReply(); UdpSessionInfoReply reply = new UdpSessionInfoReply();
foreach (var item in result.Data)
if (result.Data != null)
{ {
reply.UdpSessions.Add(new SessionInfo
foreach (var item in result.Data)
{ {
LastActiveTime = item.LastActiveTime.ToString("yyyy-MM-dd HH:mm:ss"),
StartTime = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
RemoteAddressIP = item.RemoteAddressIP,
TerminalPhoneNo = item.TerminalPhoneNo
});
reply.UdpSessions.Add(new SessionInfo
{
LastActiveTime = item.LastActiveTime.ToString("yyyy-MM-dd HH:mm:ss"),
StartTime = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
RemoteAddressIP = item.RemoteAddressIP,
TerminalPhoneNo = item.TerminalPhoneNo
});
}
} }
return Task.FromResult(reply); return Task.FromResult(reply);
} }


+ 4
- 4
src/JT808.Gateway/Services/JT808SessionService.cs View File

@@ -36,7 +36,7 @@ namespace JT808.Gateway.Services
{ {
resultDto.Data = null; resultDto.Data = null;
resultDto.Code = JT808ResultCode.Error; resultDto.Code = JT808ResultCode.Error;
resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
resultDto.Message =ex.Message;
} }
return resultDto; return resultDto;
} }
@@ -59,7 +59,7 @@ namespace JT808.Gateway.Services
{ {
resultDto.Data = null; resultDto.Data = null;
resultDto.Code = JT808ResultCode.Error; resultDto.Code = JT808ResultCode.Error;
resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
resultDto.Message = ex.Message;
} }
return resultDto; return resultDto;
} }
@@ -84,13 +84,13 @@ namespace JT808.Gateway.Services
{ {
resultDto.Data = false; resultDto.Data = false;
resultDto.Code = 500; resultDto.Code = 500;
resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
resultDto.Message = ex.Message;
} }
catch (Exception ex) catch (Exception ex)
{ {
resultDto.Data = false; resultDto.Data = false;
resultDto.Code = JT808ResultCode.Error; resultDto.Code = JT808ResultCode.Error;
resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
resultDto.Message = ex.Message;
} }
return resultDto; return resultDto;
} }


+ 1
- 1
src/JT808.Gateway/Services/JT808UnificationSendService.cs View File

@@ -37,7 +37,7 @@ namespace JT808.Gateway.Services
{ {
resultDto.Data = false; resultDto.Data = false;
resultDto.Code = JT808ResultCode.Error; resultDto.Code = JT808ResultCode.Error;
resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
resultDto.Message = ex.Message;
} }
return resultDto; return resultDto;
} }


+ 1
- 1
src/JT808.Gateway/Simples/JT808SimpleTcpClient.cs View File

@@ -5,7 +5,7 @@ using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace JT808.DotNetty.Core
namespace JT808.Gateway.Simples
{ {
internal class JT808SimpleTcpClient internal class JT808SimpleTcpClient
{ {


+ 1
- 1
src/JT808.Gateway/Simples/JT808SimpleUdpClient.cs View File

@@ -5,7 +5,7 @@ using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace JT808.DotNetty.Core
namespace JT808.Gateway.Simples
{ {
internal class JT808SimpleUdpClient internal class JT808SimpleUdpClient
{ {


Loading…
Cancel
Save