From 0bc93cafde17255dce21d5002bc1c472b314531b Mon Sep 17 00:00:00 2001
From: smallchi <564952747@qq.com>
Date: Wed, 23 Oct 2019 18:43:48 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E7=8E=B0=E6=9C=89=E7=9A=84=E9=A1=B9?=
=?UTF-8?q?=E7=9B=AE=E6=95=B4=E5=90=88=E5=88=B0=E4=B8=80=E8=B5=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../JT808.Gateway.SimpleClient.csproj | 18 +
src/JT808.Gateway.SimpleClient/Program.cs | 46 +
.../Services/GrpcClientService.cs | 68 +
.../Services/UpService.cs | 68 +
.../Configs/NLog.xsd | 3106 +++++++++++++++++
.../Configs/nlog.Unix.config | 36 +
.../Configs/nlog.Win32NT.config | 36 +
.../JT808.Gateway.SimpleServer.csproj | 36 +
src/JT808.Gateway.SimpleServer/Program.cs | 70 +
src/JT808.Gateway.sln | 37 +
src/JT808.Gateway/Client/DeviceConfig.cs | 28 +
.../Client/JT808ClientDotnettyExtensions.cs | 23 +
.../Client/JT808ClientMsgSNDistributedImpl.cs | 16 +
src/JT808.Gateway/Client/JT808TcpClient.cs | 112 +
.../Client/JT808TcpClientExtensions.cs | 103 +
.../Client/JT808TcpClientFactory.cs | 62 +
.../Codecs/JT808ClientTcpDecoder.cs | 20 +
.../Codecs/JT808ClientTcpEncoder.cs | 52 +
src/JT808.Gateway/Codecs/JT808TcpDecoder.cs | 32 +
src/JT808.Gateway/Codecs/JT808TcpEncoder.cs | 52 +
src/JT808.Gateway/Codecs/JT808UdpDecoder.cs | 33 +
.../JT808ClientConfiguration.cs | 31 +
.../Configurations/JT808Configuration.cs | 41 +
.../Converters/JsonByteArrayHexConverter.cs | 29 +
.../Converters/JsonIPAddressConverter.cs | 26 +
.../Converters/JsonIPEndPointConverter.cs | 32 +
.../Dtos/JT808AtomicCounterDto.cs | 12 +
.../Dtos/JT808DefaultResultDto.cs | 15 +
src/JT808.Gateway/Dtos/JT808IPAddressDto.cs | 37 +
src/JT808.Gateway/Dtos/JT808ResultDto.cs | 29 +
.../Dtos/JT808TcpSessionInfoDto.cs | 24 +
.../Dtos/JT808UdpSessionInfoDto.cs | 24 +
.../Dtos/JT808UnificationSendRequestDto.cs | 11 +
.../Enums/JT808TransportProtocolType.cs | 15 +
.../Handlers/JT808MsgIdHttpHandlerBase.cs | 91 +
.../JT808TcpClientConnectionHandler.cs | 96 +
.../Handlers/JT808TcpClientHandler.cs | 31 +
.../Handlers/JT808TcpConnectionHandler.cs | 104 +
.../Handlers/JT808TcpServerHandler.cs | 77 +
.../Handlers/JT808UdpServerHandler.cs | 79 +
src/JT808.Gateway/IJT808ClientBuilder.cs | 14 +
src/JT808.Gateway/IJT808GatewayBuilder.cs | 14 +
.../Impls/JT808DatagramPacketImpl.cs | 18 +
.../Impls/JT808GatewayBuilderDefault.cs | 25 +
.../Impls/JT808MsgProducerDefaultImpl.cs | 30 +
.../Impls/JT808MsgReplyConsumerDefaultImpl.cs | 193 +
.../Impls/JT808SessionProducerDefaultImpl.cs | 32 +
.../Interfaces/IJT808DatagramPacket.cs | 13 +
src/JT808.Gateway/Interfaces/IJT808Reply.cs | 17 +
src/JT808.Gateway/Interfaces/IJT808Session.cs | 20 +
.../Interfaces/IJT808SessionService.cs | 30 +
.../IJT808UnificationSendService.cs | 12 +
src/JT808.Gateway/JT808.Gateway.csproj | 42 +
src/JT808.Gateway/JT808GatewayConstants.cs | 48 +
src/JT808.Gateway/JT808GatewayExtensions.cs | 96 +
.../Metadata/JT808AtomicCounter.cs | 49 +
.../Metadata/JT808ClientReport.cs | 16 +
.../Metadata/JT808ClientRequest.cs | 30 +
.../Metadata/JT808HttpRequest.cs | 22 +
.../Metadata/JT808HttpResponse.cs | 22 +
src/JT808.Gateway/Metadata/JT808Request.cs | 23 +
src/JT808.Gateway/Metadata/JT808Response.cs | 31 +
src/JT808.Gateway/Metadata/JT808TcpSession.cs | 32 +
src/JT808.Gateway/Metadata/JT808UdpPackage.cs | 20 +
src/JT808.Gateway/Metadata/JT808UdpSession.cs | 38 +
src/JT808.Gateway/Protos/JT808Gateway.proto | 63 +
src/JT808.Gateway/PubSub/IJT808MsgConsumer.cs | 15 +
src/JT808.Gateway/PubSub/IJT808MsgProducer.cs | 17 +
.../PubSub/IJT808MsgReplyConsumer.cs | 15 +
.../PubSub/IJT808MsgReplyProducer.cs | 17 +
src/JT808.Gateway/PubSub/IJT808PubSub.cs | 11 +
.../PubSub/IJT808SessionConsumer.cs | 18 +
.../PubSub/IJT808SessionProducer.cs | 13 +
.../Services/JT808AtomicCounterService.cs | 52 +
.../JT808AtomicCounterServiceFactory.cs | 30 +
.../JT808ClientReceiveAtomicCounterService.cs | 35 +
.../JT808ClientReportHostedService.cs | 37 +
.../Services/JT808ClientReportService.cs | 43 +
.../JT808ClientSendAtomicCounterService.cs | 35 +
.../Services/JT808GatewayService.cs | 96 +
.../Services/JT808MsgReplyHostedService.cs | 42 +
src/JT808.Gateway/Services/JT808MsgService.cs | 11 +
.../Services/JT808SessionService.cs | 98 +
.../Services/JT808UnificationSendService.cs | 45 +
.../Session/JT808SessionManager.cs | 304 ++
.../Simples/JT808SimpleTcpClient.cs | 50 +
.../Simples/JT808SimpleUdpClient.cs | 48 +
.../Tcp/JT808TcpDotnettyExtensions.cs | 21 +
src/JT808.Gateway/Tcp/JT808TcpServerHost.cs | 95 +
.../Udp/JT808UdpDotnettyExtensions.cs | 22 +
src/JT808.Gateway/Udp/JT808UdpServerHost.cs | 76 +
91 files changed, 7054 insertions(+)
create mode 100644 src/JT808.Gateway.SimpleClient/JT808.Gateway.SimpleClient.csproj
create mode 100644 src/JT808.Gateway.SimpleClient/Program.cs
create mode 100644 src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs
create mode 100644 src/JT808.Gateway.SimpleClient/Services/UpService.cs
create mode 100644 src/JT808.Gateway.SimpleServer/Configs/NLog.xsd
create mode 100644 src/JT808.Gateway.SimpleServer/Configs/nlog.Unix.config
create mode 100644 src/JT808.Gateway.SimpleServer/Configs/nlog.Win32NT.config
create mode 100644 src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj
create mode 100644 src/JT808.Gateway.SimpleServer/Program.cs
create mode 100644 src/JT808.Gateway.sln
create mode 100644 src/JT808.Gateway/Client/DeviceConfig.cs
create mode 100644 src/JT808.Gateway/Client/JT808ClientDotnettyExtensions.cs
create mode 100644 src/JT808.Gateway/Client/JT808ClientMsgSNDistributedImpl.cs
create mode 100644 src/JT808.Gateway/Client/JT808TcpClient.cs
create mode 100644 src/JT808.Gateway/Client/JT808TcpClientExtensions.cs
create mode 100644 src/JT808.Gateway/Client/JT808TcpClientFactory.cs
create mode 100644 src/JT808.Gateway/Codecs/JT808ClientTcpDecoder.cs
create mode 100644 src/JT808.Gateway/Codecs/JT808ClientTcpEncoder.cs
create mode 100644 src/JT808.Gateway/Codecs/JT808TcpDecoder.cs
create mode 100644 src/JT808.Gateway/Codecs/JT808TcpEncoder.cs
create mode 100644 src/JT808.Gateway/Codecs/JT808UdpDecoder.cs
create mode 100644 src/JT808.Gateway/Configurations/JT808ClientConfiguration.cs
create mode 100644 src/JT808.Gateway/Configurations/JT808Configuration.cs
create mode 100644 src/JT808.Gateway/Converters/JsonByteArrayHexConverter.cs
create mode 100644 src/JT808.Gateway/Converters/JsonIPAddressConverter.cs
create mode 100644 src/JT808.Gateway/Converters/JsonIPEndPointConverter.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808AtomicCounterDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808DefaultResultDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808IPAddressDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808ResultDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808TcpSessionInfoDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808UdpSessionInfoDto.cs
create mode 100644 src/JT808.Gateway/Dtos/JT808UnificationSendRequestDto.cs
create mode 100644 src/JT808.Gateway/Enums/JT808TransportProtocolType.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808MsgIdHttpHandlerBase.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808TcpClientConnectionHandler.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808TcpClientHandler.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808TcpConnectionHandler.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808TcpServerHandler.cs
create mode 100644 src/JT808.Gateway/Handlers/JT808UdpServerHandler.cs
create mode 100644 src/JT808.Gateway/IJT808ClientBuilder.cs
create mode 100644 src/JT808.Gateway/IJT808GatewayBuilder.cs
create mode 100644 src/JT808.Gateway/Impls/JT808DatagramPacketImpl.cs
create mode 100644 src/JT808.Gateway/Impls/JT808GatewayBuilderDefault.cs
create mode 100644 src/JT808.Gateway/Impls/JT808MsgProducerDefaultImpl.cs
create mode 100644 src/JT808.Gateway/Impls/JT808MsgReplyConsumerDefaultImpl.cs
create mode 100644 src/JT808.Gateway/Impls/JT808SessionProducerDefaultImpl.cs
create mode 100644 src/JT808.Gateway/Interfaces/IJT808DatagramPacket.cs
create mode 100644 src/JT808.Gateway/Interfaces/IJT808Reply.cs
create mode 100644 src/JT808.Gateway/Interfaces/IJT808Session.cs
create mode 100644 src/JT808.Gateway/Interfaces/IJT808SessionService.cs
create mode 100644 src/JT808.Gateway/Interfaces/IJT808UnificationSendService.cs
create mode 100644 src/JT808.Gateway/JT808.Gateway.csproj
create mode 100644 src/JT808.Gateway/JT808GatewayConstants.cs
create mode 100644 src/JT808.Gateway/JT808GatewayExtensions.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808AtomicCounter.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808ClientReport.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808ClientRequest.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808HttpRequest.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808HttpResponse.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808Request.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808Response.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808TcpSession.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808UdpPackage.cs
create mode 100644 src/JT808.Gateway/Metadata/JT808UdpSession.cs
create mode 100644 src/JT808.Gateway/Protos/JT808Gateway.proto
create mode 100644 src/JT808.Gateway/PubSub/IJT808MsgConsumer.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808MsgProducer.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808MsgReplyConsumer.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808MsgReplyProducer.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808PubSub.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808SessionConsumer.cs
create mode 100644 src/JT808.Gateway/PubSub/IJT808SessionProducer.cs
create mode 100644 src/JT808.Gateway/Services/JT808AtomicCounterService.cs
create mode 100644 src/JT808.Gateway/Services/JT808AtomicCounterServiceFactory.cs
create mode 100644 src/JT808.Gateway/Services/JT808ClientReceiveAtomicCounterService.cs
create mode 100644 src/JT808.Gateway/Services/JT808ClientReportHostedService.cs
create mode 100644 src/JT808.Gateway/Services/JT808ClientReportService.cs
create mode 100644 src/JT808.Gateway/Services/JT808ClientSendAtomicCounterService.cs
create mode 100644 src/JT808.Gateway/Services/JT808GatewayService.cs
create mode 100644 src/JT808.Gateway/Services/JT808MsgReplyHostedService.cs
create mode 100644 src/JT808.Gateway/Services/JT808MsgService.cs
create mode 100644 src/JT808.Gateway/Services/JT808SessionService.cs
create mode 100644 src/JT808.Gateway/Services/JT808UnificationSendService.cs
create mode 100644 src/JT808.Gateway/Session/JT808SessionManager.cs
create mode 100644 src/JT808.Gateway/Simples/JT808SimpleTcpClient.cs
create mode 100644 src/JT808.Gateway/Simples/JT808SimpleUdpClient.cs
create mode 100644 src/JT808.Gateway/Tcp/JT808TcpDotnettyExtensions.cs
create mode 100644 src/JT808.Gateway/Tcp/JT808TcpServerHost.cs
create mode 100644 src/JT808.Gateway/Udp/JT808UdpDotnettyExtensions.cs
create mode 100644 src/JT808.Gateway/Udp/JT808UdpServerHost.cs
diff --git a/src/JT808.Gateway.SimpleClient/JT808.Gateway.SimpleClient.csproj b/src/JT808.Gateway.SimpleClient/JT808.Gateway.SimpleClient.csproj
new file mode 100644
index 0000000..597fe2f
--- /dev/null
+++ b/src/JT808.Gateway.SimpleClient/JT808.Gateway.SimpleClient.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ netcoreapp3.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/JT808.Gateway.SimpleClient/Program.cs b/src/JT808.Gateway.SimpleClient/Program.cs
new file mode 100644
index 0000000..e7158bb
--- /dev/null
+++ b/src/JT808.Gateway.SimpleClient/Program.cs
@@ -0,0 +1,46 @@
+using JT808.Gateway.Client;
+using JT808.Gateway.SimpleClient.Services;
+using JT808.Protocol;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Threading.Tasks;
+using Grpc.Net.Client;
+using JT808.Gateway.GrpcService;
+
+namespace JT808.Gateway.SimpleClient
+{
+ class Program
+ {
+ 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
+ AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
+ var serverHostBuilder = new HostBuilder()
+ .ConfigureLogging((context, logging) =>
+ {
+ logging.AddConsole();
+ logging.SetMinimumLevel(LogLevel.Trace);
+ })
+ .ConfigureServices((hostContext, services) =>
+ {
+ services.AddGrpcClient(o =>
+ {
+ o.Address = new Uri("https://127.0.0.1:5001");
+ });
+ services.AddSingleton();
+ services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
+ services.AddLogging(options => {
+ options.AddConsole();
+ options.SetMinimumLevel(LogLevel.Trace);
+ });
+ services.AddJT808Configure()
+ .AddJT808Client();
+ services.AddHostedService();
+ services.AddHostedService();
+ });
+ await serverHostBuilder.RunConsoleAsync();
+ }
+ }
+}
diff --git a/src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs b/src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs
new file mode 100644
index 0000000..b04b1e8
--- /dev/null
+++ b/src/JT808.Gateway.SimpleClient/Services/GrpcClientService.cs
@@ -0,0 +1,68 @@
+using JT808.Gateway.Client;
+using JT808.Protocol.MessageBody;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using JT808.Gateway.GrpcService;
+using static JT808.Gateway.GrpcService.JT808Gateway;
+using Google.Protobuf;
+using System.Text.Json;
+using JT808.Protocol.Extensions;
+
+namespace JT808.Gateway.SimpleClient.Services
+{
+ public class GrpcClientService : IHostedService
+ {
+ private readonly ILogger logger;
+ private readonly JT808GatewayClient client;
+
+ public GrpcClientService(
+ ILoggerFactory loggerFactory,
+ JT808GatewayClient jT808GatewayClient)
+ {
+ this.client = jT808GatewayClient;
+ logger = loggerFactory.CreateLogger("GrpcClientService");
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ Task.Run(() => {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ Thread.Sleep(1000 * 10);
+ var result1 = client.GetTcpAtomicCounter(new Empty());
+ var result2 = client.GetUdpAtomicCounter(new Empty());
+ var result3 = client.GetTcpSessionAll(new Empty());
+ var result4 = client.GetUdpSessionAll(new Empty());
+ var result5 = client.UnificationSend(new UnificationSendRequest()
+ {
+ TerminalPhoneNo= "12345678910",
+ Data= ByteString.CopyFrom("7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E".ToHexBytes())
+ });
+ var result6 = client.RemoveSessionByTerminalPhoneNo(new SessionRemoveRequest()
+ {
+ TerminalPhoneNo= "12345678910"
+ });
+
+ logger.LogDebug(JsonSerializer.Serialize(result1));
+ logger.LogDebug(JsonSerializer.Serialize(result2));
+ logger.LogDebug(JsonSerializer.Serialize(result3));
+ logger.LogDebug(JsonSerializer.Serialize(result4));
+ logger.LogDebug(JsonSerializer.Serialize(result5));
+ logger.LogDebug(JsonSerializer.Serialize(result6));
+ }
+ }, cancellationToken);
+ return Task.CompletedTask;
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/src/JT808.Gateway.SimpleClient/Services/UpService.cs b/src/JT808.Gateway.SimpleClient/Services/UpService.cs
new file mode 100644
index 0000000..a9a9d83
--- /dev/null
+++ b/src/JT808.Gateway.SimpleClient/Services/UpService.cs
@@ -0,0 +1,68 @@
+using JT808.Gateway.Client;
+using JT808.Protocol.MessageBody;
+using Microsoft.Extensions.Hosting;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace JT808.Gateway.SimpleClient.Services
+{
+ public class UpService : IHostedService
+ {
+ private readonly IJT808TcpClientFactory jT808TcpClientFactory;
+
+ public UpService(IJT808TcpClientFactory jT808TcpClientFactory)
+ {
+ this.jT808TcpClientFactory = jT808TcpClientFactory;
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ JT808TcpClient client1 = jT808TcpClientFactory.Create(new DeviceConfig("12345678910", "127.0.0.1", 808));
+ //1.终端注册
+ client1.Send(new JT808_0x0100()
+ {
+ PlateNo = "粤A12345",
+ PlateColor = 2,
+ AreaID = 0,
+ CityOrCountyId = 0,
+ MakerId = "Koike001",
+ TerminalId = "Koike001",
+ TerminalModel = "Koike001"
+ });
+ //2.终端鉴权
+ client1.Send(new JT808_0x0102()
+ {
+ Code = "1234"
+ });
+ Task.Run(() => {
+ while (true)
+ {
+ var i = 0;
+ //3.每5000秒发一次
+ client1.Send(new JT808_0x0200()
+ {
+ Lat = 110000 + i,
+ Lng = 100000 + i,
+ GPSTime = DateTime.Now,
+ Speed = 50,
+ Direction = 30,
+ AlarmFlag = 5,
+ Altitude = 50,
+ StatusFlag = 10
+ });
+ i++;
+ Thread.Sleep(5000);
+ }
+ });
+ return Task.CompletedTask;
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/src/JT808.Gateway.SimpleServer/Configs/NLog.xsd b/src/JT808.Gateway.SimpleServer/Configs/NLog.xsd
new file mode 100644
index 0000000..2f57d09
--- /dev/null
+++ b/src/JT808.Gateway.SimpleServer/Configs/NLog.xsd
@@ -0,0 +1,3106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Watch config file for changes and reload automatically.
+
+
+
+
+ Print internal NLog messages to the console. Default value is: false
+
+
+
+
+ Print internal NLog messages to the console error output. Default value is: false
+
+
+
+
+ Write internal NLog messages to the specified file.
+
+
+
+
+ Log level threshold for internal log messages. Default value is: Info.
+
+
+
+
+ Global log level threshold for application log messages. Messages below this level won't be logged..
+
+
+
+
+ Throw an exception when there is an internal error. Default value is: false.
+
+
+
+
+ Throw an exception when there is a configuration error. If not set, determined by throwExceptions.
+
+
+
+
+ Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false.
+
+
+
+
+ Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false.
+
+
+
+
+ Write timestamps for internal NLog messages. Default value is: true.
+
+
+
+
+ Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false.
+
+
+
+
+ Perform mesage template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prefix for targets/layout renderers/filters/conditions loaded from this assembly.
+
+
+
+
+ Load NLog extensions from the specified file (*.dll)
+
+
+
+
+ Load NLog extensions from the specified assembly. Assembly name should be fully qualified.
+
+
+
+
+
+
+
+
+
+ Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*
+
+
+
+
+ Comma separated list of levels that this rule matches.
+
+
+
+
+ Minimum level that this rule matches.
+
+
+
+
+ Maximum level that this rule matches.
+
+
+
+
+ Level that this rule matches.
+
+
+
+
+ Comma separated list of target names.
+
+
+
+
+ Ignore further rules if this one matches.
+
+
+
+
+ Enable or disable logging rule. Disabled rules are ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file.
+
+
+
+
+ Ignore any errors in the include file.
+
+
+
+
+
+
+ Variable name.
+
+
+
+
+ Variable value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events that should be processed in a batch by the lazy writer thread.
+
+
+
+
+ Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch
+
+
+
+
+ Action to be taken when the lazy writer thread request queue count exceeds the set limit.
+
+
+
+
+ Limit on the number of requests in the lazy writer thread request queue.
+
+
+
+
+ Time in milliseconds to sleep between batches.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Delay the flush until the LogEvent has been confirmed as written
+
+
+
+
+ Condition expression. Log events who meet this condition will cause a flush on the wrapped target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events to be buffered.
+
+
+
+
+ Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.
+
+
+
+
+ Indicates whether to use sliding timeout.
+
+
+
+
+ Action to take if the buffer overflows.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+ Indicates whether to include contents of the stack.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ Option to include all properties from the log events
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Viewer parameter name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to use default row highlighting rules.
+
+
+
+
+ Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+ Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition that must be met in order to set the specified foreground and background color.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Indicates whether to ignore case when comparing texts.
+
+
+
+
+ Regular expression to be matched. You must specify either text or regex.
+
+
+
+
+ Text to be matched. You must specify either text or regex.
+
+
+
+
+ Indicates whether to match whole words only.
+
+
+
+
+ Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send the log messages to the standard error instead of the standard output.
+
+
+
+
+ Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.
+
+
+
+
+ Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
+
+
+
+
+ Name of the database provider.
+
+
+
+
+ Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
+
+
+
+
+ Indicates whether to keep the database connection open between the log events.
+
+
+
+
+ Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
+
+
+
+
+ Name of the connection string (as specified in <connectionStrings> configuration section.
+
+
+
+
+ Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
+
+
+
+
+ Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
+
+
+
+
+ Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ Text of the SQL command to be run on each log level.
+
+
+
+
+ Type of the SQL command to be run on each log level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type of the command.
+
+
+
+
+ Connection string to run the command against. If not provided, connection string from the target is used.
+
+
+
+
+ Indicates whether to ignore failures.
+
+
+
+
+ Command text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Database parameter name.
+
+
+
+
+ Database parameter precision.
+
+
+
+
+ Database parameter scale.
+
+
+
+
+ Database parameter size.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Layout that renders event Category.
+
+
+
+
+ Layout that renders event ID.
+
+
+
+
+ Name of the Event Log to write to. This can be System, Application or any user-defined name.
+
+
+
+
+ Name of the machine on which Event Log service is running.
+
+
+
+
+ Value to be used as the event Source.
+
+
+
+
+ Action to take if the message is larger than the option.
+
+
+
+
+ Optional entrytype. When not set, or when not convertable to then determined by
+
+
+
+
+ Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API
+
+
+
+
+ Message length limit to write to the Event Log.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether to return to the first target after any successful write.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ File encoding.
+
+
+
+
+ Line ending mode.
+
+
+
+
+ Way file archives are numbered.
+
+
+
+
+ Name of the file to be used for an archive.
+
+
+
+
+ Indicates whether to automatically archive log files every time the specified time passes.
+
+
+
+
+ Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose:
+
+
+
+
+ Indicates whether to compress archive files into the zip archive format.
+
+
+
+
+ Maximum number of archive files that should be kept.
+
+
+
+
+ Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation.
+
+
+
+
+ Is the an absolute or relative path?
+
+
+
+
+ Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.
+
+
+
+
+ Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write
+
+
+
+
+ Is the an absolute or relative path?
+
+
+
+
+ Value indicationg whether file creation calls should be synchronized by a system global mutex.
+
+
+
+
+ Maximum number of log filenames that should be stored as existing.
+
+
+
+
+ Indicates whether the footer should be written only when the file is archived.
+
+
+
+
+ Name of the file to write to.
+
+
+
+
+ Value specifying the date format to use when archiving files.
+
+
+
+
+ Indicates whether to archive old log file on startup.
+
+
+
+
+ Indicates whether to create directories if they do not exist.
+
+
+
+
+ File attributes (Windows only).
+
+
+
+
+ Indicates whether to delete old log file on startup.
+
+
+
+
+ Indicates whether to replace file contents on each write instead of appending log message at the end.
+
+
+
+
+ Indicates whether to enable log file(s) to be deleted.
+
+
+
+
+ Number of times the write is appended on the file before NLog discards the log message.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on the same host.
+
+
+
+
+ Indicates whether to keep log file open instead of opening and closing it on each logging event.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on different network hosts.
+
+
+
+
+ Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).
+
+
+
+
+ Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ Log file buffer size in bytes.
+
+
+
+
+ Indicates whether to automatically flush the file buffers after each log message.
+
+
+
+
+ Delay in milliseconds to wait before attempting to write to the file again.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Condition expression. Log events who meet this condition will be forwarded to the wrapped target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Windows domain name to change context to.
+
+
+
+
+ Required impersonation level.
+
+
+
+
+ Type of the logon provider.
+
+
+
+
+ Logon Type.
+
+
+
+
+ User account password.
+
+
+
+
+ Indicates whether to revert to the credentials of the process instead of impersonating another user.
+
+
+
+
+ Username to change context to.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Interval in which messages will be written up to the number of messages.
+
+
+
+
+ Maximum allowed number of messages written per .
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Endpoint address.
+
+
+
+
+ Name of the endpoint configuration in WCF configuration file.
+
+
+
+
+ Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply)
+
+
+
+
+ Client ID.
+
+
+
+
+ Indicates whether to include per-event properties in the payload sent to the server.
+
+
+
+
+ Indicates whether to use binary message encoding.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calculate the value for the parameter.
+
+
+
+
+ Name of the parameter.
+
+
+
+
+ Type of the parameter.
+
+
+
+
+ Type of the parameter. Obsolete alias for
+
+
+
+
+ Parameter can combine multiple LogEvents into a single parameter value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send message as HTML instead of plain text.
+
+
+
+
+ Encoding to be used for sending e-mail.
+
+
+
+
+ Indicates whether to add new lines between log entries.
+
+
+
+
+ CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Mail message body (repeated for each log message send in one mail).
+
+
+
+
+ Mail subject.
+
+
+
+
+ Sender's email address (e.g. joe@domain.com).
+
+
+
+
+ Indicates the SMTP client timeout.
+
+
+
+
+ Priority used for sending mails.
+
+
+
+
+ Indicates whether NewLine characters in the body should be replaced with tags.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ SMTP Server to be used for sending.
+
+
+
+
+ SMTP Authentication mode.
+
+
+
+
+ Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.
+
+
+
+
+ Port number that SMTP Server is listening on.
+
+
+
+
+ Indicates whether the default Settings from System.Net.MailSettings should be used.
+
+
+
+
+ Folder where applications save mail messages to be processed by the local SMTP server.
+
+
+
+
+ Specifies how outgoing email messages will be handled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Class name.
+
+
+
+
+ Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Network address.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ End of line value if a newline is appended at the end of log message .
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+ Indicates whether to include contents of the stack.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ Option to include all properties from the log events
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Indicates whether to perform layout calculation.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether performance counter should be automatically created.
+
+
+
+
+ Name of the performance counter category.
+
+
+
+
+ Counter help text.
+
+
+
+
+ Name of the performance counter.
+
+
+
+
+ Performance counter type.
+
+
+
+
+ The value by which to increment the counter.
+
+
+
+
+ Performance counter instance name.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Default filter to be applied when no specific rule matches.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition to be tested.
+
+
+
+
+ Resulting filter to be applied when the condition matches.
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ Number of times to repeat each log message.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ Number of retries that should be attempted on the wrapped target in case of a failure.
+
+
+
+
+ Time to wait between retries in milliseconds.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Always use independent of
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
+
+
+ Encoding.
+
+
+
+
+ Value whether escaping be done according to the old NLog style (Very non-standard)
+
+
+
+
+ Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs)
+
+
+
+
+ Web service method name. Only used with Soap.
+
+
+
+
+ Web service namespace. Only used with Soap.
+
+
+
+
+ Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters)
+
+
+
+
+ Protocol to be used when calling web service.
+
+
+
+
+ Web service URL.
+
+
+
+
+ Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ).
+
+
+
+
+ (optional) root namespace of the XML document, if POST of XML document chosen. (see and ).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+ Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').
+
+
+
+
+ Column delimiter.
+
+
+
+
+ Quote Character.
+
+
+
+
+ Quoting mode.
+
+
+
+
+ Indicates whether CVS should include header.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout of the column.
+
+
+
+
+ Name of the column.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ List of property names to exclude when is true
+
+
+
+
+ Option to include all properties from the log events
+
+
+
+
+ Indicates whether to include contents of the dictionary.
+
+
+
+
+ Indicates whether to include contents of the dictionary.
+
+
+
+
+ Option to render the empty object value {}
+
+
+
+
+ Option to suppress the extra spaces in the output json
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Determines wether or not this attribute will be Json encoded.
+
+
+
+
+ Indicates whether to escape non-ascii characters
+
+
+
+
+ Layout that will be rendered as the attribute's value.
+
+
+
+
+ Name of the attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Option to include all properties from the log events
+
+
+
+
+ Indicates whether to include contents of the dictionary.
+
+
+
+
+ Indicates whether to include contents of the dictionary.
+
+
+
+
+ Indicates whether to include contents of the stack.
+
+
+
+
+ Indicates whether to include contents of the stack.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Condition expression.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Default number of unique filter values to expect, will automatically increase if needed
+
+
+
+
+ Append FilterCount to the when an event is no longer filtered
+
+
+
+
+ Insert FilterCount value into when an event is no longer filtered
+
+
+
+
+ Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout.
+
+
+
+
+ Max number of unique filter values to expect simultaneously
+
+
+
+
+ Max length of filter values, will truncate if above limit
+
+
+
+
+ Default buffer size for the internal buffers
+
+
+
+
+ Reuse internal buffers, and doesn't have to constantly allocate new buffers
+
+
+
+
+ How long before a filter expires, and logging is accepted again
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/JT808.Gateway.SimpleServer/Configs/nlog.Unix.config b/src/JT808.Gateway.SimpleServer/Configs/nlog.Unix.config
new file mode 100644
index 0000000..ee227dd
--- /dev/null
+++ b/src/JT808.Gateway.SimpleServer/Configs/nlog.Unix.config
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/JT808.Gateway.SimpleServer/Configs/nlog.Win32NT.config b/src/JT808.Gateway.SimpleServer/Configs/nlog.Win32NT.config
new file mode 100644
index 0000000..ec26e74
--- /dev/null
+++ b/src/JT808.Gateway.SimpleServer/Configs/nlog.Win32NT.config
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj b/src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj
new file mode 100644
index 0000000..55c13a6
--- /dev/null
+++ b/src/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj
@@ -0,0 +1,36 @@
+
+
+
+ Exe
+ netcoreapp3.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+
diff --git a/src/JT808.Gateway.SimpleServer/Program.cs b/src/JT808.Gateway.SimpleServer/Program.cs
new file mode 100644
index 0000000..25ecb19
--- /dev/null
+++ b/src/JT808.Gateway.SimpleServer/Program.cs
@@ -0,0 +1,70 @@
+using JT808.Gateway.Services;
+using JT808.Gateway.Tcp;
+using JT808.Gateway.Udp;
+using JT808.Protocol;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using NLog.Extensions.Logging;
+using System;
+using System.Net;
+
+namespace JT808.Gateway.SimpleServer
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Host.CreateDefaultBuilder(args)
+ .ConfigureAppConfiguration((hostingContext, config) =>
+ {
+ config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
+ config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
+ })
+ .ConfigureLogging((hostContext, configLogging) => {
+ Console.WriteLine($"Environment.OSVersion.Platform:{Environment.OSVersion.Platform.ToString()}");
+ NLog.LogManager.LoadConfiguration($"Configs/nlog.{Environment.OSVersion.Platform.ToString()}.config");
+ configLogging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true });
+ configLogging.SetMinimumLevel(LogLevel.Trace);
+ })
+
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder
+ //.ConfigureKestrel(options =>
+ //{
+ // options.Listen(IPAddress.Any, 5001, listenOptions =>
+ // {
+ // listenOptions.Protocols = HttpProtocols.Http2;
+ // });
+ //})
+ .Configure(app =>
+ {
+ app.UseRouting();
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapGrpcService();
+ });
+ });
+ })
+ .ConfigureServices((hostContext,services) =>
+ {
+ services.Configure(hostContext.Configuration.GetSection("Kestrel"));
+ services.AddGrpc();
+ services.AddSingleton();
+ services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
+ services.AddJT808Configure()
+ .AddJT808Gateway(hostContext.Configuration)
+ .AddJT808GatewayTcpHost()
+ .AddJT808GatewayUdpHost()
+ .Builder();
+ })
+ .Build()
+ .Run();
+ }
+ }
+}
diff --git a/src/JT808.Gateway.sln b/src/JT808.Gateway.sln
new file mode 100644
index 0000000..546cc35
--- /dev/null
+++ b/src/JT808.Gateway.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29411.108
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway", "JT808.Gateway\JT808.Gateway.csproj", "{A42A396F-D32B-4AC2-B554-735AA7E2DBA8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.SimpleServer", "JT808.Gateway.SimpleServer\JT808.Gateway.SimpleServer.csproj", "{F9ABFDDB-84A2-44C8-A162-A1FE4EA4D332}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.Gateway.SimpleClient", "JT808.Gateway.SimpleClient\JT808.Gateway.SimpleClient.csproj", "{886D4937-7265-40DC-87CC-85CE35553214}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A42A396F-D32B-4AC2-B554-735AA7E2DBA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A42A396F-D32B-4AC2-B554-735AA7E2DBA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A42A396F-D32B-4AC2-B554-735AA7E2DBA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A42A396F-D32B-4AC2-B554-735AA7E2DBA8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F9ABFDDB-84A2-44C8-A162-A1FE4EA4D332}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F9ABFDDB-84A2-44C8-A162-A1FE4EA4D332}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F9ABFDDB-84A2-44C8-A162-A1FE4EA4D332}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F9ABFDDB-84A2-44C8-A162-A1FE4EA4D332}.Release|Any CPU.Build.0 = Release|Any CPU
+ {886D4937-7265-40DC-87CC-85CE35553214}.Debug|Any CPU.ActiveCfg = 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.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F5671BD2-B44A-4A7C-80EA-E060A512992D}
+ EndGlobalSection
+EndGlobal
diff --git a/src/JT808.Gateway/Client/DeviceConfig.cs b/src/JT808.Gateway/Client/DeviceConfig.cs
new file mode 100644
index 0000000..53518ef
--- /dev/null
+++ b/src/JT808.Gateway/Client/DeviceConfig.cs
@@ -0,0 +1,28 @@
+using JT808.Protocol;
+using JT808.Protocol.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.Gateway.Client
+{
+ public class DeviceConfig
+ {
+ public DeviceConfig(string terminalPhoneNo, string tcpHost,int tcpPort)
+ {
+ TerminalPhoneNo = terminalPhoneNo;
+ TcpHost = tcpHost;
+ TcpPort = tcpPort;
+ MsgSNDistributed = new JT808ClientMsgSNDistributedImpl();
+ }
+ public string TerminalPhoneNo { get; private set; }
+ public string TcpHost { get; private set; }
+ public int TcpPort { get; private set; }
+ ///
+ /// 心跳时间(秒)
+ ///
+ public int Heartbeat { get; set; } = 30;
+
+ public IJT808MsgSNDistributed MsgSNDistributed { get; }
+ }
+}
diff --git a/src/JT808.Gateway/Client/JT808ClientDotnettyExtensions.cs b/src/JT808.Gateway/Client/JT808ClientDotnettyExtensions.cs
new file mode 100644
index 0000000..05d998f
--- /dev/null
+++ b/src/JT808.Gateway/Client/JT808ClientDotnettyExtensions.cs
@@ -0,0 +1,23 @@
+
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using JT808.Protocol;
+using JT808.Gateway.Services;
+
+namespace JT808.Gateway.Client
+{
+ public static class JT808ClientDotnettyExtensions
+ {
+ public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder)
+ {
+ jT808Builder.Services.AddSingleton();
+ jT808Builder.Services.AddSingleton();
+ jT808Builder.Services.AddSingleton();
+ jT808Builder.Services.AddSingleton();
+ jT808Builder.Services.AddHostedService();
+ return jT808Builder;
+ }
+ }
+}
diff --git a/src/JT808.Gateway/Client/JT808ClientMsgSNDistributedImpl.cs b/src/JT808.Gateway/Client/JT808ClientMsgSNDistributedImpl.cs
new file mode 100644
index 0000000..a7c11b6
--- /dev/null
+++ b/src/JT808.Gateway/Client/JT808ClientMsgSNDistributedImpl.cs
@@ -0,0 +1,16 @@
+using JT808.Protocol;
+using JT808.Protocol.Interfaces;
+using System.Threading;
+
+namespace JT808.Gateway.Client
+{
+ internal class JT808ClientMsgSNDistributedImpl : IJT808MsgSNDistributed
+ {
+ int _counter = 0;
+
+ public ushort Increment()
+ {
+ return (ushort)Interlocked.Increment(ref _counter);
+ }
+ }
+}
diff --git a/src/JT808.Gateway/Client/JT808TcpClient.cs b/src/JT808.Gateway/Client/JT808TcpClient.cs
new file mode 100644
index 0000000..9b6b93c
--- /dev/null
+++ b/src/JT808.Gateway/Client/JT808TcpClient.cs
@@ -0,0 +1,112 @@
+using DotNetty.Buffers;
+using DotNetty.Codecs;
+using DotNetty.Handlers.Timeout;
+using DotNetty.Transport.Bootstrapping;
+using DotNetty.Transport.Channels;
+using DotNetty.Transport.Channels.Sockets;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Runtime.InteropServices;
+using Microsoft.Extensions.DependencyInjection;
+using System.Net;
+using JT808.Protocol;
+using JT808.Gateway.Services;
+using JT808.Gateway.Codecs;
+using JT808.Gateway.Handlers;
+using JT808.Gateway.Metadata;
+
+namespace JT808.Gateway.Client
+{
+ public sealed class JT808TcpClient : IDisposable
+ {
+ private MultithreadEventLoopGroup group;
+
+ private IChannel clientChannel;
+
+ private bool disposed = false;
+
+ public DeviceConfig DeviceConfig { get; private set; }
+
+ public ILoggerFactory LoggerFactory { get; private set; }
+
+ public JT808TcpClient(DeviceConfig deviceConfig, IServiceProvider serviceProvider)
+ {
+ DeviceConfig = deviceConfig;
+ LoggerFactory = serviceProvider.GetRequiredService();
+ JT808ClientSendAtomicCounterService jT808SendAtomicCounterService = serviceProvider.GetRequiredService();
+ JT808ClientReceiveAtomicCounterService jT808ReceiveAtomicCounterService = serviceProvider.GetRequiredService();
+ IJT808Config jT808Config = serviceProvider.GetRequiredService();
+ group = new MultithreadEventLoopGroup(1);
+ Bootstrap bootstrap = new Bootstrap();
+ bootstrap.Group(group);
+ bootstrap.Channel();
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ bootstrap.Option(ChannelOption.SoReuseport, true);
+ }
+ bootstrap
+ .Option(ChannelOption.SoBacklog, 8192)
+ .Handler(new ActionChannelInitializer(channel =>
+ {
+ channel.Pipeline.AddLast("jt808TcpBuffer", new DelimiterBasedFrameDecoder(int.MaxValue,
+ Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }),
+ Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag })));
+ channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(60, deviceConfig.Heartbeat, 3600));
+ channel.Pipeline.AddLast("jt808TcpDecode", new JT808ClientTcpDecoder());
+ channel.Pipeline.AddLast("jt808TcpEncode", new JT808ClientTcpEncoder(jT808Config,jT808SendAtomicCounterService, LoggerFactory));
+ channel.Pipeline.AddLast("jt808TcpClientConnection", new JT808TcpClientConnectionHandler(this));
+ channel.Pipeline.AddLast("jt808TcpService", new JT808TcpClientHandler(jT808ReceiveAtomicCounterService,this));
+ }));
+ clientChannel = bootstrap.ConnectAsync(IPAddress.Parse(DeviceConfig.TcpHost), DeviceConfig.TcpPort).Result;
+ }
+
+ public async void Send(JT808ClientRequest request)
+ {
+ if (disposed) return;
+ if (clientChannel == null) throw new NullReferenceException("Channel is empty.");
+ if (request == null) throw new ArgumentNullException("JT808ClientRequest Parameter is empty.");
+ if (clientChannel.Active && clientChannel.Open)
+ {
+ await clientChannel.WriteAndFlushAsync(request);
+ }
+ }
+
+ public bool IsOpen
+ {
+ get
+ {
+ if (clientChannel == null) return false;
+ return clientChannel.Active && clientChannel.Open;
+ }
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposed)
+ {
+ return;
+ }
+ if (disposing)
+ {
+ // 清理托管资源
+ group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
+ }
+ disposed = true;
+ }
+
+ ~JT808TcpClient()
+ {
+ //必须为false
+ //这表明,隐式清理时,只要处理非托管资源就可以了。
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ //必须为true
+ Dispose(true);
+ //通知垃圾回收机制不再调用终结器(析构器)
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/JT808.Gateway/Client/JT808TcpClientExtensions.cs b/src/JT808.Gateway/Client/JT808TcpClientExtensions.cs
new file mode 100644
index 0000000..919405e
--- /dev/null
+++ b/src/JT808.Gateway/Client/JT808TcpClientExtensions.cs
@@ -0,0 +1,103 @@
+using JT808.Protocol;
+using JT808.Protocol.MessageBody;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using JT808.Protocol.Enums;
+using JT808.Protocol.Extensions;
+using JT808.Gateway.Metadata;
+
+namespace JT808.Gateway.Client
+{
+ public static class JT808TcpClientExtensions
+ {
+ public static void Send(this JT808TcpClient client, JT808Header header, JT808Bodies bodies, int minBufferSize = 1024)
+ {
+ JT808Package package = new JT808Package();
+ package.Header = header;
+ package.Bodies = bodies;
+ package.Header.TerminalPhoneNo = client.DeviceConfig.TerminalPhoneNo;
+ package.Header.MsgNum = client.DeviceConfig.MsgSNDistributed.Increment();
+ JT808ClientRequest request = new JT808ClientRequest(package, minBufferSize);
+ client.Send(request);
+ }
+
+ ///
+ /// 终端通用应答
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0001 bodies, int minBufferSize = 100)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.终端通用应答.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+
+ ///
+ /// 终端心跳
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0002 bodies, int minBufferSize = 100)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.终端心跳.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+
+ ///
+ /// 终端注销
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0003 bodies, int minBufferSize = 100)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.终端注销.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+
+ ///
+ /// 终端鉴权
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0102 bodies, int minBufferSize = 100)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.终端鉴权.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+
+ ///
+ /// 终端注册
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0100 bodies, int minBufferSize = 100)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.终端注册.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+
+ ///
+ /// 位置信息汇报
+ ///
+ ///
+ ///
+ ///
+ public static void Send(this JT808TcpClient client, JT808_0x0200 bodies, int minBufferSize = 200)
+ {
+ JT808Header header = new JT808Header();
+ header.MsgId = JT808MsgId.位置信息汇报.ToUInt16Value();
+ client.Send(header, bodies, minBufferSize);
+ }
+ }
+}
diff --git a/src/JT808.Gateway/Client/JT808TcpClientFactory.cs b/src/JT808.Gateway/Client/JT808TcpClientFactory.cs
new file mode 100644
index 0000000..1e78b8a
--- /dev/null
+++ b/src/JT808.Gateway/Client/JT808TcpClientFactory.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace JT808.Gateway.Client
+{
+ public interface IJT808TcpClientFactory : IDisposable
+ {
+ JT808TcpClient Create(DeviceConfig deviceConfig);
+
+ List GetAll();
+ }
+
+ public class JT808TcpClientFactory: IJT808TcpClientFactory
+ {
+ private readonly ConcurrentDictionary dict;
+
+ private readonly IServiceProvider serviceProvider;
+
+ public JT808TcpClientFactory(IServiceProvider serviceProvider)
+ {
+ dict = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
+ this.serviceProvider = serviceProvider;
+ }
+
+ public JT808TcpClient Create(DeviceConfig deviceConfig)
+ {
+ if(dict.TryGetValue(deviceConfig.TerminalPhoneNo,out var client))
+ {
+ return client;
+ }
+ else
+ {
+ JT808TcpClient jT808TcpClient = new JT808TcpClient(deviceConfig, serviceProvider);
+ dict.TryAdd(deviceConfig.TerminalPhoneNo, jT808TcpClient);
+ return jT808TcpClient;
+ }
+ }
+
+ public void Dispose()
+ {
+ foreach(var client in dict)
+ {
+ try
+ {
+ client.Value.Dispose();
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ public List GetAll()
+ {
+ return dict.Values.ToList();
+ }
+ }
+}
diff --git a/src/JT808.Gateway/Codecs/JT808ClientTcpDecoder.cs b/src/JT808.Gateway/Codecs/JT808ClientTcpDecoder.cs
new file mode 100644
index 0000000..c3aa8f1
--- /dev/null
+++ b/src/JT808.Gateway/Codecs/JT808ClientTcpDecoder.cs
@@ -0,0 +1,20 @@
+using DotNetty.Buffers;
+using DotNetty.Codecs;
+using System.Collections.Generic;
+using JT808.Protocol;
+using DotNetty.Transport.Channels;
+
+namespace JT808.Gateway.Codecs
+{
+ public class JT808ClientTcpDecoder : ByteToMessageDecoder
+ {
+ protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List