From 7711ff50e1268d364b157c552ff441c011b256fd Mon Sep 17 00:00:00 2001 From: "SmallChi(Koike)" <564952747@qq.com> Date: Mon, 17 Apr 2023 23:46:35 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=8E=BB=E6=8E=89=E4=B8=BB=E7=BA=BF=E7=9A=84?= =?UTF-8?q?dotnetty=E9=A1=B9=E7=9B=AE=202.=E5=B0=86=E5=90=84=E4=B8=AA?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=95=B4=E5=90=88=E5=88=B0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=BA=93=E9=87=8C=E9=9D=A2=E7=BB=9F=E4=B8=80=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dotnetcore.yml | 2 +- README.md | 58 +- api/README.md | 542 ++- api/README_DotNetty.md | 294 -- api/README_Pipeline.md | 541 --- doc/README.md | 16 - doc/dotnetty/performance_1000.png | Bin 132644 -> 0 bytes doc/dotnetty/performance_10000.png | Bin 160293 -> 0 bytes doc/dotnetty/performance_2000.png | Bin 139151 -> 0 bytes doc/dotnetty/performance_5000.png | Bin 156925 -> 0 bytes global.json | 5 + publish.bat | 18 - publish.gateway.bat | 6 - .../JT808.DotNetty.SimpleClient.csproj | 16 - .../JT808.DotNetty.SimpleClient/Program.cs | 42 - .../Services/Up2011Service.cs | 72 - .../Services/Up2013Service.cs | 100 - .../Services/Up2019Service.cs | 74 - .../JT808.DotNetty.SimpleQueueServer.csproj | 21 - .../Program.cs | 44 - .../appsettings.json | 25 - ...808DotNettyReplyMessageServiceInherited.cs | 41 - .../JT808.DotNetty.SimpleQueueService.csproj | 21 - .../Program.cs | 41 - .../appsettings.json | 25 - .../JT808.DotNetty.SimpleServer.csproj | 21 - .../JT808.DotNetty.SimpleServer/Program.cs | 44 - .../appsettings.json | 20 - simples/JT808.DotNettySimples.sln | 51 - .../Impl/JT808MsgIdHandlerImpl.cs | 1 - .../Startup.cs | 2 +- .../Impl/JT808SessionNoticeServiceImpl.cs | 2 +- .../Program.cs | 3 +- .../Impl/JT808MessageHandlerImpl.cs | 14 +- .../Impl/JT808MsgLogging.cs | 8 +- .../JT808.Gateway.SimpleServer.csproj | 2 +- simples/JT808.Gateway.SimpleServer/Program.cs | 23 +- simples/build.bat | 1 - simples/global.json | 5 - simples/netty.props | 18 - simples/pipeline.props | 5 - .../Dtos/JT808AtomicCounterDto.cs | 12 - .../Dtos/JT808DefaultResultDto.cs | 15 - .../Dtos/JT808IPAddressDto.cs | 37 - .../Dtos/JT808ResultDto.cs | 30 - .../Dtos/JT808TcpSessionInfoDto.cs | 24 - .../Dtos/JT808UdpSessionInfoDto.cs | 24 - .../Dtos/JT808UnificationSendRequestDto.cs | 11 - .../Enums/JT808TransportProtocolType.cs | 15 - .../IJT808ClientBuilder.cs | 15 - .../IJT808MsgConsumer.cs | 15 - .../IJT808MsgProducer.cs | 17 - .../IJT808MsgReplyConsumer.cs | 15 - .../IJT808MsgReplyProducer.cs | 17 - .../IJT808NettyBuilder.cs | 15 - .../IJT808PubSub.cs | 11 - .../IJT808SessionConsumer.cs | 18 - .../IJT808SessionProducer.cs | 13 - .../JT808.DotNetty.Abstractions.csproj | 32 - .../JT808NettyConstants.cs | 52 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - .../Configs/ClientBenchmarkOptions.cs | 24 - .../Configs/NLog.xsd | 3106 ----------------- .../Configs/nlog.unix.config | 36 - .../Configs/nlog.win.config | 35 - .../Controllers/ReportController.cs | 63 - .../JT808.DotNetty.CleintBenchmark.csproj | 59 - src/JT808.DotNetty.CleintBenchmark/Program.cs | 77 - .../Services/CleintBenchmarkHostedService.cs | 90 - .../appsettings.json | 24 - .../wwwroot/echarts.min.js | 13 - .../wwwroot/index.html | 153 - .../Codecs/JT808ClientTcpDecoder.cs | 20 - .../Codecs/JT808ClientTcpEncoder.cs | 54 - .../JT808TcpClientConnectionHandler.cs | 103 - .../Handlers/JT808TcpClientHandler.cs | 30 - .../JT808.DotNetty.Client.csproj | 37 - .../JT808ClientDotnettyExtensions.cs | 42 - .../JT808DeviceConfig.cs | 30 - .../JT808ReportOptions.cs | 25 - src/JT808.DotNetty.Client/JT808TcpClient.cs | 112 - .../JT808TcpClientExtensions.cs | 22 - .../JT808TcpClientFactory.cs | 62 - .../Metadata/JT808AtomicCounter.cs | 49 - .../Metadata/JT808ClientRequest.cs | 34 - .../Metadata/JT808Report.cs | 16 - .../JT808ReceiveAtomicCounterService.cs | 35 - .../Services/JT808ReportHostedService.cs | 67 - .../Services/JT808SendAtomicCounterService.cs | 35 - .../Codecs/JT808TcpDecoder.cs | 32 - .../Codecs/JT808TcpEncoder.cs | 52 - .../Codecs/JT808UdpDecoder.cs | 33 - .../Configurations/JT808Configuration.cs | 52 - .../ByteArrayHexTextJsonConverter.cs | 35 - .../Converters/JsonByteArrayHexConverter.cs | 29 - .../Converters/JsonIPAddressConverter.cs | 26 - .../Converters/JsonIPEndPointConverter.cs | 32 - .../Handlers/JT808MsgIdHttpHandlerBase.cs | 102 - .../Impls/JT808DatagramPacketImpl.cs | 21 - .../Impls/JT808DefaultChannelId.cs | 42 - .../Impls/JT808MsgProducerDefaultImpl.cs | 29 - .../Impls/JT808MsgReplyConsumerDefaultImpl.cs | 280 -- .../Impls/JT808NettyBuilderDefault.cs | 26 - .../Impls/JT808SessionProducerDefaultImpl.cs | 31 - .../Interfaces/IJT808DatagramPacket.cs | 13 - .../Interfaces/IJT808Reply.cs | 17 - .../Interfaces/IJT808Session.cs | 20 - .../Interfaces/IJT808SessionService.cs | 36 - .../IJT808UnificationSendService.cs | 12 - .../Interfaces/IJT808WebApiAuthorization.cs | 13 - .../Interfaces/IJT808WebApiNettyBuilder.cs | 16 - .../JT808.DotNetty.Core.csproj | 40 - .../JT808CoreDotnettyExtensions.cs | 58 - .../Metadata/JT808AtomicCounter.cs | 49 - .../Metadata/JT808HttpRequest.cs | 22 - .../Metadata/JT808HttpResponse.cs | 22 - .../Metadata/JT808TcpSession.cs | 32 - .../Metadata/JT808UdpPackage.cs | 20 - .../Metadata/JT808UdpSession.cs | 38 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - .../Services/JT808AtomicCounterService.cs | 52 - .../JT808AtomicCounterServiceFactory.cs | 30 - .../Services/JT808MsgReplyHostedService.cs | 42 - .../Services/JT808MsgService.cs | 11 - .../Services/JT808SessionService.cs | 127 - .../Services/JT808UnificationSendService.cs | 47 - .../Session/JT808SessionManager.cs | 304 -- .../Configs/JT808ConsumerConfig.cs | 15 - .../Configs/JT808MsgConsumerConfig.cs | 13 - .../Configs/JT808MsgProducerConfig.cs | 13 - .../Configs/JT808MsgReplyConsumerConfig.cs | 13 - .../Configs/JT808MsgReplyProducerConfig.cs | 13 - .../Configs/JT808ProducerConfig.cs | 15 - .../Configs/JT808SessionConsumerConfig.cs | 13 - .../Configs/JT808SessionProducerConfig.cs | 13 - .../JT808.DotNetty.Kafka.csproj | 36 - .../JT808ClientBuilderDefault.cs | 25 - .../JT808ClientKafkaExtensions.cs | 64 - src/JT808.DotNetty.Kafka/JT808MsgConsumer.cs | 99 - src/JT808.DotNetty.Kafka/JT808MsgProducer.cs | 54 - .../JT808MsgReplyConsumer.cs | 102 - .../JT808MsgReplyProducer.cs | 55 - .../JT808ServerKafkaExtensions.cs | 47 - .../JT808SessionConsumer.cs | 102 - .../JT808SessionProducer.cs | 55 - .../JT808.DotNetty.RabbitMQ.csproj | 22 - .../JT808MsgProducer.cs | 35 - .../JT808ProducerConfig.cs | 14 - .../JT808.DotNetty.MsgIdHandler.Test.csproj | 25 - .../JT808DotNettyMsgIdHandlerDefaultImpl.cs | 42 - .../Program.cs | 38 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 20 - .../JT808.DotNetty.MsgLogging.Test.csproj | 25 - .../JT808MsgLoggingImpl.cs | 49 - .../JT808.DotNetty.MsgLogging.Test/Program.cs | 42 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 25 - .../JT808.DotNetty.ReplyMessage.Test.csproj | 25 - ...808DotNettyReplyMessageServiceInherited.cs | 46 - .../Program.cs | 41 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 20 - .../JT808.DotNetty.SessionNotice.Test.csproj | 25 - ...08DotNettySessionNoticeServiceInherited.cs | 39 - .../Program.cs | 40 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 20 - .../JT808.DotNetty.Traffic.Test.csproj | 25 - .../JT808DotNettyTrafficServiceTest.cs | 39 - .../JT808.DotNetty.Traffic.Test/Program.cs | 43 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 20 - .../JT808.DotNetty.Transmit.Test.csproj | 25 - .../JT808DotNettyTransmitServiceTest.cs | 34 - .../JT808.DotNetty.Transmit.Test/Program.cs | 42 - .../Properties/launchSettings.json | 11 - .../appsettings.json | 20 - .../IJT808DotNettyMsgIdHandler.cs | 14 - .../JT808.DotNetty.MsgIdHandler.csproj | 31 - .../JT808DotNettyMsgIdHandlerExtensions.cs | 19 - .../JT808DotNettyMsgIdHandlerHostedService.cs | 34 - .../JT808.DotNetty.MsgLogging.csproj | 31 - ...T808DotNettyMsgDownLoggingHostedService.cs | 36 - .../JT808DotNettyMsgLoggingExtensions.cs | 20 - .../JT808DotNettyMsgUpLoggingHostedService.cs | 36 - .../JT808MsgLoggingType.cs | 18 - .../JT808.DotNetty.ReplyMessage.csproj | 29 - .../JT808DotNettyReplyMessageExtensions.cs | 58 - .../JT808DotNettyReplyMessageHostedService.cs | 34 - .../JT808DotNettyReplyMessageService.cs | 250 -- .../JT808.DotNetty.SessionNotice.csproj | 31 - .../JT808DotNettySessionNoticeExtensions.cs | 61 - ...JT808DotNettySessionNoticeHostedService.cs | 35 - .../JT808DotNettySessionNoticeService.cs | 25 - .../JT808.DotNetty.Traffic.csproj | 32 - .../JT808DotNettyTrafficService.cs | 32 - .../JT808DotNettyTrafficServiceExtensions.cs | 34 - ...T808DotNettyTrafficServiceHostedService.cs | 38 - .../TrafficRedisClient.cs | 9 - .../Configs/DataTransferOptions.cs | 13 - .../Configs/RemoteServerOptions.cs | 11 - .../Handlers/ClientConnectionHandler.cs | 76 - .../JT808.DotNetty.Transmit.csproj | 36 - .../JT808DotNettyTransmitExtensions.cs | 41 - .../JT808DotNettyTransmitHostedService.cs | 33 - .../JT808DotNettyTransmitService.cs | 236 -- .../Handlers/JT808TcpConnectionHandler.cs | 103 - .../Handlers/JT808TcpServerHandler.cs | 77 - .../JT808.DotNetty.Tcp.csproj | 28 - .../JT808TcpDotnettyExtensions.cs | 35 - src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs | 96 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - .../JT808.DotNetty.Core.Test.csproj | 29 - .../JT808TcpSessionManagerTest.cs | 74 - .../SeedTcpSession.cs | 27 - .../JT808.DotNetty.Hosting/Configs/NLog.xsd | 3106 ----------------- .../Configs/nlog.unix.config | 36 - .../Configs/nlog.win.config | 35 - .../JT808.DotNetty.Hosting.csproj | 44 - .../JT808.DotNetty.Hosting.ini | 6 - .../JT808.DotNetty.Hosting/Program.cs | 80 - .../JT808.DotNetty.Hosting/appsettings.json | 46 - .../JT808.DotNetty.Kafka.Test.csproj | 32 - .../JT808BaseTest.cs | 13 - .../JT808Config.json | 29 - .../JT808ConfigTest.cs | 54 - .../JT808MsgConsumerTest.cs | 35 - .../JT808MsgProducerTest.cs | 59 - .../JT808MsgReplyConsumerTest.cs | 36 - .../JT808MsgReplyProducerTest.cs | 59 - .../JT808SessionConsumerTest.cs | 36 - .../JT808SessionProducerTest.cs | 49 - .../JT808.DotNetty.RabbitMQ.Test.csproj | 15 - .../JT808.DotNetty.RabbitMQ.Test/UnitTest1.cs | 14 - .../JT808.DotNetty.Tcp.Test.csproj | 29 - .../JT808SessionServiceTest.cs | 88 - .../JT808.DotNetty.Tcp.Test/TestBase.cs | 69 - .../JT808.DotNetty.Udp.Test.csproj | 28 - .../JT808SessionServiceTest.cs | 95 - .../JT808.DotNetty.Udp.Test/TestBase.cs | 67 - .../JT808AuthorizationDefaultTest.cs | 62 - .../Handlers/JT808WebAPIServerHandlerTest.cs | 211 -- .../JT808.DotNetty.WebApi.Test.csproj | 29 - .../JT808HttpClientTest.cs | 159 - .../Handlers/JT808UdpServerHandler.cs | 79 - .../JT808.DotNetty.Udp.csproj | 29 - .../JT808UdpDotnettyExtensions.cs | 33 - src/JT808.DotNetty.Udp/JT808UdpServerHost.cs | 76 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - .../JT808AuthorizationDefault.cs | 51 - .../JT808MsgIdDefaultWebApiHandler.cs | 162 - .../Handlers/JT808WebAPIServerHandler.cs | 98 - .../JT808.DotNetty.WebApi.csproj | 28 - .../JT808WebAPIServerHost.cs | 82 - .../JT808WebApiBuilderDefault.cs | 37 - .../JT808WebApiDotnettyExtensions.cs | 33 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - .../JT808.DotNetty.WebApiClientTool.csproj | 36 - .../JT808.DotNetty.WebApiClientTool.xml | 46 - .../JT808HttpClient.cs | 97 - .../PublishProfiles/FolderProfile.pubxml | 13 - .../PublishProfiles/FolderProfile.pubxml.user | 6 - src/JT808.DotNetty.sln | 205 -- .../Configurations}/DataTransferOptions.cs | 2 +- .../Configurations}/RemoteServerOptions.cs | 2 +- .../Enums}/JT808MsgLoggingType.cs | 2 +- .../IJT808ClientBuilder.cs | 5 +- .../IJT808GatewayBuilder.cs | 5 +- .../IJT808MsgLogging.cs | 5 +- .../JT808.Gateway.Abstractions.csproj | 5 +- .../JT808.Gateway.Abstractions.xml | 15 + .../JT808.Gateway.CleintBenchmark.csproj | 4 +- .../JT808.Gateway.ServerBenchmark.csproj | 6 +- .../JT808.Gateway.ServerBenchmark/Program.cs | 2 - .../IJT808ClientBuilder.cs | 5 +- .../Internal/JT808ClientBuilderDefault.cs | 7 +- .../JT808.Gateway.Client.csproj | 3 +- .../JT808ClientExtensions.cs | 3 +- .../JT808.Gateway.Kafka.csproj | 2 +- .../JT808ClientBuilderDefault.cs | 7 +- .../JT808ClientKafkaExtensions.cs | 3 +- .../JT808.Gateway.MsgIdHandler.csproj | 17 - .../IJT808MsgLogging.cs | 15 - .../JT808.Gateway.MsgLogging.csproj | 20 - .../JT808.Gateway.MsgLogging.xml | 23 - .../JT808.Gateway.ReplyMessage.csproj | 19 - .../JT808.Gateway.ReplyMessage.xml | 34 - .../JT808.Gateway.SessionNotice.csproj | 20 - .../JT808.Gateway.SessionNotice.xml | 38 - .../JT808.Gateway.Transmit.csproj | 18 - .../JT808.Gateway.Transmit.xml | 45 - .../Impl/JT808CustomMessageHandlerImpl.cs | 4 +- .../Impl/JT808MsgLogging.cs | 8 +- .../JT808.Gateway.NormalHosting.csproj | 9 +- .../JT808.Gateway.NormalHosting/Program.cs | 28 +- .../Impl/JT808CustomMessageHandlerImpl.cs | 3 - .../JT808.Gateway.QueueHosting.csproj | 11 +- .../JT808.Gateway.QueueHosting/Program.cs | 12 +- .../JT808.Gateway.Test.csproj | 2 +- .../Session/JT808SessionManagerTest.cs | 18 + .../JT808.Gateway.WebApiClientTool.xml | 8 +- .../JT808HttpClientExtensions.cs | 9 +- src/JT808.Gateway.sln | 45 +- .../JT808MsgIdHandlerExtensions.cs | 3 +- .../Extensions}/JT808MsgLoggingExtensions.cs | 3 +- .../JT808ReplyMessageExtensions.cs | 3 +- .../JT808SessionNoticeExtensions.cs | 4 +- .../Extensions}/JT808TransmitExtensions.cs | 6 +- .../JT808MsgDownLoggingHostedService.cs | 3 +- .../JT808MsgDownReplyLoggingHostedService.cs | 3 +- .../JT808MsgIdHandlerHostedService.cs | 2 +- .../JT808MsgUpLoggingHostedService.cs | 3 +- .../JT808ReplyMessageHostedService.cs | 2 +- .../JT808SessionNoticeHostedService.cs | 3 +- .../JT808TransmitHostedService.cs | 3 +- .../Internal/JT808GatewayBuilderDefault.cs | 7 +- src/JT808.Gateway/JT808.Gateway.csproj | 6 +- src/JT808.Gateway/JT808.Gateway.xml | 110 +- src/JT808.Gateway/JT808GatewayExtensions.cs | 5 +- src/JT808.Gateway/JT808TcpServer.cs | 2 +- src/JT808.Gateway/JT808UdpServer.cs | 2 +- .../Services}/JT808SessionNoticeService.cs | 2 +- .../Services}/JT808TransmitService.cs | 19 +- src/PipelineInfo.props | 2 +- src/Version.props | 5 - src/global.json | 5 - 332 files changed, 849 insertions(+), 18054 deletions(-) delete mode 100644 api/README_DotNetty.md delete mode 100644 api/README_Pipeline.md delete mode 100644 doc/dotnetty/performance_1000.png delete mode 100644 doc/dotnetty/performance_10000.png delete mode 100644 doc/dotnetty/performance_2000.png delete mode 100644 doc/dotnetty/performance_5000.png create mode 100644 global.json delete mode 100644 publish.bat delete mode 100644 simples/JT808.DotNetty.SimpleClient/JT808.DotNetty.SimpleClient.csproj delete mode 100644 simples/JT808.DotNetty.SimpleClient/Program.cs delete mode 100644 simples/JT808.DotNetty.SimpleClient/Services/Up2011Service.cs delete mode 100644 simples/JT808.DotNetty.SimpleClient/Services/Up2013Service.cs delete mode 100644 simples/JT808.DotNetty.SimpleClient/Services/Up2019Service.cs delete mode 100644 simples/JT808.DotNetty.SimpleQueueServer/JT808.DotNetty.SimpleQueueServer.csproj delete mode 100644 simples/JT808.DotNetty.SimpleQueueServer/Program.cs delete mode 100644 simples/JT808.DotNetty.SimpleQueueServer/appsettings.json delete mode 100644 simples/JT808.DotNetty.SimpleQueueService/Impl/JT808DotNettyReplyMessageServiceInherited.cs delete mode 100644 simples/JT808.DotNetty.SimpleQueueService/JT808.DotNetty.SimpleQueueService.csproj delete mode 100644 simples/JT808.DotNetty.SimpleQueueService/Program.cs delete mode 100644 simples/JT808.DotNetty.SimpleQueueService/appsettings.json delete mode 100644 simples/JT808.DotNetty.SimpleServer/JT808.DotNetty.SimpleServer.csproj delete mode 100644 simples/JT808.DotNetty.SimpleServer/Program.cs delete mode 100644 simples/JT808.DotNetty.SimpleServer/appsettings.json delete mode 100644 simples/JT808.DotNettySimples.sln delete mode 100644 simples/global.json delete mode 100644 simples/netty.props delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808UdpSessionInfoDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Enums/JT808TransportProtocolType.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808ClientBuilder.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808MsgConsumer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808MsgProducer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808MsgReplyConsumer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808MsgReplyProducer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808NettyBuilder.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808PubSub.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808SessionConsumer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/IJT808SessionProducer.cs delete mode 100644 src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj delete mode 100644 src/JT808.DotNetty.Abstractions/JT808NettyConstants.cs delete mode 100644 src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Configs/ClientBenchmarkOptions.cs delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Configs/NLog.xsd delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Configs/nlog.unix.config delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Configs/nlog.win.config delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Controllers/ReportController.cs delete mode 100644 src/JT808.DotNetty.CleintBenchmark/JT808.DotNetty.CleintBenchmark.csproj delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Program.cs delete mode 100644 src/JT808.DotNetty.CleintBenchmark/Services/CleintBenchmarkHostedService.cs delete mode 100644 src/JT808.DotNetty.CleintBenchmark/appsettings.json delete mode 100644 src/JT808.DotNetty.CleintBenchmark/wwwroot/echarts.min.js delete mode 100644 src/JT808.DotNetty.CleintBenchmark/wwwroot/index.html delete mode 100644 src/JT808.DotNetty.Client/Codecs/JT808ClientTcpDecoder.cs delete mode 100644 src/JT808.DotNetty.Client/Codecs/JT808ClientTcpEncoder.cs delete mode 100644 src/JT808.DotNetty.Client/Handlers/JT808TcpClientConnectionHandler.cs delete mode 100644 src/JT808.DotNetty.Client/Handlers/JT808TcpClientHandler.cs delete mode 100644 src/JT808.DotNetty.Client/JT808.DotNetty.Client.csproj delete mode 100644 src/JT808.DotNetty.Client/JT808ClientDotnettyExtensions.cs delete mode 100644 src/JT808.DotNetty.Client/JT808DeviceConfig.cs delete mode 100644 src/JT808.DotNetty.Client/JT808ReportOptions.cs delete mode 100644 src/JT808.DotNetty.Client/JT808TcpClient.cs delete mode 100644 src/JT808.DotNetty.Client/JT808TcpClientExtensions.cs delete mode 100644 src/JT808.DotNetty.Client/JT808TcpClientFactory.cs delete mode 100644 src/JT808.DotNetty.Client/Metadata/JT808AtomicCounter.cs delete mode 100644 src/JT808.DotNetty.Client/Metadata/JT808ClientRequest.cs delete mode 100644 src/JT808.DotNetty.Client/Metadata/JT808Report.cs delete mode 100644 src/JT808.DotNetty.Client/Services/JT808ReceiveAtomicCounterService.cs delete mode 100644 src/JT808.DotNetty.Client/Services/JT808ReportHostedService.cs delete mode 100644 src/JT808.DotNetty.Client/Services/JT808SendAtomicCounterService.cs delete mode 100644 src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs delete mode 100644 src/JT808.DotNetty.Core/Codecs/JT808TcpEncoder.cs delete mode 100644 src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs delete mode 100644 src/JT808.DotNetty.Core/Configurations/JT808Configuration.cs delete mode 100644 src/JT808.DotNetty.Core/Converters/ByteArrayHexTextJsonConverter.cs delete mode 100644 src/JT808.DotNetty.Core/Converters/JsonByteArrayHexConverter.cs delete mode 100644 src/JT808.DotNetty.Core/Converters/JsonIPAddressConverter.cs delete mode 100644 src/JT808.DotNetty.Core/Converters/JsonIPEndPointConverter.cs delete mode 100644 src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808DatagramPacketImpl.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808DefaultChannelId.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808MsgProducerDefaultImpl.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808MsgReplyConsumerDefaultImpl.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808NettyBuilderDefault.cs delete mode 100644 src/JT808.DotNetty.Core/Impls/JT808SessionProducerDefaultImpl.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808DatagramPacket.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808Reply.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808Session.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808SessionService.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808UnificationSendService.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808WebApiAuthorization.cs delete mode 100644 src/JT808.DotNetty.Core/Interfaces/IJT808WebApiNettyBuilder.cs delete mode 100644 src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj delete mode 100644 src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808AtomicCounter.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808HttpRequest.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808HttpResponse.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808TcpSession.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808UdpPackage.cs delete mode 100644 src/JT808.DotNetty.Core/Metadata/JT808UdpSession.cs delete mode 100644 src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.Core/Services/JT808AtomicCounterService.cs delete mode 100644 src/JT808.DotNetty.Core/Services/JT808AtomicCounterServiceFactory.cs delete mode 100644 src/JT808.DotNetty.Core/Services/JT808MsgReplyHostedService.cs delete mode 100644 src/JT808.DotNetty.Core/Services/JT808MsgService.cs delete mode 100644 src/JT808.DotNetty.Core/Services/JT808SessionService.cs delete mode 100644 src/JT808.DotNetty.Core/Services/JT808UnificationSendService.cs delete mode 100644 src/JT808.DotNetty.Core/Session/JT808SessionManager.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808ConsumerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808MsgConsumerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808MsgProducerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyConsumerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyProducerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808ProducerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808SessionConsumerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/Configs/JT808SessionProducerConfig.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808.DotNetty.Kafka.csproj delete mode 100644 src/JT808.DotNetty.Kafka/JT808ClientBuilderDefault.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808ClientKafkaExtensions.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808MsgConsumer.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808MsgProducer.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808MsgReplyConsumer.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808MsgReplyProducer.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808ServerKafkaExtensions.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808SessionConsumer.cs delete mode 100644 src/JT808.DotNetty.Kafka/JT808SessionProducer.cs delete mode 100644 src/JT808.DotNetty.RabbitMQ/JT808.DotNetty.RabbitMQ.csproj delete mode 100644 src/JT808.DotNetty.RabbitMQ/JT808MsgProducer.cs delete mode 100644 src/JT808.DotNetty.RabbitMQ/JT808ProducerConfig.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808.DotNetty.MsgIdHandler.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808.DotNetty.MsgLogging.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808MsgLoggingImpl.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808.DotNetty.ReplyMessage.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808.DotNetty.SessionNotice.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808.DotNetty.Traffic.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808DotNettyTrafficServiceTest.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808.DotNetty.Transmit.Test.csproj delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808DotNettyTransmitServiceTest.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Program.cs delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Properties/launchSettings.json delete mode 100644 src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/appsettings.json delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/IJT808DotNettyMsgIdHandler.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808.DotNetty.MsgIdHandler.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808.DotNetty.MsgLogging.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgDownLoggingHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgLoggingExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgUpLoggingHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808MsgLoggingType.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808.DotNetty.ReplyMessage.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808.DotNetty.SessionNotice.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808.DotNetty.Traffic.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/TrafficRedisClient.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/DataTransferOptions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/RemoteServerOptions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Handlers/ClientConnectionHandler.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808.DotNetty.Transmit.csproj delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitExtensions.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitHostedService.cs delete mode 100644 src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitService.cs delete mode 100644 src/JT808.DotNetty.Tcp/Handlers/JT808TcpConnectionHandler.cs delete mode 100644 src/JT808.DotNetty.Tcp/Handlers/JT808TcpServerHandler.cs delete mode 100644 src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj delete mode 100644 src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs delete mode 100644 src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs delete mode 100644 src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/NLog.xsd delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.unix.config delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.win.config delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.ini delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Program.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/appsettings.json delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808.DotNetty.Kafka.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808BaseTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808Config.json delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808ConfigTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgConsumerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgProducerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyConsumerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyProducerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionConsumerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionProducerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/JT808.DotNetty.RabbitMQ.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/UnitTest1.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Authorization/JT808AuthorizationDefaultTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Handlers/JT808WebAPIServerHandlerTest.cs delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj delete mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808HttpClientTest.cs delete mode 100644 src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs delete mode 100644 src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj delete mode 100644 src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs delete mode 100644 src/JT808.DotNetty.Udp/JT808UdpServerHost.cs delete mode 100644 src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.WebApi/Authorization/JT808AuthorizationDefault.cs delete mode 100644 src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs delete mode 100644 src/JT808.DotNetty.WebApi/Handlers/JT808WebAPIServerHandler.cs delete mode 100644 src/JT808.DotNetty.WebApi/JT808.DotNetty.WebApi.csproj delete mode 100644 src/JT808.DotNetty.WebApi/JT808WebAPIServerHost.cs delete mode 100644 src/JT808.DotNetty.WebApi/JT808WebApiBuilderDefault.cs delete mode 100644 src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs delete mode 100644 src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.csproj delete mode 100644 src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.xml delete mode 100644 src/JT808.DotNetty.WebApiClientTool/JT808HttpClient.cs delete mode 100644 src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 src/JT808.DotNetty.sln rename src/{JT808.Gateway.Services/JT808.Gateway.Transmit/Configs => JT808.Gateway.Abstractions/Configurations}/DataTransferOptions.cs (80%) rename src/{JT808.Gateway.Services/JT808.Gateway.Transmit/Configs => JT808.Gateway.Abstractions/Configurations}/RemoteServerOptions.cs (78%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgLogging => JT808.Gateway.Abstractions/Enums}/JT808MsgLoggingType.cs (87%) rename src/{JT808.DotNetty.Services/JT808.DotNetty.MsgLogging => JT808.Gateway.Abstractions}/IJT808MsgLogging.cs (77%) delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808.Gateway.MsgIdHandler.csproj delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/IJT808MsgLogging.cs delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.xml delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.xml delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.xml delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj delete mode 100644 src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.xml rename src/{JT808.Gateway.Services/JT808.Gateway.MsgIdHandler => JT808.Gateway/Extensions}/JT808MsgIdHandlerExtensions.cs (90%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgLogging => JT808.Gateway/Extensions}/JT808MsgLoggingExtensions.cs (94%) rename src/{JT808.Gateway.Services/JT808.Gateway.ReplyMessage => JT808.Gateway/Extensions}/JT808ReplyMessageExtensions.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.SessionNotice => JT808.Gateway/Extensions}/JT808SessionNoticeExtensions.cs (96%) rename src/{JT808.Gateway.Services/JT808.Gateway.Transmit => JT808.Gateway/Extensions}/JT808TransmitExtensions.cs (91%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgLogging => JT808.Gateway/HostedServices}/JT808MsgDownLoggingHostedService.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgLogging => JT808.Gateway/HostedServices}/JT808MsgDownReplyLoggingHostedService.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgIdHandler => JT808.Gateway/HostedServices}/JT808MsgIdHandlerHostedService.cs (96%) rename src/{JT808.Gateway.Services/JT808.Gateway.MsgLogging => JT808.Gateway/HostedServices}/JT808MsgUpLoggingHostedService.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.ReplyMessage => JT808.Gateway/HostedServices}/JT808ReplyMessageHostedService.cs (98%) rename src/{JT808.Gateway.Services/JT808.Gateway.SessionNotice => JT808.Gateway/HostedServices}/JT808SessionNoticeHostedService.cs (94%) rename src/{JT808.Gateway.Services/JT808.Gateway.Transmit => JT808.Gateway/HostedServices}/JT808TransmitHostedService.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.SessionNotice => JT808.Gateway/Services}/JT808SessionNoticeService.cs (93%) rename src/{JT808.Gateway.Services/JT808.Gateway.Transmit => JT808.Gateway/Services}/JT808TransmitService.cs (97%) delete mode 100644 src/Version.props delete mode 100644 src/global.json diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 8554994..21f43ce 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -12,7 +12,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@master with: - dotnet-version: 7.0.100 + dotnet-version: 7.0.203 - name: dotnet info run: dotnet --info - name: dotnet JT808.Gateway restore diff --git a/README.md b/README.md index 209847d..62e5271 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # JT808Gateway -基于Pipeline封装的JT808Pipeline支持TCP/UDP通用消息业务处理 - -基于DotNetty封装的JT808DotNetty支持TCP/UDP通用消息业务处理 +JT808Pipeline支持TCP/UDP通用消息业务处理 [了解JT808协议进这边](https://github.com/SmallChi/JT808) @@ -42,26 +40,13 @@ > 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 -## 基于网关的相关服务 - -| 服务名称 | 服务说明 | 使用场景 | -| :-------------------------------- | :----------- | :----------------------------------------------------------------------------------------------------------------- | -| MsgIdHandler | 消息处理服务 | 从队列中消费设备上报数据,再结合自身的业务场景,将数据进行处理并入库 | -| MsgLogging | 消息日志服务 | 从队列中消费设备上报和平台应答数据,再将数据存入influxdb等数据库中,便于技术和技术支持排查设备与平台交互的原始数据 | -| ReplyMessage | 消息响应服务 | 用于响应设备上报消息,以及下发指令信息到设备 | -| SessionNotice | 会话管理服务 | 通知设备上线下线,对于udp设备来说,可以在设备上线时,将指令跟随消息下发到设备 | -| Traffic (v1.1.0新版pipeline已移出) | 流量统计服务 | 由于运营商sim卡查询流量滞后,通过流量统计服务可以实时准确的统计设备流量,可以最优配置设备的流量大小,以节省成本 | -| Transmit | 原包转发服务 | 该服务可以将设备上报原始数据转发到第三方,支持全部转发,指定终端号转发 | - ## 基于WebApi的消息业务处理程序 -通过继承JT808.DotNetty.Core.Handlers.JT808MsgIdHttpHandlerBase去实现自定义的WebApi接口服务。 - 通过继承JT808.Gateway.Handlers.JT808MsgIdDefaultWebApiHandler去实现自定义的WebApi接口服务。 [接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api) -## 基于NET5.0 Pipeline +## 基于Pipeline Pipeline分为两种方式使用,一种是使用队列的方式,一种是网关集成的方式。 @@ -78,33 +63,7 @@ Pipeline分为两种方式使用,一种是使用队列的方式,一种是网 | Install-Package JT808.Gateway | ![JT808.Gateway](https://img.shields.io/nuget/v/JT808.Gateway.svg) | ![JT808.Gateway](https://img.shields.io/nuget/vpre/JT808.Gateway.svg) | ![JT808.Gateway](https://img.shields.io/nuget/dt/JT808.Gateway.svg) | | Install-Package JT808.Gateway.WebApiClientTool | ![JT808.Gateway.WebApiClientTool](https://img.shields.io/nuget/v/JT808.Gateway.WebApiClientTool.svg) | ![JT808.Gateway.WebApiClientTool](https://img.shields.io/nuget/vpre/JT808.Gateway.WebApiClientTool.svg) | ![JT808.Gateway.WebApiClientTool](https://img.shields.io/nuget/dt/JT808.Gateway.WebApiClientTool.svg) | | Install-Package JT808.Gateway.Client | ![JT808.Gateway.Client](https://img.shields.io/nuget/v/JT808.Gateway.Client.svg) | ![JT808.Gateway.Client](https://img.shields.io/nuget/vpre/JT808.Gateway.Client.svg) | ![JT808.Gateway.Client](https://img.shields.io/nuget/dt/JT808.Gateway.Client.svg) | -| Install-Package JT808.Gateway.Kafka | ![JT808.Gateway.Kafka](https://img.shields.io/nuget/v/JT808.Gateway.Kafka.svg) | ![JT808.Gateway.Kafka](https://img.shields.io/nuget/vpre/JT808.Gateway.Kafka.svg) | ![JT808.Gateway.Kafka](https://img.shields.io/nuget/dt/JT808.Gateway.Kafka.svg) | -| Install-Package JT808.Gateway.Transmit | ![JT808.Gateway.Transmit](https://img.shields.io/nuget/v/JT808.Gateway.Transmit.svg) | ![JT808.Gateway.Transmit](https://img.shields.io/nuget/vpre/JT808.Gateway.Transmit.svg) | ![JT808.Gateway.Transmit](https://img.shields.io/nuget/dt/JT808.Gateway.Transmit.svg) | -| Install-Package JT808.Gateway.SessionNotice | ![JT808.Gateway.SessionNotice](https://img.shields.io/nuget/v/JT808.Gateway.SessionNotice.svg) | ![JT808.Gateway.SessionNotice](https://img.shields.io/nuget/vpre/JT808.Gateway.SessionNotice.svg) | ![JT808.Gateway.SessionNotice](https://img.shields.io/nuget/dt/JT808.Gateway.SessionNotice.svg) | -| Install-Package JT808.Gateway.ReplyMessage | ![JT808.Gateway.ReplyMessage](https://img.shields.io/nuget/v/JT808.Gateway.ReplyMessage.svg) | ![JT808.Gateway.ReplyMessage](https://img.shields.io/nuget/vpre/JT808.Gateway.ReplyMessage.svg) | ![JT808.Gateway.ReplyMessage](https://img.shields.io/nuget/dt/JT808.Gateway.ReplyMessage.svg) | -| Install-Package JT808.Gateway.MsgLogging | ![JT808.Gateway.MsgLogging](https://img.shields.io/nuget/v/JT808.Gateway.MsgLogging.svg) | ![JT808.Gateway.MsgLogging](https://img.shields.io/nuget/vpre/JT808.Gateway.MsgLogging.svg) | ![JT808.Gateway.MsgLogging](https://img.shields.io/nuget/dt/JT808.Gateway.MsgLogging.svg) | -| Install-Package JT808.Gateway.MsgIdHandler | ![JT808.Gateway.MsgIdHandler](https://img.shields.io/nuget/v/JT808.Gateway.MsgIdHandler.svg) | ![JT808.Gateway.MsgIdHandler](https://img.shields.io/nuget/vpre/JT808.Gateway.MsgIdHandler.svg) | ![JT808.Gateway.MsgIdHandler](https://img.shields.io/nuget/dt/JT808.Gateway.MsgIdHandler.svg) | - -## 基于DotNetty - -### DotNetty的NuGet安装 - -| Package Name| Version |Preview Version | Downloads| -| --- | --- | ---| ---| -| Install-Package JT808.DotNetty.Abstractions | ![JT808.DotNetty.Abstractions](https://img.shields.io/nuget/v/JT808.DotNetty.Abstractions.svg)| ![JT808.DotNetty.Abstractions](https://img.shields.io/nuget/vpre/JT808.DotNetty.Abstractions.svg) | ![JT808.DotNetty.Abstractions](https://img.shields.io/nuget/dt/JT808.DotNetty.Abstractions.svg) | -| Install-Package JT808.DotNetty.Core | ![JT808.DotNetty.Core](https://img.shields.io/nuget/v/JT808.DotNetty.Core.svg) | ![JT808.DotNetty.Core](https://img.shields.io/nuget/vpre/JT808.DotNetty.Core.svg) | ![JT808.DotNetty.Core](https://img.shields.io/nuget/dt/JT808.DotNetty.Core.svg) | -| Install-Package JT808.DotNetty.Tcp | ![JT808.DotNetty.Tcp](https://img.shields.io/nuget/v/JT808.DotNetty.Tcp.svg) | ![JT808.DotNetty.Tcp](https://img.shields.io/nuget/vpre/JT808.DotNetty.Tcp.svg) | ![JT808.DotNetty.Tcp](https://img.shields.io/nuget/dt/JT808.DotNetty.Tcp.svg) | -| Install-Package JT808.DotNetty.Udp | ![JT808.DotNetty.Udp](https://img.shields.io/nuget/v/JT808.DotNetty.Udp.svg) | ![JT808.DotNetty.Udp](https://img.shields.io/nuget/vpre/JT808.DotNetty.Udp.svg) | ![JT808.DotNetty.Udp](https://img.shields.io/nuget/dt/JT808.DotNetty.Udp.svg) | -| Install-Package JT808.DotNetty.WebApi | ![JT808.DotNetty.WebApi](https://img.shields.io/nuget/v/JT808.DotNetty.WebApi.svg) | ![JT808.DotNetty.WebApi](https://img.shields.io/nuget/vpre/JT808.DotNetty.WebApi.svg) | ![JT808.DotNetty.WebApi](https://img.shields.io/nuget/dt/JT808.DotNetty.WebApi.svg) | -| Install-Package JT808.DotNetty.WebApiClientTool | ![JT808.DotNetty.WebApiClientTool](https://img.shields.io/nuget/v/JT808.DotNetty.WebApiClientTool.svg) | ![JT808.DotNetty.WebApiClientTool](https://img.shields.io/nuget/vpre/JT808.DotNetty.WebApiClientTool.svg) | ![JT808.DotNetty.WebApiClientTool](https://img.shields.io/nuget/dt/JT808.DotNetty.WebApiClientTool.svg) | -| Install-Package JT808.DotNetty.Client | ![JT808.DotNetty.Client](https://img.shields.io/nuget/v/JT808.DotNetty.Client.svg) | ![JT808.DotNetty.Client](https://img.shields.io/nuget/vpre/JT808.DotNetty.Client.svg) | ![JT808.DotNetty.Client](https://img.shields.io/nuget/dt/JT808.DotNetty.Client.svg) | -| Install-Package JT808.DotNetty.Transmit | ![JT808.DotNetty.Transmit](https://img.shields.io/nuget/v/JT808.DotNetty.Transmit.svg) | ![JT808.DotNetty.Transmit](https://img.shields.io/nuget/vpre/JT808.DotNetty.Transmit.svg) | ![JT808.DotNetty.Transmit](https://img.shields.io/nuget/dt/JT808.DotNetty.Transmit.svg) | -| Install-Package JT808.DotNetty.Traffic | ![JT808.DotNetty.Traffic](https://img.shields.io/nuget/v/JT808.DotNetty.Traffic.svg) | ![JT808.DotNetty.Traffic](https://img.shields.io/nuget/vpre/JT808.DotNetty.Traffic.svg) | ![JT808.DotNetty.Traffic](https://img.shields.io/nuget/dt/JT808.DotNetty.Traffic.svg) | -| Install-Package JT808.DotNetty.SessionNotice | ![JT808.DotNetty.SessionNotice](https://img.shields.io/nuget/v/JT808.DotNetty.SessionNotice.svg)| ![JT808.DotNetty.SessionNotice](https://img.shields.io/nuget/vpre/JT808.DotNetty.SessionNotice.svg) | ![JT808.DotNetty.SessionNotice](https://img.shields.io/nuget/dt/JT808.DotNetty.SessionNotice.svg) | -| Install-Package JT808.DotNetty.ReplyMessage | ![JT808.DotNetty.ReplyMessage](https://img.shields.io/nuget/v/JT808.DotNetty.ReplyMessage.svg) | ![JT808.DotNetty.ReplyMessage](https://img.shields.io/nuget/vpre/JT808.DotNetty.ReplyMessage.svg) | ![JT808.DotNetty.ReplyMessage](https://img.shields.io/nuget/dt/JT808.DotNetty.ReplyMessage.svg) | -| Install-Package JT808.DotNetty.MsgLogging | ![JT808.DotNetty.MsgLogging](https://img.shields.io/nuget/v/JT808.DotNetty.MsgLogging.svg) | ![JT808.DotNetty.Abstractions](https://img.shields.io/nuget/vpre/JT808.DotNetty.MsgLogging.svg) | ![JT808.DotNetty.MsgLogging](https://img.shields.io/nuget/dt/JT808.DotNetty.MsgLogging.svg) || ![JT808.DotNetty.MsgLogging](https://img.shields.io/nuget/vpre/JT808.DotNetty.MsgLogging.svg) -| Install-Package JT808.DotNetty.MsgIdHandler | ![JT808.DotNetty.MsgIdHandler](https://img.shields.io/nuget/v/JT808.DotNetty.MsgIdHandler.svg) | ![JT808.DotNetty.MsgIdHandler](https://img.shields.io/nuget/vpre/JT808.DotNetty.MsgIdHandler.svg) | ![JT808.DotNetty.MsgIdHandler](https://img.shields.io/nuget/dt/JT808.DotNetty.MsgIdHandler.svg) | -| Install-Package JT808.DotNetty.Kafka | ![JT808.DotNetty.Kafka](https://img.shields.io/nuget/v/JT808.DotNetty.Kafka.svg) | ![JT808.DotNetty.Kafka](https://img.shields.io/nuget/vpre/JT808.DotNetty.Kafka.svg) | ![JT808.DotNetty.Kafka](https://img.shields.io/nuget/dt/JT808.DotNetty.Kafka.svg) | ![JT808.DotNetty.Kafka](https://img.shields.io/nuget/vpre/JT808.DotNetty.Kafka.svg) | +| Install-Package JT808.Gateway.Kafka | ![JT808.Gateway.Kafka](https://img.shields.io/nuget/v/JT808.Gateway.Kafka.svg) | ![JT808.Gateway.Kafka](https://img.shields.io/nuget/vpre/JT808.Gateway.Kafka.svg) | ![JT808.Gateway.MsgIdHandler](https://img.shields.io/nuget/dt/JT808.Gateway.MsgIdHandler.svg) | ## 举个栗子 @@ -139,17 +98,6 @@ Pipeline分为两种方式使用,一种是使用队列的方式,一种是网 如图所示: ![demo4](https://github.com/SmallChi/JT808Gateway/blob/master/doc/img/demo4.png) -### DotNetty - -1.打开/simples/JT808.Simples.sln项目进行还原编译生成 - -2.进入JT808.DotNetty.SimpleServer项目下的Debug目录运行服务端 - -3.进入JT808.DotNetty.SimpleClient项目下的Debug目录运行客户端 - -如图所示: -![demo2](https://github.com/SmallChi/JT808Gateway/blob/master/doc/img/demo2.png) - ## 常见问题 - 多协议兼容实现思路[点我查看](https://github.com/SmallChi/JT808Gateway/issues/11#issuecomment-727687417) diff --git a/api/README.md b/api/README.md index e827127..2414df6 100644 --- a/api/README.md +++ b/api/README.md @@ -1,5 +1,541 @@ -# JT808 WebApi 接口文档 +# 基于JT808Gateway WebApi 接口文档 -[基于JT808Gateway WebApi接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api/README_Pipeline.md) +基地址:127.0.0.1:828/jt808api/ -[基于JT808DotNetty WebApi接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api/README_DotNetty.md) +> 注意url格式 + +数据格式:只支持Json格式 + +默认端口:828 + +## 1.统一下发设备消息服务 + +[统一下发设备消息服务](#send) + +## 2.管理会话服务 + +[基于Tcp管理会话服务](#tcp_session) + +[基于Udp管理会话服务](#udp_session) + +## 3.SIM黑名单管理服务 + +[SIM黑名单管理服务](#blacklist) + +## 接口请求对照表 + +### 公共接口请求 + +|请求Url|请求方式|说明| +|:------|:------|:------| +| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| + +### 基于Tcp接口请求 + +|请求Url|请求方式|说明| +|:------|:------|:------| +| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| +| 127.0.0.1:828/jt808api/Tcp/Session/SessionTcpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| +| 127.0.0.1:828/jt808api/Tcp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| +| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| + +### 基于Udp接口请求 + +|请求Url|请求方式|说明| +|:------|:------|:------| +| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| +| 127.0.0.1:828/jt808api/Udp/Session/SessionUdpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| +| 127.0.0.1:828/jt808api/Udp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号查询对应会话| +| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| + +### SIM黑名单管理接口请求 + +|请求Url|请求方式|说明| +|:------|:------|:------| +| 127.0.0.1:828/jt808api/Blacklist/Add| POST| SIM卡黑名单服务-将对应SIM号加入黑名单| +| 127.0.0.1:828/jt808api/Blacklist/Remove| POST| SIM卡黑名单服务-将对应SIM号移除黑名单| +| 127.0.0.1:828/jt808api/Blacklist/GetAll| Get| SIM卡黑名单服务-获取所有sim的黑名单列表| + +### 统一对象返回 JT808ResultDto\ + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Message| string| 消息描述| +| Code| int| 状态码| +| Data| T(泛型)| 数据| + +返回Code[状态码]说明: + +|状态码|说明| +|:------:|:------:| +| 200 | 返回成功 | +| 201 | 内容为空 | +| 404 | 没有该服务 | +| 500 | 服务内部错误 | + +### 基于Tcp统一下发设备消息服务 + +请求地址:/UnificationSend + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|------|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| +| HexData| string| JT808 Hex String JT808数据包字符串| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", + "HexData":"7E****7E" +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| bool| 是否成功| + +返回结果: + +``` result1 +{ + "Message":"", + "Code":200, + "Data":true +} +``` + +### 基于Tcp管理会话服务 + +#### 统一会话信息对象返回 JT808TcpSessionInfoDto + +|属性|数据类型|参数说明| +|------|------|------| +| LastActiveTime| DateTime| 最后上线时间| +| StartTime| DateTime| 上线时间| +| TerminalPhoneNo|string| 终端手机号| +| RemoteAddressIP| string| 远程ip地址| + +#### 1.获取会话集合 + +请求地址:Tcp/Session/GetAll + +请求方式:GET + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| List\ | 实际会话信息集合 | + +返回结果: + +``` session1 +{ + "Message":"", + "Code":200, + "Data":[ + { + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789012", + "RemoteAddressIP":"127.0.0.1:11808" + },{ + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789013", + "RemoteAddressIP":"127.0.0.1:11808" + } + ] +} +``` + +#### 2.通过设备终端号查询对应会话 + +请求地址:Tcp/Session/QuerySessionByTerminalPhoneNo + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| JT808TcpSessionInfoDto对象 | 统一会话信息对象返回 | + +返回结果: + +``` session2 +{ + "Message":"", + "Code":200, + "Data": { + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789012", + "RemoteAddressIP":"127.0.0.1:11808" + } +} +``` + +#### 3.通过设备终端号移除对应会话 + +请求地址:Tcp/Session/RemoveByTerminalPhoneNo + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| bool | 是否成功 + +返回结果: + +``` session3 +{ + "Message":"", + "Code":200, + "Data":true +} +``` + +#### 4.获取会话分页集合 + +请求地址:Tcp/Session/SessionTcpByPage + +请求方式:GET + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| pageIndex| int| 当前页(默认0)| +| pageSize| int| 页容量(默认10)| + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| List\ | 实际会话信息集合 | +| PageIndex| int | 当前页(默认0) | +| PageSize| int | 页容量(默认10) | +| Total| int | 总数 | + +返回结果: + +``` session1 +{ + "message":null, + "code":200, + "data":{ + "pageIndex":0, + "pageSize":10, + "total":2, + "data":[ + { + "lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", + "startTime":"2022-09-03T19:34:07.8733615+08:00", + "terminalPhoneNo":"123456789012", + "remoteAddressIP":"127.0.0.1:9826" + }, + { + "lastActiveTime":"2022-09-03T19:34:05.135997+08:00", + "startTime":"2022-09-03T19:34:05.136035+08:00", + "terminalPhoneNo":"123456789013", + "remoteAddressIP":"127.0.0.1:9825" + } + ] + } +} +``` + +### 基于Udp管理会话服务 + +#### 统一会话信息对象返回 JT808UdpSessionInfoDto + +|属性|数据类型|参数说明| +|------|------|------| +| LastActiveTime| DateTime| 最后上线时间| +| StartTime| DateTime| 上线时间| +| TerminalPhoneNo|string| 终端手机号| +| RemoteAddressIP| string| 远程ip地址| + +#### 1.获取会话集合 + +请求地址:Udp/Session/GetAll + +请求方式:GET + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| List\ | 实际会话信息集合 | + +返回结果: + +``` session1 +{ + "Message":"", + "Code":200, + "Data":[ + { + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789012", + "RemoteAddressIP":"127.0.0.1:11808" + },{ + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789013", + "RemoteAddressIP":"127.0.0.1:11808" + } + ] +} +``` + +#### 2.通过设备终端号查询对应会话 + +请求地址:Udp/Session/QuerySessionByTerminalPhoneNo + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| JT808UdpSessionInfoDto对象 | 统一会话信息对象返回 | + +返回结果: + +``` session2 +{ + "Message":"", + "Code":200, + "Data":{ + "LastActiveTime":"2018-11-27 20:00:00", + "StartTime":"2018-11-25 20:00:00", + "TerminalPhoneNo":"123456789012", + "RemoteAddressIP":"127.0.0.1:11808" + } +} +``` + +#### 3.通过设备终端号移除对应会话 + +请求地址:Udp/Session/RemoveByTerminalPhoneNo + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| bool | 是否成功 + +返回结果: + +``` session3 +{ + "Message":"", + "Code":200, + "Data":true +} +``` + +#### 4.获取会话分页集合 + +请求地址:Udp/Session/SessionUdpByPage + +请求方式:GET + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| pageIndex| int| 当前页(默认0)| +| pageSize| int| 页容量(默认10)| + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| List\ | 实际会话信息集合 | +| PageIndex| int | 当前页(默认0) | +| PageSize| int | 页容量(默认10) | +| Total| int | 总数 | + +返回结果: + +``` session1 +{ + "message":null, + "code":200, + "data":{ + "pageIndex":0, + "pageSize":10, + "total":2, + "data":[ + { + "lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", + "startTime":"2022-09-03T19:34:07.8733615+08:00", + "terminalPhoneNo":"123456789012", + "remoteAddressIP":"127.0.0.1:9826" + }, + { + "lastActiveTime":"2022-09-03T19:34:05.135997+08:00", + "startTime":"2022-09-03T19:34:05.136035+08:00", + "terminalPhoneNo":"123456789013", + "remoteAddressIP":"127.0.0.1:9825" + } + ] + } +} +``` + +### SIM黑名单管理服务 + +#### 1.添加sim卡黑名单 + +请求地址:Blacklist/Add + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| bool | 是否成功 + +返回结果: + +``` session3 +{ + "Message":"", + "Code":200, + "Data":true +} +``` + +#### 2.移除sim卡黑名单 + +请求地址:Blacklist/Remove + +请求方式:POST + +请求参数: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| TerminalPhoneNo| string| 设备终端号| + +``` 1 +{ + "TerminalPhoneNo":"123456789012", +} +``` + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| Data| bool | 是否成功 + +返回结果: + +``` session3 +{ + "Message":"", + "Code":200, + "Data":true +} +``` + +#### 3.获取sim卡黑名单 + +请求地址:Blacklist/GetAll + +请求方式:GET + +返回数据: + +|属性|数据类型|参数说明| +|:------:|:------:|:------| +| terminalPhoneNo| List\| 设备终端号集合| + +返回结果: + +``` session3 +{ + "Message":"", + "Code":200, + "Data":[ + "12345678901", + "12345678902" + ] +} +``` diff --git a/api/README_DotNetty.md b/api/README_DotNetty.md deleted file mode 100644 index 7125579..0000000 --- a/api/README_DotNetty.md +++ /dev/null @@ -1,294 +0,0 @@ -# 基于JT808DotNetty WebApi 接口文档 - -基地址:127.0.0.1:828/jt808api/ - -> 注意url格式 - -数据格式:只支持Json格式 - -默认端口:828 - -## 1.统一下发设备消息服务 - -[统一下发设备消息服务](#send) - -## 2.管理会话服务 - -[基于Tcp管理会话服务](#tcp_session) - -[基于Udp管理会话服务](#udp_session) - -## 4.消息包计数服务 - -[基于Tcp消息包计数服务](#tcp_counter) - -[基于Udp消息包计数服务](#udp_counter) - -## 接口请求对照表 - -### 公共接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| - -### 基于Tcp接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| -| 127.0.0.1:828/jt808api/Tcp/Session/QueryTcpSessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| -| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| -| 127.0.0.1:828/jt808api/Tcp/GetAtomicCounter| GET| 基于Tcp消息包计数服务| - -### 基于Udp接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| -| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| -| 127.0.0.1:828/jt808api/Udp/GetAtomicCounter| GET| 基于Udp消息包计数服务| - -### 统一对象返回 JT808ResultDto\ - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Message| string| 消息描述| -| Code| int| 状态码| -| Data| T(泛型)| 数据| - -返回Code[状态码]说明: - -|状态码|说明| -|:------:|:------:| -| 200 | 返回成功 | -| 201 | 内容为空 | -| 404 | 没有该服务 | -| 500 | 服务内部错误 | - -### 基于Tcp统一下发设备消息服务 - -请求地址:/UnificationSend - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|------|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| -| Data| byte[]| JT808 byte[]数组| - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool| 是否成功| - -返回结果: - -``` result1 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -### 基于Tcp管理会话服务 - -#### 统一会话信息对象返回 JT808TcpSessionInfoDto - -|属性|数据类型|参数说明| -|------|------|------| -| LastActiveTime| DateTime| 最后上线时间| -| StartTime| DateTime| 上线时间| -| TerminalPhoneNo|string| 终端手机号| -| RemoteAddressIP| string| 远程ip地址| - -#### 1.获取会话集合 - -请求地址:Tcp/Session/GetAll - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | - -返回结果: - -``` session1 -{ - "Message":"", - "Code":200, - "Data":[ - { - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - },{ - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789013", - "RemoteAddressIP":"127.0.0.1:11808" - } - ] -} -``` - -#### 2.通过设备终端号移除对应会话 - -请求地址:Tcp/Session/RemoveByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| terminalPhoneNo| string| 设备终端号| - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -### 基于Udp管理会话服务 - -#### 统一会话信息对象返回 JT808UdpSessionInfoDto - -|属性|数据类型|参数说明| -|------|------|------| -| LastActiveTime| DateTime| 最后上线时间| -| StartTime| DateTime| 上线时间| -| TerminalPhoneNo|string| 终端手机号| -| RemoteAddressIP| string| 远程ip地址| - -#### 1.获取会话集合 - -请求地址:Udp/Session/GetAll - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | - -返回结果: - -``` session1 -{ - "Message":"", - "Code":200, - "Data":[ - { - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - },{ - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789013", - "RemoteAddressIP":"127.0.0.1:11808" - } - ] -} -``` - -#### 2.通过设备终端号移除对应会话 - -请求地址:Udp/Session/RemoveByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| terminalPhoneNo| string| 设备终端号| - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -### 基于Tcp消息包计数服务 - -请求地址:Tcp/GetAtomicCounter - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|------|:------:|:------| -| MsgSuccessCount| long| 消息包成功数| -| MsgFailCount| long| 消息包失败数| - -返回结果: - -``` counter -{ - "Message":"", - "Code":200, - "Data":{ - "MsgSuccessCount":10000, - "MsgFailCount":0 - } -} -``` - -### 基于Udp消息包计数服务 - -请求地址:Udp/GetAtomicCounter - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|------|:------:|:------| -| MsgSuccessCount| long| 消息包成功数| -| MsgFailCount| long| 消息包失败数| - -返回结果: - -``` counter -{ - "Message":"", - "Code":200, - "Data":{ - "MsgSuccessCount":1000, - "MsgFailCount":0 - } -} -``` diff --git a/api/README_Pipeline.md b/api/README_Pipeline.md deleted file mode 100644 index 2414df6..0000000 --- a/api/README_Pipeline.md +++ /dev/null @@ -1,541 +0,0 @@ -# 基于JT808Gateway WebApi 接口文档 - -基地址:127.0.0.1:828/jt808api/ - -> 注意url格式 - -数据格式:只支持Json格式 - -默认端口:828 - -## 1.统一下发设备消息服务 - -[统一下发设备消息服务](#send) - -## 2.管理会话服务 - -[基于Tcp管理会话服务](#tcp_session) - -[基于Udp管理会话服务](#udp_session) - -## 3.SIM黑名单管理服务 - -[SIM黑名单管理服务](#blacklist) - -## 接口请求对照表 - -### 公共接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| - -### 基于Tcp接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| -| 127.0.0.1:828/jt808api/Tcp/Session/SessionTcpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| -| 127.0.0.1:828/jt808api/Tcp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| -| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| - -### 基于Udp接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| -| 127.0.0.1:828/jt808api/Udp/Session/SessionUdpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| -| 127.0.0.1:828/jt808api/Udp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号查询对应会话| -| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| - -### SIM黑名单管理接口请求 - -|请求Url|请求方式|说明| -|:------|:------|:------| -| 127.0.0.1:828/jt808api/Blacklist/Add| POST| SIM卡黑名单服务-将对应SIM号加入黑名单| -| 127.0.0.1:828/jt808api/Blacklist/Remove| POST| SIM卡黑名单服务-将对应SIM号移除黑名单| -| 127.0.0.1:828/jt808api/Blacklist/GetAll| Get| SIM卡黑名单服务-获取所有sim的黑名单列表| - -### 统一对象返回 JT808ResultDto\ - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Message| string| 消息描述| -| Code| int| 状态码| -| Data| T(泛型)| 数据| - -返回Code[状态码]说明: - -|状态码|说明| -|:------:|:------:| -| 200 | 返回成功 | -| 201 | 内容为空 | -| 404 | 没有该服务 | -| 500 | 服务内部错误 | - -### 基于Tcp统一下发设备消息服务 - -请求地址:/UnificationSend - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|------|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| -| HexData| string| JT808 Hex String JT808数据包字符串| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", - "HexData":"7E****7E" -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool| 是否成功| - -返回结果: - -``` result1 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -### 基于Tcp管理会话服务 - -#### 统一会话信息对象返回 JT808TcpSessionInfoDto - -|属性|数据类型|参数说明| -|------|------|------| -| LastActiveTime| DateTime| 最后上线时间| -| StartTime| DateTime| 上线时间| -| TerminalPhoneNo|string| 终端手机号| -| RemoteAddressIP| string| 远程ip地址| - -#### 1.获取会话集合 - -请求地址:Tcp/Session/GetAll - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | - -返回结果: - -``` session1 -{ - "Message":"", - "Code":200, - "Data":[ - { - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - },{ - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789013", - "RemoteAddressIP":"127.0.0.1:11808" - } - ] -} -``` - -#### 2.通过设备终端号查询对应会话 - -请求地址:Tcp/Session/QuerySessionByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| JT808TcpSessionInfoDto对象 | 统一会话信息对象返回 | - -返回结果: - -``` session2 -{ - "Message":"", - "Code":200, - "Data": { - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - } -} -``` - -#### 3.通过设备终端号移除对应会话 - -请求地址:Tcp/Session/RemoveByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -#### 4.获取会话分页集合 - -请求地址:Tcp/Session/SessionTcpByPage - -请求方式:GET - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| pageIndex| int| 当前页(默认0)| -| pageSize| int| 页容量(默认10)| - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | -| PageIndex| int | 当前页(默认0) | -| PageSize| int | 页容量(默认10) | -| Total| int | 总数 | - -返回结果: - -``` session1 -{ - "message":null, - "code":200, - "data":{ - "pageIndex":0, - "pageSize":10, - "total":2, - "data":[ - { - "lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", - "startTime":"2022-09-03T19:34:07.8733615+08:00", - "terminalPhoneNo":"123456789012", - "remoteAddressIP":"127.0.0.1:9826" - }, - { - "lastActiveTime":"2022-09-03T19:34:05.135997+08:00", - "startTime":"2022-09-03T19:34:05.136035+08:00", - "terminalPhoneNo":"123456789013", - "remoteAddressIP":"127.0.0.1:9825" - } - ] - } -} -``` - -### 基于Udp管理会话服务 - -#### 统一会话信息对象返回 JT808UdpSessionInfoDto - -|属性|数据类型|参数说明| -|------|------|------| -| LastActiveTime| DateTime| 最后上线时间| -| StartTime| DateTime| 上线时间| -| TerminalPhoneNo|string| 终端手机号| -| RemoteAddressIP| string| 远程ip地址| - -#### 1.获取会话集合 - -请求地址:Udp/Session/GetAll - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | - -返回结果: - -``` session1 -{ - "Message":"", - "Code":200, - "Data":[ - { - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - },{ - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789013", - "RemoteAddressIP":"127.0.0.1:11808" - } - ] -} -``` - -#### 2.通过设备终端号查询对应会话 - -请求地址:Udp/Session/QuerySessionByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| JT808UdpSessionInfoDto对象 | 统一会话信息对象返回 | - -返回结果: - -``` session2 -{ - "Message":"", - "Code":200, - "Data":{ - "LastActiveTime":"2018-11-27 20:00:00", - "StartTime":"2018-11-25 20:00:00", - "TerminalPhoneNo":"123456789012", - "RemoteAddressIP":"127.0.0.1:11808" - } -} -``` - -#### 3.通过设备终端号移除对应会话 - -请求地址:Udp/Session/RemoveByTerminalPhoneNo - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -#### 4.获取会话分页集合 - -请求地址:Udp/Session/SessionUdpByPage - -请求方式:GET - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| pageIndex| int| 当前页(默认0)| -| pageSize| int| 页容量(默认10)| - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| List\ | 实际会话信息集合 | -| PageIndex| int | 当前页(默认0) | -| PageSize| int | 页容量(默认10) | -| Total| int | 总数 | - -返回结果: - -``` session1 -{ - "message":null, - "code":200, - "data":{ - "pageIndex":0, - "pageSize":10, - "total":2, - "data":[ - { - "lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", - "startTime":"2022-09-03T19:34:07.8733615+08:00", - "terminalPhoneNo":"123456789012", - "remoteAddressIP":"127.0.0.1:9826" - }, - { - "lastActiveTime":"2022-09-03T19:34:05.135997+08:00", - "startTime":"2022-09-03T19:34:05.136035+08:00", - "terminalPhoneNo":"123456789013", - "remoteAddressIP":"127.0.0.1:9825" - } - ] - } -} -``` - -### SIM黑名单管理服务 - -#### 1.添加sim卡黑名单 - -请求地址:Blacklist/Add - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -#### 2.移除sim卡黑名单 - -请求地址:Blacklist/Remove - -请求方式:POST - -请求参数: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| TerminalPhoneNo| string| 设备终端号| - -``` 1 -{ - "TerminalPhoneNo":"123456789012", -} -``` - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| Data| bool | 是否成功 - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":true -} -``` - -#### 3.获取sim卡黑名单 - -请求地址:Blacklist/GetAll - -请求方式:GET - -返回数据: - -|属性|数据类型|参数说明| -|:------:|:------:|:------| -| terminalPhoneNo| List\| 设备终端号集合| - -返回结果: - -``` session3 -{ - "Message":"", - "Code":200, - "Data":[ - "12345678901", - "12345678902" - ] -} -``` diff --git a/doc/README.md b/doc/README.md index 06cde12..1c6d1ff 100644 --- a/doc/README.md +++ b/doc/README.md @@ -374,19 +374,3 @@ net.ipv6.conf.default.disable_ipv6 = 1 reboot ``` -## 基于DotNetty - -[感谢泥水佬提供的压力测试工具](https://www.cnblogs.com/smark/p/4496660.html?utm_source=tuicool) - -| 操作系统 | 配置 | 使用 | -|:-------:|:-------:|:-------:| -| win server 2016 | 4c8g | 压力测试客户端 | -| centos7 | 4c8g | JT808服务端 | - -![performance_1000](https://github.com/SmallChi/JT808Gateway/blob/master/doc/dotnetty/performance_1000.png) - -![performance_2000](https://github.com/SmallChi/JT808Gateway/blob/master/doc/dotnetty/performance_2000.png) - -![performance_5000](https://github.com/SmallChi/JT808Gateway/blob/master/doc/dotnetty/performance_5000.png) - -![performance_10000](https://github.com/SmallChi/JT808Gateway/blob/master/doc/dotnetty/performance_10000.png) diff --git a/doc/dotnetty/performance_1000.png b/doc/dotnetty/performance_1000.png deleted file mode 100644 index fb47436bc1a5e4db32904ef17d4f3d1d037afddc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132644 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 z 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 z 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 diff --git a/doc/dotnetty/performance_5000.png b/doc/dotnetty/performance_5000.png deleted file mode 100644 index cf97f7ee89055456cf7f2a82d3753f3cb1ce4133..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156925 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

- /// 包计数器服务 - /// - public class JT808AtomicCounterDto - { - public long MsgSuccessCount { get; set; } - - public long MsgFailCount { get; set; } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs deleted file mode 100644 index 7faf2ee..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808DefaultResultDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions.Dtos -{ - public class JT808DefaultResultDto: JT808ResultDto - { - public JT808DefaultResultDto() - { - Data = "Hello,JT808 WebAPI"; - Code = JT808ResultCode.Ok; - } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs deleted file mode 100644 index 3f69192..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808IPAddressDto.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Runtime.Serialization; -using System.Text; - -namespace JT808.DotNetty.Abstractions.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 { } - } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs deleted file mode 100644 index 6376adb..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808ResultDto.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions.Dtos -{ - public class JT808ResultDto - { - public JT808ResultDto() - { - Code = JT808ResultCode.Ok; - } - - public string Message { get; set; } - - public int Code { get; set; } - - public T Data { get; set; } - } - - public class JT808ResultCode - { - public const int Ok = 200; - public const int Empty = 201; - public const int AuthFail = 401; - public const int NotFound = 404; - public const int Fail = 400; - public const int Error = 500; - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs deleted file mode 100644 index 4a71a69..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808TcpSessionInfoDto.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace JT808.DotNetty.Abstractions.Dtos -{ - public class JT808TcpSessionInfoDto - { - /// - /// 最后上线时间 - /// - public DateTime LastActiveTime { get; set; } - /// - /// 上线时间 - /// - public DateTime StartTime { get; set; } - /// - /// 终端手机号 - /// - public string TerminalPhoneNo { get; set; } - /// - /// 远程ip地址 - /// - public string RemoteAddressIP { get; set; } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808UdpSessionInfoDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808UdpSessionInfoDto.cs deleted file mode 100644 index a7d3f25..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808UdpSessionInfoDto.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace JT808.DotNetty.Abstractions.Dtos -{ - public class JT808UdpSessionInfoDto - { - /// - /// 最后上线时间 - /// - public DateTime LastActiveTime { get; set; } - /// - /// 上线时间 - /// - public DateTime StartTime { get; set; } - /// - /// 终端手机号 - /// - public string TerminalPhoneNo { get; set; } - /// - /// 远程ip地址 - /// - public string RemoteAddressIP { get; set; } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs deleted file mode 100644 index 8f32473..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808UnificationSendRequestDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace JT808.DotNetty.Abstractions.Dtos -{ - /// - /// 统一下发请求参数 - /// - public class JT808UnificationSendRequestDto - { - public string TerminalPhoneNo { get; set; } - public byte[] Data { get; set; } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Enums/JT808TransportProtocolType.cs b/src/JT808.DotNetty.Abstractions/Enums/JT808TransportProtocolType.cs deleted file mode 100644 index 0134bb8..0000000 --- a/src/JT808.DotNetty.Abstractions/Enums/JT808TransportProtocolType.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions.Enums -{ - /// - /// 传输协议类型 - /// - public enum JT808TransportProtocolType - { - tcp=1, - udp = 2 - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808ClientBuilder.cs b/src/JT808.DotNetty.Abstractions/IJT808ClientBuilder.cs deleted file mode 100644 index 124791f..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808ClientBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.Protocol; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808ClientBuilder - { - IJT808Builder JT808Builder { get; } - IJT808Builder Builder(); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808MsgConsumer.cs b/src/JT808.DotNetty.Abstractions/IJT808MsgConsumer.cs deleted file mode 100644 index 4cc774d..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808MsgConsumer.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808MsgConsumer : IJT808PubSub, IDisposable - { - void OnMessage(Action<(string TerminalNo, byte[] Data)> callback); - CancellationTokenSource Cts { get; } - void Subscribe(); - void Unsubscribe(); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808MsgProducer.cs b/src/JT808.DotNetty.Abstractions/IJT808MsgProducer.cs deleted file mode 100644 index 8c5698f..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808MsgProducer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808MsgProducer : IJT808PubSub, IDisposable - { - /// - /// - /// - /// 设备终端号 - /// 808 hex data - Task ProduceAsync(string terminalNo, byte[] data); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808MsgReplyConsumer.cs b/src/JT808.DotNetty.Abstractions/IJT808MsgReplyConsumer.cs deleted file mode 100644 index 4464fe3..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808MsgReplyConsumer.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808MsgReplyConsumer : IJT808PubSub, IDisposable - { - void OnMessage(Action<(string TerminalNo, byte[] Data)> callback); - CancellationTokenSource Cts { get; } - void Subscribe(); - void Unsubscribe(); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808MsgReplyProducer.cs b/src/JT808.DotNetty.Abstractions/IJT808MsgReplyProducer.cs deleted file mode 100644 index d3d7eec..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808MsgReplyProducer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808MsgReplyProducer : IJT808PubSub, IDisposable - { - /// - /// - /// - /// 设备终端号 - /// 808 hex data - Task ProduceAsync(string terminalNo, byte[] data); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808NettyBuilder.cs b/src/JT808.DotNetty.Abstractions/IJT808NettyBuilder.cs deleted file mode 100644 index 40e6723..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808NettyBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.Protocol; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808NettyBuilder - { - IJT808Builder JT808Builder { get; } - IJT808Builder Builder(); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808PubSub.cs b/src/JT808.DotNetty.Abstractions/IJT808PubSub.cs deleted file mode 100644 index 69ff828..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808PubSub.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Abstractions -{ - public interface IJT808PubSub - { - string TopicName { get; } - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808SessionConsumer.cs b/src/JT808.DotNetty.Abstractions/IJT808SessionConsumer.cs deleted file mode 100644 index 3525c6c..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808SessionConsumer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Abstractions -{ - /// - /// 会话通知(在线/离线) - /// - public interface IJT808SessionConsumer : IJT808PubSub, IDisposable - { - void OnMessage(Action<(string Notice, string TerminalNo)> callback); - CancellationTokenSource Cts { get; } - void Subscribe(); - void Unsubscribe(); - } -} diff --git a/src/JT808.DotNetty.Abstractions/IJT808SessionProducer.cs b/src/JT808.DotNetty.Abstractions/IJT808SessionProducer.cs deleted file mode 100644 index 04c452b..0000000 --- a/src/JT808.DotNetty.Abstractions/IJT808SessionProducer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Abstractions -{ - /// - /// 会话通知(在线/离线) - /// - public interface IJT808SessionProducer : IJT808PubSub, IDisposable - { - Task ProduceAsync(string notice,string terminalNo); - } -} diff --git a/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj b/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj deleted file mode 100644 index a5af1f4..0000000 --- a/src/JT808.DotNetty.Abstractions/JT808.DotNetty.Abstractions.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Abstractions - JT808.DotNetty.Abstractions - 基于DotNetty实现的JT808DotNetty的抽象库 - 基于DotNetty实现的JT808DotNetty的抽象库 - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.Abstractions/JT808NettyConstants.cs b/src/JT808.DotNetty.Abstractions/JT808NettyConstants.cs deleted file mode 100644 index 500bb70..0000000 --- a/src/JT808.DotNetty.Abstractions/JT808NettyConstants.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace JT808.DotNetty.Abstractions -{ - public static class JT808NettyConstants - { - public const string SessionOnline= "JT808SessionOnline"; - - public const string SessionOffline = "JT808SessionOffline"; - public const string SessionTopic = "jt808session"; - public const string MsgTopic = "jt808msgdefault"; - public const string MsgReplyTopic = "jt808msgreplydefault"; - - public static class JT808WebApiRouteTable - { - public const string RouteTablePrefix = "/jt808api"; - - public const string SessionPrefix = "Session"; - - public const string TcpPrefix = "Tcp"; - - public const string UdpPrefix = "Udp"; - - /// - /// 基于Tcp的包计数器 - /// - public static string GetTcpAtomicCounter = $"{RouteTablePrefix}/{TcpPrefix}/GetAtomicCounter"; - /// - /// 基于Tcp的会话服务集合 - /// - public static string SessionTcpGetAll = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/GetAll"; - /// - /// 会话服务-通过设备终端号移除对应会话 - /// - public static string SessionRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/RemoveByTerminalPhoneNo"; - /// - /// 会话服务-通过设备终端号查询对应会话 - /// - public static string QueryTcpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/QueryTcpSessionByTerminalPhoneNo"; - /// - /// 统一下发信息 - /// - public static string UnificationSend = $"{RouteTablePrefix}/UnificationSend"; - /// - /// 获取Udp包计数器 - /// - public static string GetUdpAtomicCounter = $"{RouteTablePrefix}/{UdpPrefix}/GetAtomicCounter"; - /// - /// 基于Udp的会话服务集合 - /// - public static string SessionUdpGetAll = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/GetAll"; - } - } -} diff --git a/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.Abstractions/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.CleintBenchmark/Configs/ClientBenchmarkOptions.cs b/src/JT808.DotNetty.CleintBenchmark/Configs/ClientBenchmarkOptions.cs deleted file mode 100644 index d1842d1..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Configs/ClientBenchmarkOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.CleintBenchmark.Configs -{ - public class ClientBenchmarkOptions : IOptions - { - public string IP { get; set; } - public int Port { get; set; } - public int DeviceCount { get; set; } = 10; - /// - /// 5000ms毫秒 - /// - public int Interval { get; set; } = 5000; - /// - /// 需要多台机器同时访问,那么可以根据这个避开重复终端号 - /// 100000-200000-300000 - /// - public int DeviceTemplate { get; set; } = 0; - public ClientBenchmarkOptions Value =>this; - } -} diff --git a/src/JT808.DotNetty.CleintBenchmark/Configs/NLog.xsd b/src/JT808.DotNetty.CleintBenchmark/Configs/NLog.xsd deleted file mode 100644 index 2f57d09..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Configs/NLog.xsd +++ /dev/null @@ -1,3106 +0,0 @@ - - - - - - - - - - - - - - - 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.DotNetty.CleintBenchmark/Configs/nlog.unix.config b/src/JT808.DotNetty.CleintBenchmark/Configs/nlog.unix.config deleted file mode 100644 index 2c8b777..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Configs/nlog.unix.config +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.CleintBenchmark/Configs/nlog.win.config b/src/JT808.DotNetty.CleintBenchmark/Configs/nlog.win.config deleted file mode 100644 index 14d4a10..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Configs/nlog.win.config +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.CleintBenchmark/Controllers/ReportController.cs b/src/JT808.DotNetty.CleintBenchmark/Controllers/ReportController.cs deleted file mode 100644 index 0474c14..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Controllers/ReportController.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using JT808.DotNetty.Client; -using JT808.DotNetty.Client.Metadata; -using JT808.DotNetty.Client.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Primitives; - -namespace JT808.DotNetty.CleintBenchmark -{ - /// - /// 车辆控制器 - /// - [Route("JT808WebApi")] - [ApiController] - [EnableCors("Domain")] - public class ReportController : ControllerBase - { - private readonly IJT808TcpClientFactory clientFactory; - private readonly JT808ReceiveAtomicCounterService ReceiveAtomicCounterService; - private readonly JT808SendAtomicCounterService SendAtomicCounterService; - - /// - /// - /// - public ReportController( - IJT808TcpClientFactory factory, - JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService, - JT808SendAtomicCounterService jT808SendAtomicCounterService) - { - clientFactory = factory; - ReceiveAtomicCounterService = jT808ReceiveAtomicCounterService; - SendAtomicCounterService = jT808SendAtomicCounterService; - } - - [HttpPost] - [HttpGet] - [Route("QueryReport")] - public ActionResult QueryReport() - { - var clients = clientFactory.GetAll(); - JT808Report report = new JT808Report() - { - SendTotalCount = SendAtomicCounterService.MsgSuccessCount, - ReceiveTotalCount = ReceiveAtomicCounterService.MsgSuccessCount, - CurrentDate = DateTime.Now, - Connections = clients.Count, - OnlineConnections = clients.Where(w => w.IsOpen).Count(), - OfflineConnections = clients.Where(w => !w.IsOpen).Count(), - }; - return report; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.CleintBenchmark/JT808.DotNetty.CleintBenchmark.csproj b/src/JT808.DotNetty.CleintBenchmark/JT808.DotNetty.CleintBenchmark.csproj deleted file mode 100644 index b546474..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/JT808.DotNetty.CleintBenchmark.csproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - Exe - net5 - 9.0 - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - - - - Always - - - - - - Always - - - Always - - - Always - - - Always - Designer - - - - - - diff --git a/src/JT808.DotNetty.CleintBenchmark/Program.cs b/src/JT808.DotNetty.CleintBenchmark/Program.cs deleted file mode 100644 index 2c46412..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Program.cs +++ /dev/null @@ -1,77 +0,0 @@ -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 JT808.DotNetty.Client; -using JT808.DotNetty.CleintBenchmark.Configs; -using Microsoft.Extensions.Configuration; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Builder; -using JT808.DotNetty.CleintBenchmark.Services; - -namespace JT808.DotNetty.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); - }) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.Configure(app => - { - app.UseRouting(); - app.UseCors("Domain"); - app.UseStaticFiles(); - app.UseDefaultFiles("/index.html"); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - }) - .ConfigureServices((hostContext, services) => - { - services.AddControllers(); - services.AddCors(options => - options.AddPolicy("Domain", builder => - builder.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader() - .AllowAnyOrigin())); - - }); - }) - .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(hostContext.Configuration.GetSection("ClientBenchmarkOptions")); - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808Client(); - services.AddHostedService(); - }); - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.CleintBenchmark/Services/CleintBenchmarkHostedService.cs b/src/JT808.DotNetty.CleintBenchmark/Services/CleintBenchmarkHostedService.cs deleted file mode 100644 index 231041c..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/Services/CleintBenchmarkHostedService.cs +++ /dev/null @@ -1,90 +0,0 @@ -using JT808.DotNetty.CleintBenchmark.Configs; -using JT808.DotNetty.Client; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -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.DotNetty.CleintBenchmark.Services -{ - public class CleintBenchmarkHostedService : IHostedService - { - private readonly ClientBenchmarkOptions clientBenchmarkOptions; - - private readonly ILogger logger; - - private readonly IJT808TcpClientFactory jT808TcpClientFactory; - - public CleintBenchmarkHostedService( - ILoggerFactory loggerFactory, - IJT808TcpClientFactory jT808TcpClientFactory, - IOptions clientBenchmarkOptionsAccessor) - { - this.jT808TcpClientFactory = jT808TcpClientFactory; - clientBenchmarkOptions = clientBenchmarkOptionsAccessor.Value; - logger = loggerFactory.CreateLogger("CleintBenchmarkHostedService"); - } - 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}"); - //先建立连接 - for (int i=0;i< clientBenchmarkOptions.DeviceCount; i++) - { - var client = jT808TcpClientFactory.Create(new JT808DeviceConfig((i+1+ clientBenchmarkOptions.DeviceTemplate).ToString(), - clientBenchmarkOptions.IP, - clientBenchmarkOptions.Port)); - } - - ThreadPool.QueueUserWorkItem((state) => - { - while (!cancellationToken.IsCancellationRequested) - { - Parallel.ForEach(jT808TcpClientFactory.GetAll(), new ParallelOptions { MaxDegreeOfParallelism = 100 }, (item) => - { - try - { - int lat = new Random(1000).Next(100000, 180000); - int Lng = new Random(1000).Next(100000, 180000); - item.Send(JT808MsgId.位置信息汇报.Create(item.DeviceConfig.TerminalPhoneNo, new JT808_0x0200() - { - Lat = lat, - Lng = Lng, - GPSTime = DateTime.Now, - Speed = 50, - Direction = 30, - AlarmFlag = 5, - Altitude = 50, - StatusFlag = 10 - })); - } - catch (Exception ex) - { - logger.LogError(ex.Message); - } - }); - Thread.Sleep(clientBenchmarkOptions.Interval); - } - }); - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - jT808TcpClientFactory.Dispose(); - logger.LogInformation("StopAsync..."); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.CleintBenchmark/appsettings.json b/src/JT808.DotNetty.CleintBenchmark/appsettings.json deleted file mode 100644 index 7611940..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/appsettings.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Error" - } - }, - "Console": { - "LogLevel": { - "Default": "Error" - } - } - }, - "AllowedHosts": "*", - //"urls": "http://*:15004;", - "ClientBenchmarkOptions": { - "IP": "127.0.0.1", - "Port": 808, - "DeviceCount": 100, - "Interval": 1000, - "DeviceTemplate": 100000 //需要多台机器同时访问,那么可以根据这个避开重复终端号 100000-200000-300000 - } -} diff --git a/src/JT808.DotNetty.CleintBenchmark/wwwroot/echarts.min.js b/src/JT808.DotNetty.CleintBenchmark/wwwroot/echarts.min.js deleted file mode 100644 index 60cdcce..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/wwwroot/echarts.min.js +++ /dev/null @@ -1,13 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.echarts={})}(this,function(t){"use strict";function e(t){var e={},i={},n=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),a=t.match(/Edge\/([\d.]+)/),o=/micromessenger/i.test(t);return n&&(i.firefox=!0,i.version=n[1]),r&&(i.ie=!0,i.version=r[1]),a&&(i.edge=!0,i.version=a[1]),o&&(i.weChat=!0),{browser:i,os:e,node:!1,canvasSupported:!!document.createElement("canvas").getContext,svgSupported:"undefined"!=typeof SVGRect,touchEventsSupported:"ontouchstart"in window&&!i.ie&&!i.edge,pointerEventsSupported:"onpointerdown"in window&&(i.edge||i.ie&&i.version>=11),domSupported:"undefined"!=typeof document}}function i(t,e){"createCanvas"===t&&(Tp=null),Ip[t]=e}function n(t){if(null==t||"object"!=typeof t)return t;var e=t,i=yp.call(t);if("[object Array]"===i){if(!E(t)){e=[];for(var r=0,a=t.length;a>r;r++)e[r]=n(t[r])}}else if(mp[i]){if(!E(t)){var o=t.constructor;if(t.constructor.from)e=o.from(t);else{e=new o(t.length);for(var r=0,a=t.length;a>r;r++)e[r]=n(t[r])}}}else if(!vp[i]&&!E(t)&&!C(t)){e={};for(var s in t)t.hasOwnProperty(s)&&(e[s]=n(t[s]))}return e}function r(t,e,i){if(!S(e)||!S(t))return i?n(e):t;for(var a in e)if(e.hasOwnProperty(a)){var o=t[a],s=e[a];!S(s)||!S(o)||x(s)||x(o)||C(s)||C(o)||M(s)||M(o)||E(s)||E(o)?!i&&a in t||(t[a]=n(e[a],!0)):r(o,s,i)}return t}function a(t,e){for(var i=t[0],n=1,a=t.length;a>n;n++)i=r(i,t[n],e);return i}function o(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function s(t,e,i){for(var n in e)e.hasOwnProperty(n)&&(i?null!=e[n]:null==t[n])&&(t[n]=e[n]);return t}function l(){return Tp||(Tp=Cp().getContext("2d")),Tp}function u(t,e){if(t){if(t.indexOf)return t.indexOf(e);for(var i=0,n=t.length;n>i;i++)if(t[i]===e)return i}return-1}function h(t,e){function i(){}var n=t.prototype;i.prototype=e.prototype,t.prototype=new i;for(var r in n)n.hasOwnProperty(r)&&(t.prototype[r]=n[r]);t.prototype.constructor=t,t.superClass=e}function c(t,e,i){t="prototype"in t?t.prototype:t,e="prototype"in e?e.prototype:e,s(t,e,i)}function d(t){return t?"string"==typeof t?!1:"number"==typeof t.length:void 0}function f(t,e,i){if(t&&e)if(t.forEach&&t.forEach===xp)t.forEach(e,i);else if(t.length===+t.length)for(var n=0,r=t.length;r>n;n++)e.call(i,t[n],n,t);else for(var a in t)t.hasOwnProperty(a)&&e.call(i,t[a],a,t)}function p(t,e,i){if(t&&e){if(t.map&&t.map===Sp)return t.map(e,i);for(var n=[],r=0,a=t.length;a>r;r++)n.push(e.call(i,t[r],r,t));return n}}function g(t,e,i,n){if(t&&e){if(t.reduce&&t.reduce===Mp)return t.reduce(e,i,n);for(var r=0,a=t.length;a>r;r++)i=e.call(n,i,t[r],r,t);return i}}function v(t,e,i){if(t&&e){if(t.filter&&t.filter===wp)return t.filter(e,i);for(var n=[],r=0,a=t.length;a>r;r++)e.call(i,t[r],r,t)&&n.push(t[r]);return n}}function m(t,e,i){if(t&&e)for(var n=0,r=t.length;r>n;n++)if(e.call(i,t[n],n,t))return t[n]}function y(t,e){var i=bp.call(arguments,2);return function(){return t.apply(e,i.concat(bp.call(arguments)))}}function _(t){var e=bp.call(arguments,1);return function(){return t.apply(this,e.concat(bp.call(arguments)))}}function x(t){return"[object Array]"===yp.call(t)}function w(t){return"function"==typeof t}function b(t){return"[object String]"===yp.call(t)}function S(t){var e=typeof t;return"function"===e||!!t&&"object"===e}function M(t){return!!vp[yp.call(t)]}function I(t){return!!mp[yp.call(t)]}function C(t){return"object"==typeof t&&"number"==typeof t.nodeType&&"object"==typeof t.ownerDocument}function T(t){return t!==t}function D(){for(var t=0,e=arguments.length;e>t;t++)if(null!=arguments[t])return arguments[t]}function A(t,e){return null!=t?t:e}function k(t,e,i){return null!=t?t:null!=e?e:i}function P(){return Function.call.apply(bp,arguments)}function L(t){if("number"==typeof t)return[t,t,t,t];var e=t.length;return 2===e?[t[0],t[1],t[0],t[1]]:3===e?[t[0],t[1],t[2],t[1]]:t}function O(t,e){if(!t)throw new Error(e)}function z(t){return null==t?null:"function"==typeof t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}function B(t){t[Dp]=!0}function E(t){return t[Dp]}function R(t){function e(t,e){i?n.set(t,e):n.set(e,t)}var i=x(t);this.data={};var n=this;t instanceof R?t.each(e):t&&f(t,e)}function N(t){return new R(t)}function F(t,e){for(var i=new t.constructor(t.length+e.length),n=0;nd;d++){var p=1<o;o++)for(var s=0;8>s;s++)null==a[s]&&(a[s]=0),a[s]+=((o+s)%2?-1:1)*de(i,7,0===o?1:0,1<a;a++){var o=document.createElement("div"),s=o.style,l=a%2,u=(a>>1)%2;s.cssText=["position:absolute","visibility: hidden","padding: 0","margin: 0","border-width: 0","width:0","height:0",n[l]+":0",r[u]+":0",n[1-l]+":auto",r[1-u]+":auto",""].join("!important;"),t.appendChild(o),i.push(o)}return i}function me(t,e){for(var i=e.transformer,n=e.srcCoords,r=!0,a=[],o=[],s=0;4>s;s++){var l=t[s].getBoundingClientRect(),u=2*s,h=l.left,c=l.top;a.push(h,c),r&=n&&h===n[u]&&c===n[u+1],o.push(t[s].offsetLeft,t[s].offsetTop)}return r?i:(e.srcCoords=a,e.transformer=fe(a,o))}function ye(t,e,i){if(e=e||window.event,null!=e.zrX)return e;var n=e.type,r=n&&n.indexOf("touch")>=0;if(r){var a="touchend"!==n?e.targetTouches[0]:e.changedTouches[0];a&&pe(t,a,e,i)}else pe(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;var o=e.button;return null==e.which&&void 0!==o&&Gp.test(e.type)&&(e.which=1&o?1:2&o?3:4&o?2:0),e}function _e(t,e,i){Fp?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function xe(t,e,i){Fp?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}function we(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function be(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function Se(t,e,i){return{type:t,event:i,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:i.zrX,offsetY:i.zrY,gestureEvent:i.gestureEvent,pinchX:i.pinchX,pinchY:i.pinchY,pinchScale:i.pinchScale,wheelDelta:i.zrDelta,zrByTouch:i.zrByTouch,which:i.which,stop:Me}}function Me(){Wp(this.event)}function Ie(){}function Ce(t,e,i){if(t[t.rectHover?"rectContain":"contain"](e,i)){for(var n,r=t;r;){if(r.clipPath&&!r.clipPath.contain(e,i))return!1;r.silent&&(n=!0),r=r.parent}return n?Yp:!0}return!1}function Te(){var t=new Zp(6);return De(t),t}function De(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function Ae(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function ke(t,e,i){var n=e[0]*i[0]+e[2]*i[1],r=e[1]*i[0]+e[3]*i[1],a=e[0]*i[2]+e[2]*i[3],o=e[1]*i[2]+e[3]*i[3],s=e[0]*i[4]+e[2]*i[5]+e[4],l=e[1]*i[4]+e[3]*i[5]+e[5];return t[0]=n,t[1]=r,t[2]=a,t[3]=o,t[4]=s,t[5]=l,t}function Pe(t,e,i){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+i[0],t[5]=e[5]+i[1],t}function Le(t,e,i){var n=e[0],r=e[2],a=e[4],o=e[1],s=e[3],l=e[5],u=Math.sin(i),h=Math.cos(i);return t[0]=n*h+o*u,t[1]=-n*u+o*h,t[2]=r*h+s*u,t[3]=-r*u+h*s,t[4]=h*a+u*l,t[5]=h*l-u*a,t}function Oe(t,e,i){var n=i[0],r=i[1];return t[0]=e[0]*n,t[1]=e[1]*r,t[2]=e[2]*n,t[3]=e[3]*r,t[4]=e[4]*n,t[5]=e[5]*r,t}function ze(t,e){var i=e[0],n=e[2],r=e[4],a=e[1],o=e[3],s=e[5],l=i*o-a*n;return l?(l=1/l,t[0]=o*l,t[1]=-a*l,t[2]=-n*l,t[3]=i*l,t[4]=(n*s-o*r)*l,t[5]=(a*r-i*s)*l,t):null}function Be(t){var e=Te();return Ae(e,t),e}function Ee(t){return t>Qp||-Qp>t}function Re(t){this._target=t.target,this._life=t.life||1e3,this._delay=t.delay||0,this._initialized=!1,this.loop=null==t.loop?!1:t.loop,this.gap=t.gap||0,this.easing=t.easing||"Linear",this.onframe=t.onframe,this.ondestroy=t.ondestroy,this.onrestart=t.onrestart,this._pausedTime=0,this._paused=!1}function Ne(t){return t=Math.round(t),0>t?0:t>255?255:t}function Fe(t){return t=Math.round(t),0>t?0:t>360?360:t}function Ge(t){return 0>t?0:t>1?1:t}function Ve(t){return Ne(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function He(t){return Ge(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function We(t,e,i){return 0>i?i+=1:i>1&&(i-=1),1>6*i?t+(e-t)*i*6:1>2*i?e:2>3*i?t+(e-t)*(2/3-i)*6:t}function Ue(t,e,i){return t+(e-t)*i}function Xe(t,e,i,n,r){return t[0]=e,t[1]=i,t[2]=n,t[3]=r,t}function Ye(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function je(t,e){dg&&Ye(dg,e),dg=cg.put(t,dg||e.slice())}function qe(t,e){if(t){e=e||[];var i=cg.get(t);if(i)return Ye(e,i);t+="";var n=t.replace(/ /g,"").toLowerCase();if(n in hg)return Ye(e,hg[n]),je(t,e),e;if("#"!==n.charAt(0)){var r=n.indexOf("("),a=n.indexOf(")");if(-1!==r&&a+1===n.length){var o=n.substr(0,r),s=n.substr(r+1,a-(r+1)).split(","),l=1;switch(o){case"rgba":if(4!==s.length)return void Xe(e,0,0,0,1);l=He(s.pop());case"rgb":return 3!==s.length?void Xe(e,0,0,0,1):(Xe(e,Ve(s[0]),Ve(s[1]),Ve(s[2]),l),je(t,e),e);case"hsla":return 4!==s.length?void Xe(e,0,0,0,1):(s[3]=He(s[3]),Ze(s,e),je(t,e),e);case"hsl":return 3!==s.length?void Xe(e,0,0,0,1):(Ze(s,e),je(t,e),e);default:return}}Xe(e,0,0,0,1)}else{if(4===n.length){var u=parseInt(n.substr(1),16);return u>=0&&4095>=u?(Xe(e,(3840&u)>>4|(3840&u)>>8,240&u|(240&u)>>4,15&u|(15&u)<<4,1),je(t,e),e):void Xe(e,0,0,0,1)}if(7===n.length){var u=parseInt(n.substr(1),16);return u>=0&&16777215>=u?(Xe(e,(16711680&u)>>16,(65280&u)>>8,255&u,1),je(t,e),e):void Xe(e,0,0,0,1)}}}}function Ze(t,e){var i=(parseFloat(t[0])%360+360)%360/360,n=He(t[1]),r=He(t[2]),a=.5>=r?r*(n+1):r+n-r*n,o=2*r-a;return e=e||[],Xe(e,Ne(255*We(o,a,i+1/3)),Ne(255*We(o,a,i)),Ne(255*We(o,a,i-1/3)),1),4===t.length&&(e[3]=t[3]),e}function Ke(t){if(t){var e,i,n=t[0]/255,r=t[1]/255,a=t[2]/255,o=Math.min(n,r,a),s=Math.max(n,r,a),l=s-o,u=(s+o)/2;if(0===l)e=0,i=0;else{i=.5>u?l/(s+o):l/(2-s-o);var h=((s-n)/6+l/2)/l,c=((s-r)/6+l/2)/l,d=((s-a)/6+l/2)/l;n===s?e=d-c:r===s?e=1/3+h-d:a===s&&(e=2/3+c-h),0>e&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,u];return null!=t[3]&&f.push(t[3]),f}}function $e(t,e){var i=qe(t);if(i){for(var n=0;3>n;n++)i[n]=0>e?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0,i[n]>255?i[n]=255:t[n]<0&&(i[n]=0);return ni(i,4===i.length?"rgba":"rgb")}}function Qe(t){var e=qe(t);return e?((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1):void 0}function Je(t,e,i){if(e&&e.length&&t>=0&&1>=t){i=i||[];var n=t*(e.length-1),r=Math.floor(n),a=Math.ceil(n),o=e[r],s=e[a],l=n-r;return i[0]=Ne(Ue(o[0],s[0],l)),i[1]=Ne(Ue(o[1],s[1],l)),i[2]=Ne(Ue(o[2],s[2],l)),i[3]=Ge(Ue(o[3],s[3],l)),i}}function ti(t,e,i){if(e&&e.length&&t>=0&&1>=t){var n=t*(e.length-1),r=Math.floor(n),a=Math.ceil(n),o=qe(e[r]),s=qe(e[a]),l=n-r,u=ni([Ne(Ue(o[0],s[0],l)),Ne(Ue(o[1],s[1],l)),Ne(Ue(o[2],s[2],l)),Ge(Ue(o[3],s[3],l))],"rgba");return i?{color:u,leftIndex:r,rightIndex:a,value:n}:u}}function ei(t,e,i,n){return t=qe(t),t?(t=Ke(t),null!=e&&(t[0]=Fe(e)),null!=i&&(t[1]=He(i)),null!=n&&(t[2]=He(n)),ni(Ze(t),"rgba")):void 0}function ii(t,e){return t=qe(t),t&&null!=e?(t[3]=Ge(e),ni(t,"rgba")):void 0}function ni(t,e){if(t&&t.length){var i=t[0]+","+t[1]+","+t[2];return("rgba"===e||"hsva"===e||"hsla"===e)&&(i+=","+t[3]),e+"("+i+")"}}function ri(t,e){return t[e]}function ai(t,e,i){t[e]=i}function oi(t,e,i){return(e-t)*i+t}function si(t,e,i){return i>.5?e:t}function li(t,e,i,n,r){var a=t.length;if(1===r)for(var o=0;a>o;o++)n[o]=oi(t[o],e[o],i);else for(var s=a&&t[0].length,o=0;a>o;o++)for(var l=0;s>l;l++)n[o][l]=oi(t[o][l],e[o][l],i)}function ui(t,e,i){var n=t.length,r=e.length;if(n!==r){var a=n>r;if(a)t.length=r;else for(var o=n;r>o;o++)t.push(1===i?e[o]:vg.call(e[o]))}for(var s=t[0]&&t[0].length,o=0;ol;l++)isNaN(t[o][l])&&(t[o][l]=e[o][l])}function hi(t,e,i){if(t===e)return!0;var n=t.length;if(n!==e.length)return!1;if(1===i){for(var r=0;n>r;r++)if(t[r]!==e[r])return!1}else for(var a=t[0].length,r=0;n>r;r++)for(var o=0;a>o;o++)if(t[r][o]!==e[r][o])return!1;return!0}function ci(t,e,i,n,r,a,o,s,l){var u=t.length;if(1===l)for(var h=0;u>h;h++)s[h]=di(t[h],e[h],i[h],n[h],r,a,o);else for(var c=t[0].length,h=0;u>h;h++)for(var d=0;c>d;d++)s[h][d]=di(t[h][d],e[h][d],i[h][d],n[h][d],r,a,o)}function di(t,e,i,n,r,a,o){var s=.5*(i-t),l=.5*(n-e);return(2*(e-i)+s+l)*o+(-3*(e-i)-2*s-l)*a+s*r+e}function fi(t){if(d(t)){var e=t.length;if(d(t[0])){for(var i=[],n=0;e>n;n++)i.push(vg.call(t[n]));return i}return vg.call(t)}return t}function pi(t){return t[0]=Math.floor(t[0]),t[1]=Math.floor(t[1]),t[2]=Math.floor(t[2]),"rgba("+t.join(",")+")"}function gi(t){var e=t[t.length-1].value;return d(e&&e[0])?2:1}function vi(t,e,i,n,r,a){var o=t._getter,s=t._setter,l="spline"===e,u=n.length;if(u){var h,c=n[0].value,f=d(c),p=!1,g=!1,v=f?gi(n):0;n.sort(function(t,e){return t.time-e.time}),h=n[u-1].time;for(var m=[],y=[],_=n[0].value,x=!0,w=0;u>w;w++){m.push(n[w].time/h);var b=n[w].value;if(f&&hi(b,_,v)||!f&&b===_||(x=!1),_=b,"string"==typeof b){var S=qe(b);S?(b=S,p=!0):g=!0}y.push(b)}if(a||!x){for(var M=y[u-1],w=0;u-1>w;w++)f?ui(y[w],M,v):!isNaN(y[w])||isNaN(M)||g||p||(y[w]=M);f&&ui(o(t._target,r),M,v);var I,C,T,D,A,k,P=0,L=0;if(p)var O=[0,0,0,0];var z=function(t,e){var i;if(0>e)i=0;else if(L>e){for(I=Math.min(P+1,u-1),i=I;i>=0&&!(m[i]<=e);i--);i=Math.min(i,u-2)}else{for(i=P;u>i&&!(m[i]>e);i++);i=Math.min(i-1,u-2)}P=i,L=e;var n=m[i+1]-m[i];if(0!==n)if(C=(e-m[i])/n,l)if(D=y[i],T=y[0===i?i:i-1],A=y[i>u-2?u-1:i+1],k=y[i>u-3?u-1:i+2],f)ci(T,D,A,k,C,C*C,C*C*C,o(t,r),v);else{var a;if(p)a=ci(T,D,A,k,C,C*C,C*C*C,O,1),a=pi(O);else{if(g)return si(D,A,C);a=di(T,D,A,k,C,C*C,C*C*C)}s(t,r,a)}else if(f)li(y[i],y[i+1],C,o(t,r),v);else{var a;if(p)li(y[i],y[i+1],C,O,1),a=pi(O);else{if(g)return si(y[i],y[i+1],C);a=oi(y[i],y[i+1],C)}s(t,r,a)}},B=new Re({target:t._target,life:h,loop:t._loop,delay:t._delay,onframe:z,ondestroy:i});return e&&"spline"!==e&&(B.easing=e),B}}}function mi(t,e,i,n,r,a,o,s){function l(){h--,h||a&&a()}b(n)?(a=r,r=n,n=0):w(r)?(a=r,r="linear",n=0):w(n)?(a=n,n=0):w(i)?(a=i,i=500):i||(i=500),t.stopAnimation(),yi(t,"",t,e,i,n,s);var u=t.animators.slice(),h=u.length;h||a&&a();for(var c=0;c0&&t.animate(e,!1).when(null==r?500:r,s).delay(a||0)}function _i(t,e,i,n){if(e){var r={};r[e]={},r[e][i]=n,t.attr(r)}else t.attr(i,n)}function xi(t,e,i,n){0>i&&(t+=i,i=-i),0>n&&(e+=n,n=-n),this.x=t,this.y=e,this.width=i,this.height=n}function wi(t){for(var e=0;t>=Ag;)e|=1&t,t>>=1;return t+e}function bi(t,e,i,n){var r=e+1;if(r===i)return 1;if(n(t[r++],t[e])<0){for(;i>r&&n(t[r],t[r-1])<0;)r++;Si(t,e,r)}else for(;i>r&&n(t[r],t[r-1])>=0;)r++;return r-e}function Si(t,e,i){for(i--;i>e;){var n=t[e];t[e++]=t[i],t[i--]=n}}function Mi(t,e,i,n,r){for(n===e&&n++;i>n;n++){for(var a,o=t[n],s=e,l=n;l>s;)a=s+l>>>1,r(o,t[a])<0?l=a:s=a+1;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=o}}function Ii(t,e,i,n,r,a){var o=0,s=0,l=1;if(a(t,e[i+r])>0){for(s=n-r;s>l&&a(t,e[i+r+l])>0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s),o+=r,l+=r}else{for(s=r+1;s>l&&a(t,e[i+r-l])<=0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s);var u=o;o=r-l,l=r-u}for(o++;l>o;){var h=o+(l-o>>>1);a(t,e[i+h])>0?o=h+1:l=h}return l}function Ci(t,e,i,n,r,a){var o=0,s=0,l=1;if(a(t,e[i+r])<0){for(s=r+1;s>l&&a(t,e[i+r-l])<0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s);var u=o;o=r-l,l=r-u}else{for(s=n-r;s>l&&a(t,e[i+r+l])>=0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s),o+=r,l+=r}for(o++;l>o;){var h=o+(l-o>>>1);a(t,e[i+h])<0?l=h:o=h+1}return l}function Ti(t,e){function i(t,e){l[c]=t,u[c]=e,c+=1}function n(){for(;c>1;){var t=c-2;if(t>=1&&u[t-1]<=u[t]+u[t+1]||t>=2&&u[t-2]<=u[t]+u[t-1])u[t-1]u[t+1])break;a(t)}}function r(){for(;c>1;){var t=c-2;t>0&&u[t-1]=r?o(n,r,a,h):s(n,r,a,h)))}function o(i,n,r,a){var o=0;for(o=0;n>o;o++)d[o]=t[i+o];var s=0,l=r,u=i;if(t[u++]=t[l++],0!==--a){if(1===n){for(o=0;a>o;o++)t[u+o]=t[l+o];return void(t[u+a]=d[s])}for(var c,f,p,g=h;;){c=0,f=0,p=!1;do if(e(t[l],d[s])<0){if(t[u++]=t[l++],f++,c=0,0===--a){p=!0;break}}else if(t[u++]=d[s++],c++,f=0,1===--n){p=!0;break}while(g>(c|f));if(p)break;do{if(c=Ci(t[l],d,s,n,0,e),0!==c){for(o=0;c>o;o++)t[u+o]=d[s+o];if(u+=c,s+=c,n-=c,1>=n){p=!0;break}}if(t[u++]=t[l++],0===--a){p=!0;break}if(f=Ii(d[s],t,l,a,0,e),0!==f){for(o=0;f>o;o++)t[u+o]=t[l+o];if(u+=f,l+=f,a-=f,0===a){p=!0;break}}if(t[u++]=d[s++],1===--n){p=!0;break}g--}while(c>=kg||f>=kg);if(p)break;0>g&&(g=0),g+=2}if(h=g,1>h&&(h=1),1===n){for(o=0;a>o;o++)t[u+o]=t[l+o];t[u+a]=d[s]}else{if(0===n)throw new Error;for(o=0;n>o;o++)t[u+o]=d[s+o]}}else for(o=0;n>o;o++)t[u+o]=d[s+o]}function s(i,n,r,a){var o=0;for(o=0;a>o;o++)d[o]=t[r+o];var s=i+n-1,l=a-1,u=r+a-1,c=0,f=0;if(t[u--]=t[s--],0!==--n){if(1===a){for(u-=n,s-=n,f=u+1,c=s+1,o=n-1;o>=0;o--)t[f+o]=t[c+o];return void(t[u]=d[l])}for(var p=h;;){var g=0,v=0,m=!1;do if(e(d[l],t[s])<0){if(t[u--]=t[s--],g++,v=0,0===--n){m=!0;break}}else if(t[u--]=d[l--],v++,g=0,1===--a){m=!0;break}while(p>(g|v));if(m)break;do{if(g=n-Ci(d[l],t,i,n,n-1,e),0!==g){for(u-=g,s-=g,n-=g,f=u+1,c=s+1,o=g-1;o>=0;o--)t[f+o]=t[c+o];if(0===n){m=!0;break}}if(t[u--]=d[l--],1===--a){m=!0;break}if(v=a-Ii(t[s],d,0,a,a-1,e),0!==v){for(u-=v,l-=v,a-=v,f=u+1,c=l+1,o=0;v>o;o++)t[f+o]=d[c+o];if(1>=a){m=!0;break}}if(t[u--]=t[s--],0===--n){m=!0;break}p--}while(g>=kg||v>=kg);if(m)break;0>p&&(p=0),p+=2}if(h=p,1>h&&(h=1),1===a){for(u-=n,s-=n,f=u+1,c=s+1,o=n-1;o>=0;o--)t[f+o]=t[c+o];t[u]=d[l]}else{if(0===a)throw new Error;for(c=u-(a-1),o=0;a>o;o++)t[c+o]=d[o]}}else for(c=u-(a-1),o=0;a>o;o++)t[c+o]=d[o]}var l,u,h=kg,c=0,d=[];l=[],u=[],this.mergeRuns=n,this.forceMergeRuns=r,this.pushRun=i}function Di(t,e,i,n){i||(i=0),n||(n=t.length);var r=n-i;if(!(2>r)){var a=0;if(Ag>r)return a=bi(t,i,n,e),void Mi(t,i,n,i+a,e);var o=new Ti(t,e),s=wi(r);do{if(a=bi(t,i,n,e),s>a){var l=r;l>s&&(l=s),Mi(t,i,i+l,i+a,e),a=l}o.pushRun(i,a),o.mergeRuns(),r-=a,i+=a}while(0!==r);o.forceMergeRuns()}}function Ai(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}function ki(t,e,i){var n=null==e.x?0:e.x,r=null==e.x2?1:e.x2,a=null==e.y?0:e.y,o=null==e.y2?0:e.y2;e.global||(n=n*i.width+i.x,r=r*i.width+i.x,a=a*i.height+i.y,o=o*i.height+i.y),n=isNaN(n)?0:n,r=isNaN(r)?1:r,a=isNaN(a)?0:a,o=isNaN(o)?0:o;var s=t.createLinearGradient(n,a,r,o);return s}function Pi(t,e,i){var n=i.width,r=i.height,a=Math.min(n,r),o=null==e.x?.5:e.x,s=null==e.y?.5:e.y,l=null==e.r?.5:e.r;e.global||(o=o*n+i.x,s=s*r+i.y,l*=a);var u=t.createRadialGradient(o,s,0,o,s,l);return u}function Li(){return!1}function Oi(t,e,i){var n=Cp(),r=e.getWidth(),a=e.getHeight(),o=n.style;return o&&(o.position="absolute",o.left=0,o.top=0,o.width=r+"px",o.height=a+"px",n.setAttribute("data-zr-dom-id",t)),n.width=r*i,n.height=a*i,n}function zi(t){if("string"==typeof t){var e=Ug.get(t);return e&&e.image}return t}function Bi(t,e,i,n,r){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!i)return e;var a=Ug.get(t),o={hostEl:i,cb:n,cbPayload:r};return a?(e=a.image,!Ri(e)&&a.pending.push(o)):(e=new Image,e.onload=e.onerror=Ei,Ug.put(t,e.__cachedImgObj={image:e,pending:[o]}),e.src=e.__zrImageSrc=t),e}return t}return e}function Ei(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;ea;a++)r=Math.max(Ki(n[a],e).width,r);return Yg>jg&&(Yg=0,Xg={}),Yg++,Xg[i]=r,r}function Fi(t,e,i,n,r,a,o,s){return o?Vi(t,e,i,n,r,a,o,s):Gi(t,e,i,n,r,a,s)}function Gi(t,e,i,n,r,a,o){var s=$i(t,e,r,a,o),l=Ni(t,e);r&&(l+=r[1]+r[3]);var u=s.outerHeight,h=Hi(0,l,i),c=Wi(0,u,n),d=new xi(h,c,l,u);return d.lineHeight=s.lineHeight,d}function Vi(t,e,i,n,r,a,o,s){var l=Qi(t,{rich:o,truncate:s,font:e,textAlign:i,textPadding:r,textLineHeight:a}),u=l.outerWidth,h=l.outerHeight,c=Hi(0,u,i),d=Wi(0,h,n);return new xi(c,d,u,h)}function Hi(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function Wi(t,e,i){return"middle"===i?t-=e/2:"bottom"===i&&(t-=e),t}function Ui(t,e,i){var n=e.textPosition,r=e.textDistance,a=i.x,o=i.y;r=r||0;var s=i.height,l=i.width,u=s/2,h="left",c="top";switch(n){case"left":a-=r,o+=u,h="right",c="middle";break;case"right":a+=r+l,o+=u,c="middle";break;case"top":a+=l/2,o-=r,h="center",c="bottom";break;case"bottom":a+=l/2,o+=s+r,h="center";break;case"inside":a+=l/2,o+=u,h="center",c="middle";break;case"insideLeft":a+=r,o+=u,c="middle";break;case"insideRight":a+=l-r,o+=u,h="right",c="middle";break;case"insideTop":a+=l/2,o+=r,h="center";break;case"insideBottom":a+=l/2,o+=s-r,h="center",c="bottom";break;case"insideTopLeft":a+=r,o+=r;break;case"insideTopRight":a+=l-r,o+=r,h="right";break;case"insideBottomLeft":a+=r,o+=s-r,c="bottom";break;case"insideBottomRight":a+=l-r,o+=s-r,h="right",c="bottom"}return t=t||{},t.x=a,t.y=o,t.textAlign=h,t.textVerticalAlign=c,t}function Xi(t,e,i,n,r){if(!e)return"";var a=(t+"").split("\n");r=Yi(e,i,n,r);for(var o=0,s=a.length;s>o;o++)a[o]=ji(a[o],r);return a.join("\n")}function Yi(t,e,i,n){n=o({},n),n.font=e;var i=A(i,"...");n.maxIterations=A(n.maxIterations,2);var r=n.minChar=A(n.minChar,0);n.cnCharWidth=Ni("国",e);var a=n.ascCharWidth=Ni("a",e);n.placeholder=A(n.placeholder,"");for(var s=t=Math.max(0,t-1),l=0;r>l&&s>=a;l++)s-=a;var u=Ni(i,e);return u>s&&(i="",u=0),s=t-u,n.ellipsis=i,n.ellipsisWidth=u,n.contentWidth=s,n.containerWidth=t,n}function ji(t,e){var i=e.containerWidth,n=e.font,r=e.contentWidth;if(!i)return"";var a=Ni(t,n);if(i>=a)return t;for(var o=0;;o++){if(r>=a||o>=e.maxIterations){t+=e.ellipsis;break}var s=0===o?qi(t,r,e.ascCharWidth,e.cnCharWidth):a>0?Math.floor(t.length*r/a):0;t=t.substr(0,s),a=Ni(t,n)}return""===t&&(t=e.placeholder),t}function qi(t,e,i,n){for(var r=0,a=0,o=t.length;o>a&&e>r;a++){var s=t.charCodeAt(a);r+=s>=0&&127>=s?i:n}return a}function Zi(t){return Ni("国",t)}function Ki(t,e){return Kg.measureText(t,e)}function $i(t,e,i,n,r){null!=t&&(t+="");var a=A(n,Zi(e)),o=t?t.split("\n"):[],s=o.length*a,l=s,u=!0;if(i&&(l+=i[0]+i[2]),t&&r){u=!1;var h=r.outerHeight,c=r.outerWidth;if(null!=h&&l>h)t="",o=[];else if(null!=c)for(var d=Yi(c-(i?i[1]+i[3]:0),e,r.ellipsis,{minChar:r.minChar,placeholder:r.placeholder}),f=0,p=o.length;p>f;f++)o[f]=ji(o[f],d)}return{lines:o,height:s,outerHeight:l,lineHeight:a,canCacheByTextString:u}}function Qi(t,e){var i={lines:[],width:0,height:0};if(null!=t&&(t+=""),!t)return i;for(var n,r=qg.lastIndex=0;null!=(n=qg.exec(t));){var a=n.index;a>r&&Ji(i,t.substring(r,a)),Ji(i,n[2],n[1]),r=qg.lastIndex}rf)return{lines:[],width:0,height:0};_.textWidth=Ni(_.text,b);var M=x.textWidth,I=null==M||"auto"===M;if("string"==typeof M&&"%"===M.charAt(M.length-1))_.percentWidth=M,u.push(_),M=0;else{if(I){M=_.textWidth;var C=x.textBackgroundColor,T=C&&C.image;T&&(T=zi(T),Ri(T)&&(M=Math.max(M,T.width*S/T.height)))}var D=w?w[1]+w[3]:0;M+=D;var P=null!=d?d-m:null;null!=P&&M>P&&(!I||D>P?(_.text="",_.textWidth=M=0):(_.text=Xi(_.text,P-D,b,c.ellipsis,{minChar:c.minChar}),_.textWidth=Ni(_.text,b),M=_.textWidth+D))}m+=_.width=M,x&&(v=Math.max(v,_.lineHeight))}g.width=m,g.lineHeight=v,s+=v,l=Math.max(l,m)}i.outerWidth=i.width=A(e.textWidth,l),i.outerHeight=i.height=A(e.textHeight,s),h&&(i.outerWidth+=h[1]+h[3],i.outerHeight+=h[0]+h[2]);for(var p=0;pl&&(o+=l,l=-l),0>u&&(s+=u,u=-u),"number"==typeof h?i=n=r=a=h:h instanceof Array?1===h.length?i=n=r=a=h[0]:2===h.length?(i=r=h[0],n=a=h[1]):3===h.length?(i=h[0],n=a=h[1],r=h[2]):(i=h[0],n=h[1],r=h[2],a=h[3]):i=n=r=a=0;var c;i+n>l&&(c=i+n,i*=l/c,n*=l/c),r+a>l&&(c=r+a,r*=l/c,a*=l/c),n+r>u&&(c=n+r,n*=u/c,r*=u/c),i+a>u&&(c=i+a,i*=u/c,a*=u/c),t.moveTo(o+i,s),t.lineTo(o+l-n,s),0!==n&&t.arc(o+l-n,s+n,n,-Math.PI/2,0),t.lineTo(o+l,s+u-r),0!==r&&t.arc(o+l-r,s+u-r,r,0,Math.PI/2),t.lineTo(o+a,s+u),0!==a&&t.arc(o+a,s+u-a,a,Math.PI/2,Math.PI),t.lineTo(o,s+i),0!==i&&t.arc(o+i,s+i,i,Math.PI,1.5*Math.PI)}function nn(t){return rn(t),f(t.rich,rn),t}function rn(t){if(t){t.font=tn(t);var e=t.textAlign;"middle"===e&&(e="center"),t.textAlign=null==e||Qg[e]?e:"left";var i=t.textVerticalAlign||t.textBaseline;"center"===i&&(i="middle"),t.textVerticalAlign=null==i||Jg[i]?i:"top";var n=t.textPadding;n&&(t.textPadding=L(t.textPadding))}}function an(t,e,i,n,r,a){n.rich?sn(t,e,i,n,r,a):on(t,e,i,n,r,a)}function on(t,e,i,n,r,a){var o,s=cn(n),l=!1,u=e.__attrCachedBy===zg.PLAIN_TEXT;a!==Bg?(a&&(o=a.style,l=!s&&u&&o),e.__attrCachedBy=s?zg.NONE:zg.PLAIN_TEXT):u&&(e.__attrCachedBy=zg.NONE);var h=n.font||$g;l&&h===(o.font||$g)||(e.font=h);var c=t.__computedFont;t.__styleFont!==h&&(t.__styleFont=h,c=t.__computedFont=e.font);var d=n.textPadding,f=n.textLineHeight,p=t.__textCotentBlock;(!p||t.__dirtyText)&&(p=t.__textCotentBlock=$i(i,c,d,f,n.truncate));var g=p.outerHeight,v=p.lines,m=p.lineHeight,y=pn(iv,t,n,r),_=y.baseX,x=y.baseY,w=y.textAlign||"left",b=y.textVerticalAlign;un(e,n,r,_,x);var S=Wi(x,g,b),M=_,I=S;if(s||d){var C=Ni(i,c),T=C;d&&(T+=d[1]+d[3]);var D=Hi(_,T,w);s&&dn(t,e,n,D,S,T,g),d&&(M=_n(_,w,d),I+=d[0])}e.textAlign=w,e.textBaseline="middle",e.globalAlpha=n.opacity||1;for(var A=0;AC&&(x=b[C],!x.textAlign||"left"===x.textAlign);)hn(t,e,x,n,M,m,T,"left"),I-=x.width,T+=x.width,C++;for(;A>=0&&(x=b[A],"right"===x.textAlign);)hn(t,e,x,n,M,m,D,"right"),I-=x.width,D-=x.width,A--;for(T+=(a-(T-v)-(y-D)-I)/2;A>=C;)x=b[C],hn(t,e,x,n,M,m,T+x.width/2,"center"),T+=x.width,C++;m+=M}}function un(t,e,i,n,r){if(i&&e.textRotation){var a=e.textOrigin;"center"===a?(n=i.width/2+i.x,r=i.height/2+i.y):a&&(n=a[0]+i.x,r=a[1]+i.y),t.translate(n,r),t.rotate(-e.textRotation),t.translate(-n,-r)}}function hn(t,e,i,n,r,a,o,s){var l=n.rich[i.styleName]||{};l.text=i.text;var u=i.textVerticalAlign,h=a+r/2;"top"===u?h=a+i.height/2:"bottom"===u&&(h=a+r-i.height/2),!i.isLineHolder&&cn(l)&&dn(t,e,l,"right"===s?o-i.width:"center"===s?o-i.width/2:o,h-i.height/2,i.width,i.height);var c=i.textPadding;c&&(o=_n(o,s,c),h-=i.height/2-c[2]-i.textHeight/2),gn(e,"shadowBlur",k(l.textShadowBlur,n.textShadowBlur,0)),gn(e,"shadowColor",l.textShadowColor||n.textShadowColor||"transparent"),gn(e,"shadowOffsetX",k(l.textShadowOffsetX,n.textShadowOffsetX,0)),gn(e,"shadowOffsetY",k(l.textShadowOffsetY,n.textShadowOffsetY,0)),gn(e,"textAlign",s),gn(e,"textBaseline","middle"),gn(e,"font",i.font||$g); -var d=vn(l.textStroke||n.textStroke,p),f=mn(l.textFill||n.textFill),p=A(l.textStrokeWidth,n.textStrokeWidth);d&&(gn(e,"lineWidth",p),gn(e,"strokeStyle",d),e.strokeText(i.text,o,h)),f&&(gn(e,"fillStyle",f),e.fillText(i.text,o,h))}function cn(t){return!!(t.textBackgroundColor||t.textBorderWidth&&t.textBorderColor)}function dn(t,e,i,n,r,a,o){var s=i.textBackgroundColor,l=i.textBorderWidth,u=i.textBorderColor,h=b(s);if(gn(e,"shadowBlur",i.textBoxShadowBlur||0),gn(e,"shadowColor",i.textBoxShadowColor||"transparent"),gn(e,"shadowOffsetX",i.textBoxShadowOffsetX||0),gn(e,"shadowOffsetY",i.textBoxShadowOffsetY||0),h||l&&u){e.beginPath();var c=i.textBorderRadius;c?en(e,{x:n,y:r,width:a,height:o,r:c}):e.rect(n,r,a,o),e.closePath()}if(h)if(gn(e,"fillStyle",s),null!=i.fillOpacity){var d=e.globalAlpha;e.globalAlpha=i.fillOpacity*i.opacity,e.fill(),e.globalAlpha=d}else e.fill();else if(S(s)){var f=s.image;f=Bi(f,null,t,fn,s),f&&Ri(f)&&e.drawImage(f,n,r,a,o)}if(l&&u)if(gn(e,"lineWidth",l),gn(e,"strokeStyle",u),null!=i.strokeOpacity){var d=e.globalAlpha;e.globalAlpha=i.strokeOpacity*i.opacity,e.stroke(),e.globalAlpha=d}else e.stroke()}function fn(t,e){e.image=t}function pn(t,e,i,n){var r=i.x||0,a=i.y||0,o=i.textAlign,s=i.textVerticalAlign;if(n){var l=i.textPosition;if(l instanceof Array)r=n.x+yn(l[0],n.width),a=n.y+yn(l[1],n.height);else{var u=e&&e.calculateTextPosition?e.calculateTextPosition(ev,i,n):Ui(ev,i,n);r=u.x,a=u.y,o=o||u.textAlign,s=s||u.textVerticalAlign}var h=i.textOffset;h&&(r+=h[0],a+=h[1])}return t=t||{},t.baseX=r,t.baseY=a,t.textAlign=o,t.textVerticalAlign=s,t}function gn(t,e,i){return t[e]=Og(t,e,i),t[e]}function vn(t,e){return null==t||0>=e||"transparent"===t||"none"===t?null:t.image||t.colorStops?"#000":t}function mn(t){return null==t||"none"===t?null:t.image||t.colorStops?"#000":t}function yn(t,e){return"string"==typeof t?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t}function _n(t,e,i){return"right"===e?t-i[1]:"center"===e?t+i[3]/2-i[1]/2:t+i[3]}function xn(t,e){return null!=t&&(t||e.textBackgroundColor||e.textBorderWidth&&e.textBorderColor||e.textPadding)}function wn(t){t=t||{},Mg.call(this,t);for(var e in t)t.hasOwnProperty(e)&&"style"!==e&&(this[e]=t[e]);this.style=new Rg(t.style,this),this._rect=null,this.__clipPaths=null}function bn(t){wn.call(this,t)}function Sn(t){return parseInt(t,10)}function Mn(t){return t?t.__builtin__?!0:"function"!=typeof t.resize||"function"!=typeof t.refresh?!1:!0:!1}function In(t,e,i){return uv.copy(t.getBoundingRect()),t.transform&&uv.applyTransform(t.transform),hv.width=e,hv.height=i,!uv.intersect(hv)}function Cn(t,e){if(t===e)return!1;if(!t||!e||t.length!==e.length)return!0;for(var i=0;in;n++){var a=i[n];!t.emphasis[e].hasOwnProperty(a)&&t[e].hasOwnProperty(a)&&(t.emphasis[e][a]=t[e][a])}}}function Vn(t){return!Tv(t)||Dv(t)||t instanceof Date?t:t.value}function Hn(t){return Tv(t)&&!(t instanceof Array)}function Wn(t,e){e=(e||[]).slice();var i=p(t||[],function(t){return{exist:t}});return Cv(e,function(t,n){if(Tv(t)){for(var r=0;r=i.length&&i.push({option:t})}}),i}function Un(t){var e=N();Cv(t,function(t){var i=t.exist;i&&e.set(i.id,t)}),Cv(t,function(t){var i=t.option;O(!i||null==i.id||!e.get(i.id)||e.get(i.id)===t,"id duplicates: "+(i&&i.id)),i&&null!=i.id&&e.set(i.id,t),!t.keyInfo&&(t.keyInfo={})}),Cv(t,function(t,i){var n=t.exist,r=t.option,a=t.keyInfo;if(Tv(r)){if(a.name=null!=r.name?r.name+"":n?n.name:Av+i,n)a.id=n.id;else if(null!=r.id)a.id=r.id+"";else{var o=0;do a.id="\x00"+a.name+"\x00"+o++;while(e.get(a.id))}e.set(a.id,t)}})}function Xn(t){var e=t.name;return!(!e||!e.indexOf(Av))}function Yn(t){return Tv(t)&&t.id&&0===(t.id+"").indexOf("\x00_ec_\x00")}function jn(t,e){return null!=e.dataIndexInside?e.dataIndexInside:null!=e.dataIndex?x(e.dataIndex)?p(e.dataIndex,function(e){return t.indexOfRawIndex(e)}):t.indexOfRawIndex(e.dataIndex):null!=e.name?x(e.name)?p(e.name,function(e){return t.indexOfName(e)}):t.indexOfName(e.name):void 0}function qn(){var t="__\x00ec_inner_"+Pv++ +"_"+Math.random().toFixed(5);return function(e){return e[t]||(e[t]={})}}function Zn(t,e,i){if(b(e)){var n={};n[e+"Index"]=0,e=n}var r=i&&i.defaultMainType;!r||Kn(e,r+"Index")||Kn(e,r+"Id")||Kn(e,r+"Name")||(e[r+"Index"]=0);var a={};return Cv(e,function(n,r){var n=e[r];if("dataIndex"===r||"dataIndexInside"===r)return void(a[r]=n);var o=r.match(/^(\w+)(Index|Id|Name)$/)||[],s=o[1],l=(o[2]||"").toLowerCase();if(!(!s||!l||null==n||"index"===l&&"none"===n||i&&i.includeMainTypes&&u(i.includeMainTypes,s)<0)){var h={mainType:s};("index"!==l||"all"!==n)&&(h[l]=n);var c=t.queryComponents(h);a[s+"Models"]=c,a[s+"Model"]=c[0]}}),a}function Kn(t,e){return t&&t.hasOwnProperty(e)}function $n(t,e,i){t.setAttribute?t.setAttribute(e,i):t[e]=i}function Qn(t,e){return t.getAttribute?t.getAttribute(e):t[e]}function Jn(t){return"auto"===t?gp.domSupported?"html":"richText":t||"html"}function tr(t){var e={main:"",sub:""};return t&&(t=t.split(Lv),e.main=t[0]||"",e.sub=t[1]||""),e}function er(t){O(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(t),'componentType "'+t+'" illegal')}function ir(t){t.$constructor=t,t.extend=function(t){var e=this,i=function(){t.$constructor?t.$constructor.apply(this,arguments):e.apply(this,arguments)};return o(i.prototype,t),i.extend=this.extend,i.superCall=rr,i.superApply=ar,h(i,this),i.superClass=e,i}}function nr(t){var e=["__\x00is_clz",zv++,Math.random().toFixed(3)].join("_");t.prototype[e]=!0,t.isInstance=function(t){return!(!t||!t[e])}}function rr(t,e){var i=P(arguments,2);return this.superClass.prototype[e].apply(t,i)}function ar(t,e,i){return this.superClass.prototype[e].apply(t,i)}function or(t,e){function i(t){var e=n[t.main];return e&&e[Ov]||(e=n[t.main]={},e[Ov]=!0),e}e=e||{};var n={};if(t.registerClass=function(t,e){if(e)if(er(e),e=tr(e),e.sub){if(e.sub!==Ov){var r=i(e);r[e.sub]=t}}else n[e.main]=t;return t},t.getClass=function(t,e,i){var r=n[t];if(r&&r[Ov]&&(r=e?r[e]:null),i&&!r)throw new Error(e?"Component "+t+"."+(e||"")+" not exists. Load it first.":t+".type should be specified.");return r},t.getClassesByMainType=function(t){t=tr(t);var e=[],i=n[t.main];return i&&i[Ov]?f(i,function(t,i){i!==Ov&&e.push(t)}):e.push(i),e},t.hasClass=function(t){return t=tr(t),!!n[t.main]},t.getAllClassMainTypes=function(){var t=[];return f(n,function(e,i){t.push(i)}),t},t.hasSubTypes=function(t){t=tr(t);var e=n[t.main];return e&&e[Ov]},t.parseClassType=tr,e.registerWhenExtend){var r=t.extend;r&&(t.extend=function(e){var i=r.call(this,e);return t.registerClass(i,e.type)})}return t}function sr(t){return t>-Hv&&Hv>t}function lr(t){return t>Hv||-Hv>t}function ur(t,e,i,n,r){var a=1-r;return a*a*(a*t+3*r*e)+r*r*(r*n+3*a*i)}function hr(t,e,i,n,r){var a=1-r;return 3*(((e-t)*a+2*(i-e)*r)*a+(n-i)*r*r)}function cr(t,e,i,n,r,a){var o=n+3*(e-i)-t,s=3*(i-2*e+t),l=3*(e-t),u=t-r,h=s*s-3*o*l,c=s*l-9*o*u,d=l*l-3*s*u,f=0;if(sr(h)&&sr(c))if(sr(s))a[0]=0;else{var p=-l/s;p>=0&&1>=p&&(a[f++]=p)}else{var g=c*c-4*h*d;if(sr(g)){var v=c/h,p=-s/o+v,m=-v/2;p>=0&&1>=p&&(a[f++]=p),m>=0&&1>=m&&(a[f++]=m)}else if(g>0){var y=Vv(g),_=h*s+1.5*o*(-c+y),x=h*s+1.5*o*(-c-y);_=0>_?-Gv(-_,Xv):Gv(_,Xv),x=0>x?-Gv(-x,Xv):Gv(x,Xv);var p=(-s-(_+x))/(3*o);p>=0&&1>=p&&(a[f++]=p)}else{var w=(2*h*s-3*o*c)/(2*Vv(h*h*h)),b=Math.acos(w)/3,S=Vv(h),M=Math.cos(b),p=(-s-2*S*M)/(3*o),m=(-s+S*(M+Uv*Math.sin(b)))/(3*o),I=(-s+S*(M-Uv*Math.sin(b)))/(3*o);p>=0&&1>=p&&(a[f++]=p),m>=0&&1>=m&&(a[f++]=m),I>=0&&1>=I&&(a[f++]=I)}}return f}function dr(t,e,i,n,r){var a=6*i-12*e+6*t,o=9*e+3*n-3*t-9*i,s=3*e-3*t,l=0;if(sr(o)){if(lr(a)){var u=-s/a;u>=0&&1>=u&&(r[l++]=u)}}else{var h=a*a-4*o*s;if(sr(h))r[0]=-a/(2*o);else if(h>0){var c=Vv(h),u=(-a+c)/(2*o),d=(-a-c)/(2*o);u>=0&&1>=u&&(r[l++]=u),d>=0&&1>=d&&(r[l++]=d)}}return l}function fr(t,e,i,n,r,a){var o=(e-t)*r+t,s=(i-e)*r+e,l=(n-i)*r+i,u=(s-o)*r+o,h=(l-s)*r+s,c=(h-u)*r+u;a[0]=t,a[1]=o,a[2]=u,a[3]=c,a[4]=c,a[5]=h,a[6]=l,a[7]=n}function pr(t,e,i,n,r,a,o,s,l,u,h){var c,d,f,p,g,v=.005,m=1/0;Yv[0]=l,Yv[1]=u;for(var y=0;1>y;y+=.05)jv[0]=ur(t,i,r,o,y),jv[1]=ur(e,n,a,s,y),p=zp(Yv,jv),m>p&&(c=y,m=p);m=1/0;for(var _=0;32>_&&!(Wv>v);_++)d=c-v,f=c+v,jv[0]=ur(t,i,r,o,d),jv[1]=ur(e,n,a,s,d),p=zp(jv,Yv),d>=0&&m>p?(c=d,m=p):(qv[0]=ur(t,i,r,o,f),qv[1]=ur(e,n,a,s,f),g=zp(qv,Yv),1>=f&&m>g?(c=f,m=g):v*=.5);return h&&(h[0]=ur(t,i,r,o,c),h[1]=ur(e,n,a,s,c)),Vv(m)}function gr(t,e,i,n){var r=1-n;return r*(r*t+2*n*e)+n*n*i}function vr(t,e,i,n){return 2*((1-n)*(e-t)+n*(i-e))}function mr(t,e,i,n,r){var a=t-2*e+i,o=2*(e-t),s=t-n,l=0;if(sr(a)){if(lr(o)){var u=-s/o;u>=0&&1>=u&&(r[l++]=u)}}else{var h=o*o-4*a*s;if(sr(h)){var u=-o/(2*a);u>=0&&1>=u&&(r[l++]=u)}else if(h>0){var c=Vv(h),u=(-o+c)/(2*a),d=(-o-c)/(2*a);u>=0&&1>=u&&(r[l++]=u),d>=0&&1>=d&&(r[l++]=d)}}return l}function yr(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function _r(t,e,i,n,r){var a=(e-t)*n+t,o=(i-e)*n+e,s=(o-a)*n+a;r[0]=t,r[1]=a,r[2]=s,r[3]=s,r[4]=o,r[5]=i}function xr(t,e,i,n,r,a,o,s,l){var u,h=.005,c=1/0;Yv[0]=o,Yv[1]=s;for(var d=0;1>d;d+=.05){jv[0]=gr(t,i,r,d),jv[1]=gr(e,n,a,d);var f=zp(Yv,jv);c>f&&(u=d,c=f)}c=1/0;for(var p=0;32>p&&!(Wv>h);p++){var g=u-h,v=u+h;jv[0]=gr(t,i,r,g),jv[1]=gr(e,n,a,g);var f=zp(jv,Yv);if(g>=0&&c>f)u=g,c=f;else{qv[0]=gr(t,i,r,v),qv[1]=gr(e,n,a,v);var m=zp(qv,Yv);1>=v&&c>m?(u=v,c=m):h*=.5}}return l&&(l[0]=gr(t,i,r,u),l[1]=gr(e,n,a,u)),Vv(c)}function wr(t,e,i){if(0!==t.length){var n,r=t[0],a=r[0],o=r[0],s=r[1],l=r[1];for(n=1;nh;h++){var p=d(t,i,r,o,nm[h]);l[0]=Zv(p,l[0]),u[0]=Kv(p,u[0])}for(f=c(e,n,a,s,rm),h=0;f>h;h++){var g=d(e,n,a,s,rm[h]);l[1]=Zv(g,l[1]),u[1]=Kv(g,u[1])}l[0]=Zv(t,l[0]),u[0]=Kv(t,u[0]),l[0]=Zv(o,l[0]),u[0]=Kv(o,u[0]),l[1]=Zv(e,l[1]),u[1]=Kv(e,u[1]),l[1]=Zv(s,l[1]),u[1]=Kv(s,u[1])}function Mr(t,e,i,n,r,a,o,s){var l=yr,u=gr,h=Kv(Zv(l(t,i,r),1),0),c=Kv(Zv(l(e,n,a),1),0),d=u(t,i,r,h),f=u(e,n,a,c);o[0]=Zv(t,r,d),o[1]=Zv(e,a,f),s[0]=Kv(t,r,d),s[1]=Kv(e,a,f)}function Ir(t,e,i,n,r,a,o,s,l){var u=oe,h=se,c=Math.abs(r-a);if(1e-4>c%Jv&&c>1e-4)return s[0]=t-i,s[1]=e-n,l[0]=t+i,void(l[1]=e+n);if(tm[0]=Qv(r)*i+t,tm[1]=$v(r)*n+e,em[0]=Qv(a)*i+t,em[1]=$v(a)*n+e,u(s,tm,em),h(l,tm,em),r%=Jv,0>r&&(r+=Jv),a%=Jv,0>a&&(a+=Jv),r>a&&!o?a+=Jv:a>r&&o&&(r+=Jv),o){var d=a;a=r,r=d}for(var f=0;a>f;f+=Math.PI/2)f>r&&(im[0]=Qv(f)*i+t,im[1]=$v(f)*n+e,u(s,im,s),h(l,im,l))}function Cr(t,e,i,n,r,a,o){if(0===r)return!1;var s=r,l=0,u=t;if(o>e+s&&o>n+s||e-s>o&&n-s>o||a>t+s&&a>i+s||t-s>a&&i-s>a)return!1;if(t===i)return Math.abs(a-t)<=s/2;l=(e-n)/(t-i),u=(t*n-i*e)/(t-i);var h=l*a-o+u,c=h*h/(l*l+1);return s/2*s/2>=c}function Tr(t,e,i,n,r,a,o,s,l,u,h){if(0===l)return!1;var c=l;if(h>e+c&&h>n+c&&h>a+c&&h>s+c||e-c>h&&n-c>h&&a-c>h&&s-c>h||u>t+c&&u>i+c&&u>r+c&&u>o+c||t-c>u&&i-c>u&&r-c>u&&o-c>u)return!1;var d=pr(t,e,i,n,r,a,o,s,u,h,null);return c/2>=d}function Dr(t,e,i,n,r,a,o,s,l){if(0===o)return!1;var u=o;if(l>e+u&&l>n+u&&l>a+u||e-u>l&&n-u>l&&a-u>l||s>t+u&&s>i+u&&s>r+u||t-u>s&&i-u>s&&r-u>s)return!1;var h=xr(t,e,i,n,r,a,s,l,null);return u/2>=h}function Ar(t){return t%=ym,0>t&&(t+=ym),t}function kr(t,e,i,n,r,a,o,s,l){if(0===o)return!1;var u=o;s-=t,l-=e;var h=Math.sqrt(s*s+l*l);if(h-u>i||i>h+u)return!1;if(Math.abs(n-r)%_m<1e-4)return!0;if(a){var c=n;n=Ar(r),r=Ar(c)}else n=Ar(n),r=Ar(r);n>r&&(r+=_m);var d=Math.atan2(l,s);return 0>d&&(d+=_m),d>=n&&r>=d||d+_m>=n&&r>=d+_m}function Pr(t,e,i,n,r,a){if(a>e&&a>n||e>a&&n>a)return 0;if(n===e)return 0;var o=e>n?1:-1,s=(a-e)/(n-e);(1===s||0===s)&&(o=e>n?.5:-.5);var l=s*(i-t)+t;return l===r?1/0:l>r?o:0}function Lr(t,e){return Math.abs(t-e)e&&u>n&&u>a&&u>s||e>u&&n>u&&a>u&&s>u)return 0;var h=cr(e,n,a,s,u,Sm);if(0===h)return 0;for(var c,d,f=0,p=-1,g=0;h>g;g++){var v=Sm[g],m=0===v||1===v?.5:1,y=ur(t,i,r,o,v);l>y||(0>p&&(p=dr(e,n,a,s,Mm),Mm[1]1&&Or(),c=ur(e,n,a,s,Mm[0]),p>1&&(d=ur(e,n,a,s,Mm[1]))),f+=2===p?vc?m:-m:vd?m:-m:d>s?m:-m:vc?m:-m:c>s?m:-m)}return f}function Br(t,e,i,n,r,a,o,s){if(s>e&&s>n&&s>a||e>s&&n>s&&a>s)return 0;var l=mr(e,n,a,s,Sm);if(0===l)return 0;var u=yr(e,n,a);if(u>=0&&1>=u){for(var h=0,c=gr(e,n,a,u),d=0;l>d;d++){var f=0===Sm[d]||1===Sm[d]?.5:1,p=gr(t,i,r,Sm[d]);o>p||(h+=Sm[d]c?f:-f:c>a?f:-f)}return h}var f=0===Sm[0]||1===Sm[0]?.5:1,p=gr(t,i,r,Sm[0]);return o>p?0:e>a?f:-f}function Er(t,e,i,n,r,a,o,s){if(s-=e,s>i||-i>s)return 0;var l=Math.sqrt(i*i-s*s);Sm[0]=-l,Sm[1]=l;var u=Math.abs(n-r);if(1e-4>u)return 0;if(1e-4>u%wm){n=0,r=wm;var h=a?1:-1;return o>=Sm[0]+t&&o<=Sm[1]+t?h:0}if(a){var l=n;n=Ar(r),r=Ar(l)}else n=Ar(n),r=Ar(r);n>r&&(r+=wm);for(var c=0,d=0;2>d;d++){var f=Sm[d];if(f+t>o){var p=Math.atan2(s,f),h=a?1:-1;0>p&&(p=wm+p),(p>=n&&r>=p||p+wm>=n&&r>=p+wm)&&(p>Math.PI/2&&p<1.5*Math.PI&&(h=-h),c+=h)}}return c}function Rr(t,e,i,n,r){for(var a=0,o=0,s=0,l=0,u=0,h=0;h1&&(i||(a+=Pr(o,s,l,u,n,r))),1===h&&(o=t[h],s=t[h+1],l=o,u=s),c){case xm.M:l=t[h++],u=t[h++],o=l,s=u;break;case xm.L:if(i){if(Cr(o,s,t[h],t[h+1],e,n,r))return!0}else a+=Pr(o,s,t[h],t[h+1],n,r)||0;o=t[h++],s=t[h++];break;case xm.C:if(i){if(Tr(o,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],e,n,r))return!0}else a+=zr(o,s,t[h++],t[h++],t[h++],t[h++],t[h],t[h+1],n,r)||0;o=t[h++],s=t[h++];break;case xm.Q:if(i){if(Dr(o,s,t[h++],t[h++],t[h],t[h+1],e,n,r))return!0}else a+=Br(o,s,t[h++],t[h++],t[h],t[h+1],n,r)||0;o=t[h++],s=t[h++];break;case xm.A:var d=t[h++],f=t[h++],p=t[h++],g=t[h++],v=t[h++],m=t[h++];h+=1;var y=1-t[h++],_=Math.cos(v)*p+d,x=Math.sin(v)*g+f;h>1?a+=Pr(o,s,_,x,n,r):(l=_,u=x);var w=(n-d)*g/p+d;if(i){if(kr(d,f,g,v,v+m,y,e,w,r))return!0}else a+=Er(d,f,g,v,v+m,y,w,r);o=Math.cos(v+m)*p+d,s=Math.sin(v+m)*g+f;break;case xm.R:l=o=t[h++],u=s=t[h++];var b=t[h++],S=t[h++],_=l+b,x=u+S;if(i){if(Cr(l,u,_,u,e,n,r)||Cr(_,u,_,x,e,n,r)||Cr(_,x,l,x,e,n,r)||Cr(l,x,l,u,e,n,r))return!0}else a+=Pr(_,u,_,x,n,r),a+=Pr(l,x,l,u,n,r);break;case xm.Z:if(i){if(Cr(o,s,l,u,e,n,r))return!0}else a+=Pr(o,s,l,u,n,r);o=l,s=u}}return i||Lr(s,u)||(a+=Pr(o,s,l,u,n,r)||0),0!==a}function Nr(t,e,i){return Rr(t,0,!1,e,i)}function Fr(t,e,i,n){return Rr(t,e,!0,i,n)}function Gr(t){wn.call(this,t),this.path=null}function Vr(t,e,i,n,r,a,o,s,l,u,h){var c=l*(Em/180),d=Bm(c)*(t-i)/2+zm(c)*(e-n)/2,f=-1*zm(c)*(t-i)/2+Bm(c)*(e-n)/2,p=d*d/(o*o)+f*f/(s*s);p>1&&(o*=Om(p),s*=Om(p));var g=(r===a?-1:1)*Om((o*o*s*s-o*o*f*f-s*s*d*d)/(o*o*f*f+s*s*d*d))||0,v=g*o*f/s,m=g*-s*d/o,y=(t+i)/2+Bm(c)*v-zm(c)*m,_=(e+n)/2+zm(c)*v+Bm(c)*m,x=Fm([1,0],[(d-v)/o,(f-m)/s]),w=[(d-v)/o,(f-m)/s],b=[(-1*d-v)/o,(-1*f-m)/s],S=Fm(w,b);Nm(w,b)<=-1&&(S=Em),Nm(w,b)>=1&&(S=0),0===a&&S>0&&(S-=2*Em),1===a&&0>S&&(S+=2*Em),h.addData(u,y,_,o,s,x,S,c,a)}function Hr(t){if(!t)return new mm;for(var e,i=0,n=0,r=i,a=n,o=new mm,s=mm.CMD,l=t.match(Gm),u=0;ug;g++)f[g]=parseFloat(f[g]);for(var v=0;p>v;){var m,y,_,x,w,b,S,M=i,I=n;switch(d){case"l":i+=f[v++],n+=f[v++],h=s.L,o.addData(h,i,n);break;case"L":i=f[v++],n=f[v++],h=s.L,o.addData(h,i,n);break;case"m":i+=f[v++],n+=f[v++],h=s.M,o.addData(h,i,n),r=i,a=n,d="l";break;case"M":i=f[v++],n=f[v++],h=s.M,o.addData(h,i,n),r=i,a=n,d="L";break;case"h":i+=f[v++],h=s.L,o.addData(h,i,n);break;case"H":i=f[v++],h=s.L,o.addData(h,i,n);break;case"v":n+=f[v++],h=s.L,o.addData(h,i,n);break;case"V":n=f[v++],h=s.L,o.addData(h,i,n);break;case"C":h=s.C,o.addData(h,f[v++],f[v++],f[v++],f[v++],f[v++],f[v++]),i=f[v-2],n=f[v-1];break;case"c":h=s.C,o.addData(h,f[v++]+i,f[v++]+n,f[v++]+i,f[v++]+n,f[v++]+i,f[v++]+n),i+=f[v-2],n+=f[v-1];break;case"S":m=i,y=n;var C=o.len(),T=o.data;e===s.C&&(m+=i-T[C-4],y+=n-T[C-3]),h=s.C,M=f[v++],I=f[v++],i=f[v++],n=f[v++],o.addData(h,m,y,M,I,i,n);break;case"s":m=i,y=n;var C=o.len(),T=o.data;e===s.C&&(m+=i-T[C-4],y+=n-T[C-3]),h=s.C,M=i+f[v++],I=n+f[v++],i+=f[v++],n+=f[v++],o.addData(h,m,y,M,I,i,n);break;case"Q":M=f[v++],I=f[v++],i=f[v++],n=f[v++],h=s.Q,o.addData(h,M,I,i,n);break;case"q":M=f[v++]+i,I=f[v++]+n,i+=f[v++],n+=f[v++],h=s.Q,o.addData(h,M,I,i,n);break;case"T":m=i,y=n;var C=o.len(),T=o.data;e===s.Q&&(m+=i-T[C-4],y+=n-T[C-3]),i=f[v++],n=f[v++],h=s.Q,o.addData(h,m,y,i,n);break;case"t":m=i,y=n;var C=o.len(),T=o.data;e===s.Q&&(m+=i-T[C-4],y+=n-T[C-3]),i+=f[v++],n+=f[v++],h=s.Q,o.addData(h,m,y,i,n);break;case"A":_=f[v++],x=f[v++],w=f[v++],b=f[v++],S=f[v++],M=i,I=n,i=f[v++],n=f[v++],h=s.A,Vr(M,I,i,n,b,S,_,x,w,h,o);break;case"a":_=f[v++],x=f[v++],w=f[v++],b=f[v++],S=f[v++],M=i,I=n,i+=f[v++],n+=f[v++],h=s.A,Vr(M,I,i,n,b,S,_,x,w,h,o)}}("z"===d||"Z"===d)&&(h=s.Z,o.addData(h),i=r,n=a),e=h}return o.toStatic(),o}function Wr(t,e){var i=Hr(t);return e=e||{},e.buildPath=function(t){if(t.setData){t.setData(i.data);var e=t.getContext();e&&t.rebuildPath(e)}else{var e=t;i.rebuildPath(e)}},e.applyTransform=function(t){Lm(i,t),this.dirty(!0)},e}function Ur(t,e){return new Gr(Wr(t,e))}function Xr(t,e){return Gr.extend(Wr(t,e))}function Yr(t,e){for(var i=[],n=t.length,r=0;n>r;r++){var a=t[r];a.path||a.createPathProxy(),a.__dirtyPath&&a.buildPath(a.path,a.shape,!0),i.push(a.path)}var o=new Gr(e);return o.createPathProxy(),o.buildPath=function(t){t.appendPath(i);var e=t.getContext();e&&t.rebuildPath(e)},o}function jr(t,e,i,n,r,a,o){var s=.5*(i-t),l=.5*(n-e);return(2*(e-i)+s+l)*o+(-3*(e-i)-2*s-l)*a+s*r+e}function qr(t,e,i){var n=e.points,r=e.smooth;if(n&&n.length>=2){if(r&&"spline"!==r){var a=Zm(n,r,i,e.smoothConstraint);t.moveTo(n[0][0],n[0][1]);for(var o=n.length,s=0;(i?o:o-1)>s;s++){var l=a[2*s],u=a[2*s+1],h=n[(s+1)%o];t.bezierCurveTo(l[0],l[1],u[0],u[1],h[0],h[1])}}else{"spline"===r&&(n=qm(n,i)),t.moveTo(n[0][0],n[0][1]);for(var s=1,c=n.length;c>s;s++)t.lineTo(n[s][0],n[s][1])}i&&t.closePath()}}function Zr(t,e,i){var n=i&&i.lineWidth;if(e&&n){var r=e.x1,a=e.x2,o=e.y1,s=e.y2;Qm(2*r)===Qm(2*a)?t.x1=t.x2=$r(r,n,!0):(t.x1=r,t.x2=a),Qm(2*o)===Qm(2*s)?t.y1=t.y2=$r(o,n,!0):(t.y1=o,t.y2=s)}}function Kr(t,e,i){var n=i&&i.lineWidth;if(e&&n){var r=e.x,a=e.y,o=e.width,s=e.height;t.x=$r(r,n,!0),t.y=$r(a,n,!0),t.width=Math.max($r(r+o,n,!1)-t.x,0===o?0:1),t.height=Math.max($r(a+s,n,!1)-t.y,0===s?0:1)}}function $r(t,e,i){var n=Qm(2*t);return(n+Qm(e))%2===0?n/2:(n+(i?1:-1))/2}function Qr(t,e,i){var n=t.cpx2,r=t.cpy2;return null===n||null===r?[(i?hr:ur)(t.x1,t.cpx1,t.cpx2,t.x2,e),(i?hr:ur)(t.y1,t.cpy1,t.cpy2,t.y2,e)]:[(i?vr:gr)(t.x1,t.cpx1,t.x2,e),(i?vr:gr)(t.y1,t.cpy1,t.y2,e)]}function Jr(t){wn.call(this,t),this._displayables=[],this._temporaryDisplayables=[],this._cursor=0,this.notClear=!0}function ta(t){return Gr.extend(t)}function ea(t,e){return Xr(t,e)}function ia(t,e){xy[t]=e}function na(t){return xy.hasOwnProperty(t)?xy[t]:void 0}function ra(t,e,i,n){var r=Ur(t,e);return i&&("center"===n&&(i=oa(i,r.getBoundingRect())),sa(r,i)),r}function aa(t,e,i){var n=new bn({style:{image:t,x:e.x,y:e.y,width:e.width,height:e.height},onload:function(t){if("center"===i){var r={width:t.width,height:t.height};n.setStyle(oa(e,r))}}});return n}function oa(t,e){var i,n=e.width/e.height,r=t.height*n;r<=t.width?i=t.height:(r=t.width,i=r/n);var a=t.x+t.width/2,o=t.y+t.height/2;return{x:a-r/2,y:o-i/2,width:r,height:i}}function sa(t,e){if(t.applyTransform){var i=t.getBoundingRect(),n=i.calculateTransform(e);t.applyTransform(n)}}function la(t){return Zr(t.shape,t.shape,t.style),t}function ua(t){return Kr(t.shape,t.shape,t.style),t}function ha(t){return null!=t&&"none"!==t}function ca(t){if("string"!=typeof t)return t;var e=Sy.get(t);return e||(e=$e(t,-.1),1e4>My&&(Sy.set(t,e),My++)),e}function da(t){if(t.__hoverStlDirty){t.__hoverStlDirty=!1;var e=t.__hoverStl;if(!e)return void(t.__cachedNormalStl=t.__cachedNormalZ2=null);var i=t.__cachedNormalStl={};t.__cachedNormalZ2=t.z2;var n=t.style;for(var r in e)null!=e[r]&&(i[r]=n[r]);i.fill=n.fill,i.stroke=n.stroke}}function fa(t){var e=t.__hoverStl;if(e&&!t.__highlighted){var i=t.__zr,n=t.useHoverLayer&&i&&"canvas"===i.painter.type;if(t.__highlighted=n?"layer":"plain",!(t.isGroup||!i&&t.useHoverLayer)){var r=t,a=t.style;n&&(r=i.addHover(t),a=r.style),Ea(a),n||da(r),a.extendFrom(e),pa(a,e,"fill"),pa(a,e,"stroke"),Ba(a),n||(t.dirty(!1),t.z2+=py)}}}function pa(t,e,i){!ha(e[i])&&ha(t[i])&&(t[i]=ca(t[i]))}function ga(t){var e=t.__highlighted;if(e&&(t.__highlighted=!1,!t.isGroup))if("layer"===e)t.__zr&&t.__zr.removeHover(t);else{var i=t.style,n=t.__cachedNormalStl;n&&(Ea(i),t.setStyle(n),Ba(i));var r=t.__cachedNormalZ2;null!=r&&t.z2-r===py&&(t.z2=r)}}function va(t,e,i){var n,r=my,a=my;t.__highlighted&&(r=vy,n=!0),e(t,i),t.__highlighted&&(a=vy,n=!0),t.isGroup&&t.traverse(function(t){!t.isGroup&&e(t,i)}),n&&t.__highDownOnUpdate&&t.__highDownOnUpdate(r,a)}function ma(t,e){e=t.__hoverStl=e!==!1&&(t.hoverStyle||e||{}),t.__hoverStlDirty=!0,t.__highlighted&&(t.__cachedNormalStl=null,ga(t),fa(t))}function ya(t){!ba(this,t)&&!this.__highByOuter&&va(this,fa)}function _a(t){!ba(this,t)&&!this.__highByOuter&&va(this,ga)}function xa(t){this.__highByOuter|=1<<(t||0),va(this,fa)}function wa(t){!(this.__highByOuter&=~(1<<(t||0)))&&va(this,ga)}function ba(t,e){return t.__highDownSilentOnTouch&&e.zrByTouch}function Sa(t,e){Ma(t,!0),va(t,ma,e)}function Ma(t,e){var i=e===!1;if(t.__highDownSilentOnTouch=t.highDownSilentOnTouch,t.__highDownOnUpdate=t.highDownOnUpdate,!i||t.__highDownDispatcher){var n=i?"off":"on";t[n]("mouseover",ya)[n]("mouseout",_a),t[n]("emphasis",xa)[n]("normal",wa),t.__highByOuter=t.__highByOuter||0,t.__highDownDispatcher=!i}}function Ia(t){return!(!t||!t.__highDownDispatcher)}function Ca(t){var e=_y[t];return null==e&&32>=yy&&(e=_y[t]=yy++),e}function Ta(t,e,i,n,r,a,o){r=r||fy;var s,l=r.labelFetcher,u=r.labelDataIndex,h=r.labelDimIndex,c=i.getShallow("show"),d=n.getShallow("show");(c||d)&&(l&&(s=l.getFormattedLabel(u,"normal",null,h)),null==s&&(s=w(r.defaultText)?r.defaultText(u,r):r.defaultText));var f=c?s:null,p=d?A(l?l.getFormattedLabel(u,"emphasis",null,h):null,s):null;(null!=f||null!=p)&&(Aa(t,i,a,r),Aa(e,n,o,r,!0)),t.text=f,e.text=p}function Da(t,e,i){var n=t.style;e&&(Ea(n),t.setStyle(e),Ba(n)),n=t.__hoverStl,i&&n&&(Ea(n),o(n,i),Ba(n))}function Aa(t,e,i,n,r){return Pa(t,e,n,r),i&&o(t,i),t}function ka(t,e,i){var n,r={isRectText:!0};i===!1?n=!0:r.autoColor=i,Pa(t,e,r,n)}function Pa(t,e,i,n){if(i=i||fy,i.isRectText){var r;i.getTextPosition?r=i.getTextPosition(e,n):(r=e.getShallow("position")||(n?null:"inside"),"outside"===r&&(r="top")),t.textPosition=r,t.textOffset=e.getShallow("offset");var a=e.getShallow("rotate");null!=a&&(a*=Math.PI/180),t.textRotation=a,t.textDistance=A(e.getShallow("distance"),n?null:5)}var o,s=e.ecModel,l=s&&s.option.textStyle,u=La(e);if(u){o={};for(var h in u)if(u.hasOwnProperty(h)){var c=e.getModel(["rich",h]);Oa(o[h]={},c,l,i,n)}}return t.rich=o,Oa(t,e,l,i,n,!0),i.forceRich&&!i.textStyle&&(i.textStyle={}),t}function La(t){for(var e;t&&t!==t.ecModel;){var i=(t.option||fy).rich;if(i){e=e||{};for(var n in i)i.hasOwnProperty(n)&&(e[n]=1)}t=t.parentModel}return e}function Oa(t,e,i,n,r,a){i=!r&&i||fy,t.textFill=za(e.getShallow("color"),n)||i.color,t.textStroke=za(e.getShallow("textBorderColor"),n)||i.textBorderColor,t.textStrokeWidth=A(e.getShallow("textBorderWidth"),i.textBorderWidth),r||(a&&(t.insideRollbackOpt=n,Ba(t)),null==t.textFill&&(t.textFill=n.autoColor)),t.fontStyle=e.getShallow("fontStyle")||i.fontStyle,t.fontWeight=e.getShallow("fontWeight")||i.fontWeight,t.fontSize=e.getShallow("fontSize")||i.fontSize,t.fontFamily=e.getShallow("fontFamily")||i.fontFamily,t.textAlign=e.getShallow("align"),t.textVerticalAlign=e.getShallow("verticalAlign")||e.getShallow("baseline"),t.textLineHeight=e.getShallow("lineHeight"),t.textWidth=e.getShallow("width"),t.textHeight=e.getShallow("height"),t.textTag=e.getShallow("tag"),a&&n.disableBox||(t.textBackgroundColor=za(e.getShallow("backgroundColor"),n),t.textPadding=e.getShallow("padding"),t.textBorderColor=za(e.getShallow("borderColor"),n),t.textBorderWidth=e.getShallow("borderWidth"),t.textBorderRadius=e.getShallow("borderRadius"),t.textBoxShadowColor=e.getShallow("shadowColor"),t.textBoxShadowBlur=e.getShallow("shadowBlur"),t.textBoxShadowOffsetX=e.getShallow("shadowOffsetX"),t.textBoxShadowOffsetY=e.getShallow("shadowOffsetY")),t.textShadowColor=e.getShallow("textShadowColor")||i.textShadowColor,t.textShadowBlur=e.getShallow("textShadowBlur")||i.textShadowBlur,t.textShadowOffsetX=e.getShallow("textShadowOffsetX")||i.textShadowOffsetX,t.textShadowOffsetY=e.getShallow("textShadowOffsetY")||i.textShadowOffsetY}function za(t,e){return"auto"!==t?t:e&&e.autoColor?e.autoColor:null}function Ba(t){var e,i=t.textPosition,n=t.insideRollbackOpt;if(n&&null==t.textFill){var r=n.autoColor,a=n.isRectText,o=n.useInsideStyle,s=o!==!1&&(o===!0||a&&i&&"string"==typeof i&&i.indexOf("inside")>=0),l=!s&&null!=r;(s||l)&&(e={textFill:t.textFill,textStroke:t.textStroke,textStrokeWidth:t.textStrokeWidth}),s&&(t.textFill="#fff",null==t.textStroke&&(t.textStroke=r,null==t.textStrokeWidth&&(t.textStrokeWidth=2))),l&&(t.textFill=r)}t.insideRollback=e}function Ea(t){var e=t.insideRollback;e&&(t.textFill=e.textFill,t.textStroke=e.textStroke,t.textStrokeWidth=e.textStrokeWidth,t.insideRollback=null)}function Ra(t,e){var i=e||e.getModel("textStyle");return z([t.fontStyle||i&&i.getShallow("fontStyle")||"",t.fontWeight||i&&i.getShallow("fontWeight")||"",(t.fontSize||i&&i.getShallow("fontSize")||12)+"px",t.fontFamily||i&&i.getShallow("fontFamily")||"sans-serif"].join(" "))}function Na(t,e,i,n,r,a){"function"==typeof r&&(a=r,r=null);var o=n&&n.isAnimationEnabled();if(o){var s=t?"Update":"",l=n.getShallow("animationDuration"+s),u=n.getShallow("animationEasing"+s),h=n.getShallow("animationDelay"+s);"function"==typeof h&&(h=h(r,n.getAnimationDelayParams?n.getAnimationDelayParams(e,r):null)),"function"==typeof l&&(l=l(r)),l>0?e.animateTo(i,l,h||0,u,a,!!a):(e.stopAnimation(),e.attr(i),a&&a())}else e.stopAnimation(),e.attr(i),a&&a()}function Fa(t,e,i,n,r){Na(!0,t,e,i,n,r)}function Ga(t,e,i,n,r){Na(!1,t,e,i,n,r)}function Va(t,e){for(var i=De([]);t&&t!==e;)ke(i,t.getLocalTransform(),i),t=t.parent;return i}function Ha(t,e,i){return e&&!d(e)&&(e=Jp.getLocalTransform(e)),i&&(e=ze([],e)),ae([],t,e)}function Wa(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),r=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-r:"bottom"===t?r:0];return a=Ha(a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?"bottom":"top"}function Ua(t,e,i){function n(t){var e={};return t.traverse(function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}function r(t){var e={position:W(t.position),rotation:t.rotation};return t.shape&&(e.shape=o({},t.shape)),e}if(t&&e){var a=n(t);e.traverse(function(t){if(!t.isGroup&&t.anid){var e=a[t.anid];if(e){var n=r(t);t.attr(r(e)),Fa(t,n,i,t.dataIndex)}}})}}function Xa(t,e){return p(t,function(t){var i=t[0];i=cy(i,e.x),i=dy(i,e.x+e.width);var n=t[1];return n=cy(n,e.y),n=dy(n,e.y+e.height),[i,n]})}function Ya(t,e){var i=cy(t.x,e.x),n=dy(t.x+t.width,e.x+e.width),r=cy(t.y,e.y),a=dy(t.y+t.height,e.y+e.height);return n>=i&&a>=r?{x:i,y:r,width:n-i,height:a-r}:void 0}function ja(t,e,i){e=o({rectHover:!0},e);var n=e.style={strokeNoScale:!0};return i=i||{x:-1,y:-1,width:2,height:2},t?0===t.indexOf("image://")?(n.image=t.slice(8),s(n,i),new bn(e)):ra(t.replace("path://",""),e,i,"center"):void 0}function qa(t,e,i,n,r){for(var a=0,o=r[r.length-1];ag||g>1)return!1;var v=Ka(f,p,h,c)/d;return 0>v||v>1?!1:!0}function Ka(t,e,i,n){return t*n-i*e}function $a(t){return 1e-6>=t&&t>=-1e-6}function Qa(t,e,i){this.parentModel=e,this.ecModel=i,this.option=t}function Ja(t,e,i){for(var n=0;n=0&&i.push(t)}),i}t.topologicalTravel=function(t,e,n,r){function a(t){l[t].entryCount--,0===l[t].entryCount&&u.push(t)}function o(t){h[t]=!0,a(t)}if(t.length){var s=i(e),l=s.graph,u=s.noEntryList,h={};for(f(t,function(t){h[t]=!0});u.length;){var c=u.pop(),d=l[c],p=!!h[c];p&&(n.call(r,c,d.originalDeps.slice()),delete h[c]),f(d.successor,p?o:a)}f(h,function(){throw new Error("Circle dependency may exists")})}}}function ro(t){return t.replace(/^\s+|\s+$/g,"")}function ao(t,e,i,n){var r=e[1]-e[0],a=i[1]-i[0];if(0===r)return 0===a?i[0]:(i[0]+i[1])/2;if(n)if(r>0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/r*a+i[0]}function oo(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?ro(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?0/0:+t}function so(t,e,i){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),i?t:+t}function lo(t){return t.sort(function(t,e){return t-e}),t}function uo(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}function ho(t){var e=t.toString(),i=e.indexOf("e"); -if(i>0){var n=+e.slice(i+1);return 0>n?-n:0}var r=e.indexOf(".");return 0>r?0:e.length-1-r}function co(t,e){var i=Math.log,n=Math.LN10,r=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n),o=Math.min(Math.max(-r+a,0),20);return isFinite(o)?o:20}function fo(t,e,i){if(!t[e])return 0;var n=g(t,function(t,e){return t+(isNaN(e)?0:e)},0);if(0===n)return 0;for(var r=Math.pow(10,i),a=p(t,function(t){return(isNaN(t)?0:t)/n*r*100}),o=100*r,s=p(a,function(t){return Math.floor(t)}),l=g(s,function(t,e){return t+e},0),u=p(a,function(t,e){return t-s[e]});o>l;){for(var h=Number.NEGATIVE_INFINITY,c=null,d=0,f=u.length;f>d;++d)u[d]>h&&(h=u[d],c=d);++s[c],u[c]=0,++l}return s[e]/r}function po(t){var e=2*Math.PI;return(t%e+e)%e}function go(t){return t>-Oy&&Oy>t}function vo(t){if(t instanceof Date)return t;if("string"==typeof t){var e=By.exec(t);if(!e)return new Date(0/0);if(e[8]){var i=+e[4]||0;return"Z"!==e[8].toUpperCase()&&(i-=e[8].slice(0,3)),new Date(Date.UTC(+e[1],+(e[2]||1)-1,+e[3]||1,i,+(e[5]||0),+e[6]||0,+e[7]||0))}return new Date(+e[1],+(e[2]||1)-1,+e[3]||1,+e[4]||0,+(e[5]||0),+e[6]||0,+e[7]||0)}return new Date(null==t?0/0:Math.round(t))}function mo(t){return Math.pow(10,yo(t))}function yo(t){if(0===t)return 0;var e=Math.floor(Math.log(t)/Math.LN10);return t/Math.pow(10,e)>=10&&e++,e}function _o(t,e){var i,n=yo(t),r=Math.pow(10,n),a=t/r;return i=e?1.5>a?1:2.5>a?2:4>a?3:7>a?5:10:1>a?1:2>a?2:3>a?3:5>a?5:10,t=i*r,n>=-20?+t.toFixed(0>n?-n:0):t}function xo(t,e){var i=(t.length-1)*e+1,n=Math.floor(i),r=+t[n-1],a=i-n;return a?r+a*(t[n]-r):r}function wo(t){function e(t,i,n){return t.interval[n]s;s++)a[s]<=i&&(a[s]=i,o[s]=s?1:1-n),i=a[s],n=o[s];a[0]===a[1]&&o[0]*o[1]!==1?t.splice(r,1):r++}return t}function bo(t){return t-parseFloat(t)>=0}function So(t){return isNaN(t)?"-":(t=(t+"").split("."),t[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t.length>1?"."+t[1]:""))}function Mo(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}function Io(t){return null==t?"":(t+"").replace(Ny,function(t,e){return Fy[e]})}function Co(t,e,i){x(e)||(e=[e]);var n=e.length;if(!n)return"";for(var r=e[0].$vars||[],a=0;as;s++)for(var l=0;l':'':{renderMode:r,content:"{marker"+a+"|} ",style:{color:i}}:""}function Ao(t,e){return t+="","0000".substr(0,e-t.length)+t}function ko(t,e,i){("week"===t||"month"===t||"quarter"===t||"half-year"===t||"year"===t)&&(t="MM-dd\nyyyy");var n=vo(e),r=i?"UTC":"",a=n["get"+r+"FullYear"](),o=n["get"+r+"Month"]()+1,s=n["get"+r+"Date"](),l=n["get"+r+"Hours"](),u=n["get"+r+"Minutes"](),h=n["get"+r+"Seconds"](),c=n["get"+r+"Milliseconds"]();return t=t.replace("MM",Ao(o,2)).replace("M",o).replace("yyyy",a).replace("yy",a%100).replace("dd",Ao(s,2)).replace("d",s).replace("hh",Ao(l,2)).replace("h",l).replace("mm",Ao(u,2)).replace("m",u).replace("ss",Ao(h,2)).replace("s",h).replace("SSS",Ao(c,3))}function Po(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t}function Lo(t){return Fi(t.text,t.font,t.textAlign,t.textVerticalAlign,t.textPadding,t.textLineHeight,t.rich,t.truncate)}function Oo(t,e,i,n,r,a,o,s){return Fi(t,e,i,n,r,s,a,o)}function zo(t,e,i,n,r){var a=0,o=0;null==n&&(n=1/0),null==r&&(r=1/0);var s=0;e.eachChild(function(l,u){var h,c,d=l.position,f=l.getBoundingRect(),p=e.childAt(u+1),g=p&&p.getBoundingRect();if("horizontal"===t){var v=f.width+(g?-g.x+f.x:0);h=a+v,h>n||l.newline?(a=0,h=v,o+=s+i,s=f.height):s=Math.max(s,f.height)}else{var m=f.height+(g?-g.y+f.y:0);c=o+m,c>r||l.newline?(a+=s+i,o=0,c=m,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=a,d[1]=o,"horizontal"===t?a=h+i:o=c+i)})}function Bo(t,e,i){i=Ry(i||0);var n=e.width,r=e.height,a=oo(t.left,n),o=oo(t.top,r),s=oo(t.right,n),l=oo(t.bottom,r),u=oo(t.width,n),h=oo(t.height,r),c=i[2]+i[0],d=i[1]+i[3],f=t.aspect;switch(isNaN(u)&&(u=n-s-d-a),isNaN(h)&&(h=r-l-c-o),null!=f&&(isNaN(u)&&isNaN(h)&&(f>n/r?u=.8*n:h=.8*r),isNaN(u)&&(u=f*h),isNaN(h)&&(h=u/f)),isNaN(a)&&(a=n-s-u-d),isNaN(o)&&(o=r-l-h-c),t.left||t.right){case"center":a=n/2-u/2-i[3];break;case"right":a=n-u-d}switch(t.top||t.bottom){case"middle":case"center":o=r/2-h/2-i[0];break;case"bottom":o=r-h-c}a=a||0,o=o||0,isNaN(u)&&(u=n-d-a-(s||0)),isNaN(h)&&(h=r-c-o-(l||0));var p=new xi(a+i[3],o+i[0],u,h);return p.margin=i,p}function Eo(t,e,i){function n(i,n){var o={},l=0,u={},h=0,c=2;if(Uy(i,function(e){u[e]=t[e]}),Uy(i,function(t){r(e,t)&&(o[t]=u[t]=e[t]),a(o,t)&&l++,a(u,t)&&h++}),s[n])return a(e,i[1])?u[i[2]]=null:a(e,i[2])&&(u[i[1]]=null),u;if(h!==c&&l){if(l>=c)return o;for(var d=0;dn;n++)if(t[n].length>e)return t[n];return t[i-1]}function Vo(t){var e=t.get("coordinateSystem"),i={coordSysName:e,coordSysDims:[],axisMap:N(),categoryAxisMap:N()},n=e_[e];return n?(n(t,i,i.axisMap,i.categoryAxisMap),i):void 0}function Ho(t){return"category"===t.get("type")}function Wo(t){this.fromDataset=t.fromDataset,this.data=t.data||(t.sourceFormat===a_?{}:[]),this.sourceFormat=t.sourceFormat||o_,this.seriesLayoutBy=t.seriesLayoutBy||l_,this.dimensionsDefine=t.dimensionsDefine,this.encodeDefine=t.encodeDefine&&N(t.encodeDefine),this.startIndex=t.startIndex||0,this.dimensionsDetectCount=t.dimensionsDetectCount}function Uo(t){var e=t.option.source,i=o_;if(I(e))i=s_;else if(x(e)){0===e.length&&(i=n_);for(var n=0,r=e.length;r>n;n++){var a=e[n];if(null!=a){if(x(a)){i=n_;break}if(S(a)){i=r_;break}}}}else if(S(e)){for(var o in e)if(e.hasOwnProperty(o)&&d(e[o])){i=a_;break}}else if(null!=e)throw new Error("Invalid data");h_(t).sourceFormat=i}function Xo(t){return h_(t).source}function Yo(t){h_(t).datasetMap=N()}function jo(t){var e=t.option,i=e.data,n=I(i)?s_:i_,r=!1,a=e.seriesLayoutBy,o=e.sourceHeader,s=e.dimensions,l=Jo(t);if(l){var u=l.option;i=u.source,n=h_(l).sourceFormat,r=!0,a=a||u.seriesLayoutBy,null==o&&(o=u.sourceHeader),s=s||u.dimensions}var h=qo(i,n,a,o,s),c=e.encode;!c&&l&&(c=Qo(t,l,i,n,a,h)),h_(t).source=new Wo({data:i,fromDataset:r,seriesLayoutBy:a,sourceFormat:n,dimensionsDefine:h.dimensionsDefine,startIndex:h.startIndex,dimensionsDetectCount:h.dimensionsDetectCount,encodeDefine:c})}function qo(t,e,i,n,r){if(!t)return{dimensionsDefine:Zo(r)};var a,o,s;if(e===n_)"auto"===n||null==n?Ko(function(t){null!=t&&"-"!==t&&(b(t)?null==o&&(o=1):o=0)},i,t,10):o=n?1:0,r||1!==o||(r=[],Ko(function(t,e){r[e]=null!=t?t:""},i,t)),a=r?r.length:i===u_?t.length:t[0]?t[0].length:null;else if(e===r_)r||(r=$o(t),s=!0);else if(e===a_)r||(r=[],s=!0,f(t,function(t,e){r.push(e)}));else if(e===i_){var l=Vn(t[0]);a=x(l)&&l.length||1}var u;return s&&f(r,function(t,e){"name"===(S(t)?t.name:t)&&(u=e)}),{startIndex:o,dimensionsDefine:Zo(r),dimensionsDetectCount:a,potentialNameDimIndex:u}}function Zo(t){if(t){var e=N();return p(t,function(t){if(t=o({},S(t)?t:{name:t}),null==t.name)return t;t.name+="",null==t.displayName&&(t.displayName=t.name);var i=e.get(t.name);return i?t.name+="-"+i.count++:e.set(t.name,{count:1}),t})}}function Ko(t,e,i,n){if(null==n&&(n=1/0),e===u_)for(var r=0;rr;r++)t(i[r]?i[r][0]:null,r);else for(var a=i[0]||[],r=0;rr;r++)t(a[r],r)}function $o(t){for(var e,i=0;i_&&null==y;_++)es(i,n,r,a.dimensionsDefine,a.startIndex,_)||(y=_);if(null!=y){s.value=y;var x=a.potentialNameDimIndex||Math.max(y-1,0);u.push(x),l.push(x)}}return l.length&&(s.itemName=l),u.length&&(s.seriesName=u),s}function Jo(t){var e=t.option,i=e.data;return i?void 0:t.ecModel.getComponent("dataset",e.datasetIndex||0)}function ts(t,e){return es(t.data,t.sourceFormat,t.seriesLayoutBy,t.dimensionsDefine,t.startIndex,e)}function es(t,e,i,n,r,a){function o(t){return null!=t&&isFinite(t)&&""!==t?!1:b(t)&&"-"!==t?!0:void 0}var s,l=5;if(I(t))return!1;var u;if(n&&(u=n[a],u=S(u)?u.name:u),e===n_)if(i===u_){for(var h=t[a],c=0;c<(h||[]).length&&l>c;c++)if(null!=(s=o(h[r+c])))return s}else for(var c=0;cc;c++){var d=t[r+c];if(d&&null!=(s=o(d[a])))return s}else if(e===r_){if(!u)return;for(var c=0;cc;c++){var f=t[c];if(f&&null!=(s=o(f[u])))return s}}else if(e===a_){if(!u)return;var h=t[u];if(!h||I(h))return!1;for(var c=0;cc;c++)if(null!=(s=o(h[c])))return s}else if(e===i_)for(var c=0;cc;c++){var f=t[c],p=Vn(f);if(!x(p))return!1;if(null!=(s=o(p[a])))return s}return!1}function is(t,e){if(e){var i=e.seiresIndex,n=e.seriesId,r=e.seriesName;return null!=i&&t.componentIndex!==i||null!=n&&t.id!==n||null!=r&&t.name!==r}}function ns(t,e){var i=t.color&&!t.colorLayer;f(e,function(e,a){"colorLayer"===a&&i||Ky.hasClass(a)||("object"==typeof e?t[a]=t[a]?r(t[a],e,!1):n(e):null==t[a]&&(t[a]=e))})}function rs(t){t=t,this.option={},this.option[c_]=1,this._componentsMap=N({series:[]}),this._seriesIndices,this._seriesIndicesMap,ns(t,this._theme.option),r(t,Qy,!1),this.mergeOption(t)}function as(t,e){x(e)||(e=e?[e]:[]);var i={};return f(e,function(e){i[e]=(t.get(e)||[]).slice()}),i}function os(t,e,i){var n=e.type?e.type:i?i.subType:Ky.determineSubType(t,e);return n}function ss(t,e){t._seriesIndicesMap=N(t._seriesIndices=p(e,function(t){return t.componentIndex})||[])}function ls(t,e){return e.hasOwnProperty("subType")?v(t,function(t){return t.subType===e.subType}):t}function us(t){f(f_,function(e){this[e]=y(t[e],t)},this)}function hs(){this._coordinateSystems=[]}function cs(t){this._api=t,this._timelineOptions=[],this._mediaList=[],this._mediaDefault,this._currentMediaIndices=[],this._optionBackup,this._newBaseOption}function ds(t,e,i){var n,r,a=[],o=[],s=t.timeline;if(t.baseOption&&(r=t.baseOption),(s||t.options)&&(r=r||{},a=(t.options||[]).slice()),t.media){r=r||{};var l=t.media;g_(l,function(t){t&&t.option&&(t.query?o.push(t):n||(n=t))})}return r||(r=t),r.timeline||(r.timeline=s),g_([r].concat(a).concat(p(o,function(t){return t.option})),function(t){g_(e,function(e){e(t,i)})}),{baseOption:r,timelineOptions:a,mediaDefault:n,mediaList:o}}function fs(t,e,i){var n={width:e,height:i,aspectratio:e/i},r=!0;return f(t,function(t,e){var i=e.match(__);if(i&&i[1]&&i[2]){var a=i[1],o=i[2].toLowerCase();ps(n[o],t,a)||(r=!1)}}),r}function ps(t,e,i){return"min"===i?t>=e:"max"===i?e>=t:t===e}function gs(t,e){return t.join(",")===e.join(",")}function vs(t,e){e=e||{},g_(e,function(e,i){if(null!=e){var n=t[i];if(Ky.hasClass(i)){e=Fn(e),n=Fn(n);var r=Wn(n,e);t[i]=m_(r,function(t){return t.option&&t.exist?y_(t.exist,t.option,!0):t.exist||t.option})}else t[i]=y_(n,e,!0)}})}function ms(t){var e=t&&t.itemStyle;if(e)for(var i=0,n=b_.length;n>i;i++){var a=b_[i],o=e.normal,s=e.emphasis;o&&o[a]&&(t[a]=t[a]||{},t[a].normal?r(t[a].normal,o[a]):t[a].normal=o[a],o[a]=null),s&&s[a]&&(t[a]=t[a]||{},t[a].emphasis?r(t[a].emphasis,s[a]):t[a].emphasis=s[a],s[a]=null)}}function ys(t,e,i){if(t&&t[e]&&(t[e].normal||t[e].emphasis)){var n=t[e].normal,r=t[e].emphasis;n&&(i?(t[e].normal=t[e].emphasis=null,s(t[e],n)):t[e]=n),r&&(t.emphasis=t.emphasis||{},t.emphasis[e]=r)}}function _s(t){ys(t,"itemStyle"),ys(t,"lineStyle"),ys(t,"areaStyle"),ys(t,"label"),ys(t,"labelLine"),ys(t,"upperLabel"),ys(t,"edgeLabel")}function xs(t,e){var i=w_(t)&&t[e],n=w_(i)&&i.textStyle;if(n)for(var r=0,a=kv.length;a>r;r++){var e=kv[r];n.hasOwnProperty(e)&&(i[e]=n[e])}}function ws(t){t&&(_s(t),xs(t,"label"),t.emphasis&&xs(t.emphasis,"label"))}function bs(t){if(w_(t)){ms(t),_s(t),xs(t,"label"),xs(t,"upperLabel"),xs(t,"edgeLabel"),t.emphasis&&(xs(t.emphasis,"label"),xs(t.emphasis,"upperLabel"),xs(t.emphasis,"edgeLabel"));var e=t.markPoint;e&&(ms(e),ws(e));var i=t.markLine;i&&(ms(i),ws(i));var n=t.markArea;n&&ws(n);var r=t.data;if("graph"===t.type){r=r||t.nodes;var a=t.links||t.edges;if(a&&!I(a))for(var o=0;o=0;p--){var g=t[p];if(s||(d=g.data.rawIndexOf(g.stackedByDimension,c)),d>=0){var v=g.data.getByRawIndex(g.stackResultDimension,d);if(h>=0&&v>0||0>=h&&0>v){h+=v,f=v;break}}}return n[0]=h,n[1]=f,n});o.hostModel.setData(l),e.data=l})}function As(t,e){Wo.isInstance(t)||(t=Wo.seriesDataToSource(t)),this._source=t;var i=this._data=t.data,n=t.sourceFormat;n===s_&&(this._offset=0,this._dimSize=e,this._data=i);var r=A_[n===n_?n+"_"+t.seriesLayoutBy:n];o(this,r)}function ks(){return this._data.length}function Ps(t){return this._data[t]}function Ls(t){for(var e=0;ee.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function Ys(t,e){f(t.CHANGABLE_METHODS,function(i){t.wrapMethod(i,_(js,e))})}function js(t){var e=qs(t);e&&e.setOutputEnd(this.count())}function qs(t){var e=(t.ecModel||{}).scheduler,i=e&&e.getPipeline(t.uid);if(i){var n=i.currentTask;if(n){var r=n.agentStubMap;r&&(n=r.get(t.uid))}return n}}function Zs(){this.group=new Dg,this.uid=eo("viewChart"),this.renderTask=Rs({plan:Qs,reset:Js}),this.renderTask.context={view:this}}function Ks(t,e,i){if(t&&(t.trigger(e,i),t.isGroup&&!Ia(t)))for(var n=0,r=t.childCount();r>n;n++)Ks(t.childAt(n),e,i)}function $s(t,e,i){var n=jn(t,e),r=e&&null!=e.highlightKey?Ca(e.highlightKey):null;null!=n?f(Fn(n),function(e){Ks(t.getItemGraphicEl(e),i,r)}):t.eachItemGraphicEl(function(t){Ks(t,i,r)})}function Qs(t){return H_(t.model)}function Js(t){var e=t.model,i=t.ecModel,n=t.api,r=t.payload,a=e.pipelineContext.progressiveRender,o=t.view,s=r&&V_(r).updateMethod,l=a?"incrementalPrepareRender":s&&o[s]?s:"render";return"render"!==l&&o[l](e,i,n,r),U_[l]}function tl(t,e,i){function n(){h=(new Date).getTime(),c=null,t.apply(o,s||[])}var r,a,o,s,l,u=0,h=0,c=null;e=e||0;var d=function(){r=(new Date).getTime(),o=this,s=arguments;var t=l||e,d=l||i;l=null,a=r-(d?u:h)-t,clearTimeout(c),d?c=setTimeout(n,t):a>=0?n():c=setTimeout(n,-a),u=r};return d.clear=function(){c&&(clearTimeout(c),c=null)},d.debounceNextCall=function(t){l=t},d}function el(t,e,i,n){var r=t[e];if(r){var a=r[X_]||r,o=r[j_],s=r[Y_];if(s!==i||o!==n){if(null==i||!n)return t[e]=a;r=t[e]=tl(a,i,"debounce"===n),r[X_]=a,r[j_]=n,r[Y_]=i}return r}}function il(t,e,i,n){this.ecInstance=t,this.api=e,this.unfinished;var i=this._dataProcessorHandlers=i.slice(),n=this._visualHandlers=n.slice();this._allHandlers=i.concat(n),this._stageTaskMap=N()}function nl(t,e,i,n,r){function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}r=r||{};var o;f(e,function(e){if(!r.visualType||r.visualType===e.visualType){var s=t._stageTaskMap.get(e.uid),l=s.seriesTaskMap,u=s.overallTask;if(u){var h,c=u.agentStubMap;c.each(function(t){a(r,t)&&(t.dirty(),h=!0)}),h&&u.dirty(),tx(u,n);var d=t.getPerformArgs(u,r.block);c.each(function(t){t.perform(d)}),o|=u.perform(d)}else l&&l.each(function(s){a(r,s)&&s.dirty();var l=t.getPerformArgs(s,r.block);l.skip=!e.performRawSeries&&i.isSeriesFiltered(s.context.model),tx(s,n),o|=s.perform(l)})}}),t.unfinished|=o}function rl(t,e,i,n,r){function a(i){var a=i.uid,s=o.get(a)||o.set(a,Rs({plan:hl,reset:cl,count:fl}));s.context={model:i,ecModel:n,api:r,useClearVisual:e.isVisual&&!e.isLayout,plan:e.plan,reset:e.reset,scheduler:t},pl(t,i,s)}var o=i.seriesTaskMap||(i.seriesTaskMap=N()),s=e.seriesType,l=e.getTargetSeries;e.createOnAllSeries?n.eachRawSeries(a):s?n.eachRawSeriesByType(s,a):l&&l(n,r).each(a);var u=t._pipelineMap;o.each(function(t,e){u.get(e)||(t.dispose(),o.removeKey(e))})}function al(t,e,i,n,r){function a(e){var i=e.uid,n=s.get(i);n||(n=s.set(i,Rs({reset:sl,onDirty:ul})),o.dirty()),n.context={model:e,overallProgress:h,modifyOutputEnd:c},n.agent=o,n.__block=h,pl(t,e,n)}var o=i.overallTask=i.overallTask||Rs({reset:ol});o.context={ecModel:n,api:r,overallReset:e.overallReset,scheduler:t};var s=o.agentStubMap=o.agentStubMap||N(),l=e.seriesType,u=e.getTargetSeries,h=!0,c=e.modifyOutputEnd;l?n.eachRawSeriesByType(l,a):u?u(n,r).each(a):(h=!1,f(n.getSeries(),a));var d=t._pipelineMap;s.each(function(t,e){d.get(e)||(t.dispose(),o.dirty(),s.removeKey(e))})}function ol(t){t.overallReset(t.ecModel,t.api,t.payload)}function sl(t){return t.overallProgress&&ll}function ll(){this.agent.dirty(),this.getDownstream().dirty()}function ul(){this.agent&&this.agent.dirty()}function hl(t){return t.plan&&t.plan(t.model,t.ecModel,t.api,t.payload)}function cl(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=Fn(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?p(e,function(t,e){return dl(e)}):ex}function dl(t){return function(e,i){var n=i.data,r=i.resetDefines[t];if(r&&r.dataEach)for(var a=e.start;a0?parseInt(n,10)/100:n?parseFloat(n):0;var r=i.getAttribute("stop-color")||"#000000";e.addColorStop(n,r)}i=i.nextSibling}}function xl(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),s(e.__inheritedStyle,t.__inheritedStyle))}function wl(t){for(var e=z(t).split(dx),i=[],n=0;n0;a-=2){var o=r[a],s=r[a-1];switch(n=n||Te(),s){case"translate":o=z(o).split(dx),Pe(n,n,[parseFloat(o[0]),parseFloat(o[1]||0)]);break;case"scale":o=z(o).split(dx),Oe(n,n,[parseFloat(o[0]),parseFloat(o[1]||o[0])]);break;case"rotate":o=z(o).split(dx),Le(n,n,parseFloat(o[0]));break;case"skew":o=z(o).split(dx),console.warn("Skew transform is not supported yet");break;case"matrix":var o=z(o).split(dx);n[0]=parseFloat(o[0]),n[1]=parseFloat(o[1]),n[2]=parseFloat(o[2]),n[3]=parseFloat(o[3]),n[4]=parseFloat(o[4]),n[5]=parseFloat(o[5])}}e.setLocalTransform(n)}}function Il(t){var e=t.getAttribute("style"),i={};if(!e)return i;var n={};yx.lastIndex=0;for(var r;null!=(r=yx.exec(e));)n[r[1]]=r[2];for(var a in gx)gx.hasOwnProperty(a)&&null!=n[a]&&(i[gx[a]]=n[a]);return i}function Cl(t,e,i){var n=e/t.width,r=i/t.height,a=Math.min(n,r),o=[a,a],s=[-(t.x+t.width/2)*a+e/2,-(t.y+t.height/2)*a+i/2];return{scale:o,position:s}}function Tl(t,e){return function(i,n,r){(e||!this._disposed)&&(i=i&&i.toLowerCase(),Rp.prototype[t].call(this,i,n,r))}}function Dl(){Rp.call(this)}function Al(t,e,i){function r(t,e){return t.__prio-e.__prio}i=i||{},"string"==typeof e&&(e=ew[e]),this.id,this.group,this._dom=t;var a="canvas",o=this._zr=zn(t,{renderer:i.renderer||a,devicePixelRatio:i.devicePixelRatio,width:i.width,height:i.height});this._throttledZrFlush=tl(y(o.flush,o),17);var e=n(e);e&&C_(e,!0),this._theme=e,this._chartsViews=[],this._chartsMap={},this._componentsViews=[],this._componentsMap={},this._coordSysMgr=new hs;var s=this._api=jl(this);Di(tw,r),Di($x,r),this._scheduler=new il(this,s,$x,tw),Rp.call(this,this._ecEventProcessor=new ql),this._messageCenter=new Dl,this._initEvents(),this.resize=y(this.resize,this),this._pendingActions=[],o.animation.on("frame",this._onframe,this),Rl(o,this),B(this)}function kl(t,e,i){if(!this._disposed){var n,r=this._model,a=this._coordSysMgr.getCoordinateSystems();e=Zn(r,e);for(var o=0;oe.get("hoverLayerThreshold")&&!gp.node&&e.eachSeries(function(e){if(!e.preventUsingHoverLayer){var i=t._chartsMap[e.__viewId];i.__alive&&i.group.traverse(function(t){t.useHoverLayer=!0})}})}function Xl(t,e){var i=t.get("blendMode")||null;e.group.traverse(function(t){t.isGroup||t.style.blend!==i&&t.setStyle("blend",i),t.eachPendingDisplayable&&t.eachPendingDisplayable(function(t){t.setStyle("blend",i)})})}function Yl(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function jl(t){var e=t._coordSysMgr;return o(new us(t),{getCoordinateSystems:y(e.getCoordinateSystems,e),getComponentByElement:function(e){for(;e;){var i=e.__ecComponentInfo;if(null!=i)return t._model.getComponent(i.mainType,i.index);e=e.parent}}})}function ql(){this.eventInfo}function Zl(t){function e(t,e){for(var i=0;i65535?vw:yw}function Du(t){var e=t.constructor;return e===Array?t.slice():new e(t)}function Au(t,e){f(_w.concat(e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods,f(xw,function(i){t[i]=n(e[i])}),t._calculationInfo=o(e._calculationInfo)}function ku(t,e,i,n,r){var a=gw[e.type],o=n-1,s=e.name,l=t[s][o];if(l&&l.lengthc;c+=i)t[s].push(new a(Math.min(r-c,i)))}function Pu(t){var e=t._invertedIndicesMap;f(e,function(i,n){var r=t._dimensionInfos[n],a=r.ordinalMeta;if(a){i=e[n]=new mw(a.categories.length);for(var o=0;o=0?this._indices[t]:-1}function Bu(t,e){var i=t._idList[e];return null==i&&(i=Lu(t,t._idDimIdx,e)),null==i&&(i=pw+e),i}function Eu(t){return x(t)||(t=[t]),t}function Ru(t,e){var i=t.dimensions,n=new ww(p(i,t.getDimensionInfo,t),t.hostModel);Au(n,t);for(var r=n._storage={},a=t._storage,o=0;o=0?(r[s]=Nu(a[s]),n._rawExtent[s]=Fu(),n._extent[s]=null):r[s]=a[s])}return n}function Nu(t){for(var e=new Array(t.length),i=0;ip;p++){var g=a[p]=o({},S(a[p])?a[p]:{name:a[p]}),v=g.name,m=c[p]={otherDims:{}};null!=v&&null==u.get(v)&&(m.name=m.displayName=v,u.set(v,p)),null!=g.type&&(m.type=g.type),null!=g.displayName&&(m.displayName=g.displayName)}l.each(function(t,e){if(t=Fn(t).slice(),1===t.length&&!b(t[0])&&t[0]<0)return void l.set(e,!1);var i=l.set(e,[]);f(t,function(t,n){b(t)&&(t=u.get(t)),null!=t&&d>t&&(i[n]=t,r(c[t],e,n))})});var y=0;f(t,function(t){var e,t,i,a;if(b(t))e=t,t={};else{e=t.name;var o=t.ordinalMeta;t.ordinalMeta=null,t=n(t),t.ordinalMeta=o,i=t.dimsDef,a=t.otherDims,t.name=t.coordDim=t.coordDimIndex=t.dimsDef=t.otherDims=null}var u=l.get(e);if(u!==!1){var u=Fn(u);if(!u.length)for(var h=0;h<(i&&i.length||1);h++){for(;yI;I++){var m=c[I]=c[I]||{},C=m.coordDim;null==C&&(m.coordDim=Hu(M,h,w),m.coordDimIndex=0,(!_||0>=x)&&(m.isExtraCoord=!0),x--),null==m.name&&(m.name=Hu(m.coordDim,u)),null==m.type&&ts(e,I,m.name)&&(m.type="ordinal")}return c}function Vu(t,e,i,n){var r=Math.max(t.dimensionsDetectCount||1,e.length,i.length,n||0);return f(e,function(t){var e=t.dimsDef;e&&(r=Math.max(r,e.length))}),r}function Hu(t,e,i){if(i||null!=e.get(t)){for(var n=0;null!=e.get(t+n);)n++;t+=n}return e.set(t,!0),t}function Wu(t,e,i){i=i||{};var n,r,a,o,s=i.byIndex,l=i.stackedCoordDimension,u=!(!t||!t.get("stack"));if(f(e,function(t,i){b(t)&&(e[i]=t={name:t}),u&&!t.isExtraCoord&&(s||n||!t.ordinalMeta||(n=t),r||"ordinal"===t.type||"time"===t.type||l&&l!==t.coordDim||(r=t))}),!r||s||n||(s=!0),r){a="__\x00ecstackresult",o="__\x00ecstackedover",n&&(n.createInvertedIndices=!0);var h=r.coordDim,c=r.type,d=0;f(e,function(t){t.coordDim===h&&d++}),e.push({name:a,coordDim:h,coordDimIndex:d,type:c,isExtraCoord:!0,isCalculationCoord:!0}),d++,e.push({name:o,coordDim:o,coordDimIndex:d,type:c,isExtraCoord:!0,isCalculationCoord:!0})}return{stackedDimension:r&&r.name,stackedByDimension:n&&n.name,isStackedByIndex:s,stackedOverDimension:o,stackResultDimension:a}}function Uu(t,e){return!!e&&e===t.getCalculationInfo("stackedDimension")}function Xu(t,e){return Uu(t,e)?t.getCalculationInfo("stackResultDimension"):e}function Yu(t,e,i){i=i||{},Wo.isInstance(t)||(t=Wo.seriesDataToSource(t));var n,r=e.get("coordinateSystem"),a=hs.get(r),o=Vo(e);o&&(n=p(o.coordSysDims,function(t){var e={name:t},i=o.axisMap.get(t);if(i){var n=i.get("type");e.type=Iu(n)}return e})),n||(n=a&&(a.getDimensionsInfo?a.getDimensionsInfo():a.dimensions.slice())||["x","y"]);var s,l,u=Mw(t,{coordDimensions:n,generateCoord:i.generateCoord});o&&f(u,function(t,e){var i=t.coordDim,n=o.categoryAxisMap.get(i);n&&(null==s&&(s=e),t.ordinalMeta=n.getOrdinalMeta()),null!=t.otherDims.itemName&&(l=!0)}),l||null==s||(u[s].otherDims.itemName=0);var h=Wu(e,u),c=new ww(u,e);c.setCalculationInfo(h);var d=null!=s&&ju(t)?function(t,e,i,n){return n===s?i:this.defaultDimValueGetter(t,e,i,n)}:null;return c.hasItemOption=!1,c.initData(t,null,d),c}function ju(t){if(t.sourceFormat===i_){var e=qu(t.data||[]);return null!=e&&!x(Vn(e))}}function qu(t){for(var e=0;eo&&(o=r.interval=i),null!=n&&o>n&&(o=r.interval=n);var s=r.intervalPrecision=th(o),l=r.niceTickExtent=[Dw(Math.ceil(t[0]/o)*o,s),Dw(Math.floor(t[1]/o)*o,s)];return ih(l,t),r}function th(t){return ho(t)+2}function eh(t,e,i){t[e]=Math.max(Math.min(t[e],i[1]),i[0])}function ih(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),eh(t,0,e),eh(t,1,e),t[0]>t[1]&&(t[0]=t[1])}function nh(t,e,i,n){var r=[];if(!t)return r;var a=1e4;e[0]a)return[];return e[1]>(r.length?r[r.length-1]:i[1])&&r.push(e[1]),r}function rh(t){return t.get("stack")||Pw+t.seriesIndex}function ah(t){return t.dim+t.index}function oh(t,e){var i=[];return e.eachSeriesByType(t,function(t){ch(t)&&!dh(t)&&i.push(t)}),i}function sh(t){var e={};f(t,function(t){var i=t.coordinateSystem,n=i.getBaseAxis();if("time"===n.type||"value"===n.type)for(var r=t.getData(),a=n.dim+"_"+n.index,o=r.mapDimension(n.dim),s=0,l=r.count();l>s;++s){var u=r.get(o,s);e[a]?e[a].push(u):e[a]=[u]}});var i=[];for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];if(r){r.sort(function(t,e){return t-e});for(var a=null,o=1;o0&&(a=null===a?s:Math.min(a,s))}i[n]=a}}return i}function lh(t){var e=sh(t),i=[];return f(t,function(t){var n,r=t.coordinateSystem,a=r.getBaseAxis(),o=a.getExtent();if("category"===a.type)n=a.getBandWidth();else if("value"===a.type||"time"===a.type){var s=a.dim+"_"+a.index,l=e[s],u=Math.abs(o[1]-o[0]),h=a.scale.getExtent(),c=Math.abs(h[1]-h[0]);n=l?u/c*l:u}else{var d=t.getData();n=Math.abs(o[1]-o[0])/d.count()}var f=oo(t.get("barWidth"),n),p=oo(t.get("barMaxWidth"),n),g=oo(t.get("barMinWidth")||1,n),v=t.get("barGap"),m=t.get("barCategoryGap");i.push({bandWidth:n,barWidth:f,barMaxWidth:p,barMinWidth:g,barGap:v,barCategoryGap:m,axisKey:ah(a),stackId:rh(t)})}),uh(i)}function uh(t){var e={};f(t,function(t){var i=t.axisKey,n=t.bandWidth,r=e[i]||{bandWidth:n,remainedWidth:n,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},a=r.stacks;e[i]=r;var o=t.stackId;a[o]||r.autoWidthCount++,a[o]=a[o]||{width:0,maxWidth:0};var s=t.barWidth;s&&!a[o].width&&(a[o].width=s,s=Math.min(r.remainedWidth,s),r.remainedWidth-=s);var l=t.barMaxWidth;l&&(a[o].maxWidth=l);var u=t.barMinWidth;u&&(a[o].minWidth=u);var h=t.barGap;null!=h&&(r.gap=h);var c=t.barCategoryGap;null!=c&&(r.categoryGap=c)});var i={};return f(e,function(t,e){i[e]={};var n=t.stacks,r=t.bandWidth,a=oo(t.categoryGap,r),o=oo(t.gap,1),s=t.remainedWidth,l=t.autoWidthCount,u=(s-a)/(l+(l-1)*o);u=Math.max(u,0),f(n,function(t){var e=t.maxWidth,i=t.minWidth;if(t.width){var n=t.width;e&&(n=Math.min(n,e)),i&&(n=Math.max(n,i)),t.width=n,s-=n,l--}else{var n=u;e&&n>e&&(n=Math.min(e,s)),i&&i>n&&(n=i),n!==u&&(t.width=n,s-=n,l--)}}),u=(s-a)/(l+(l-1)*o),u=Math.max(u,0);var h,c=0;f(n,function(t){t.width||(t.width=u),h=t,c+=t.width*(1+o)}),h&&(c-=h.width*o);var d=-c/2;f(n,function(t,n){i[e][n]=i[e][n]||{bandWidth:r,offset:d,width:t.width},d+=t.width*(1+o)})}),i}function hh(t,e,i){if(t&&e){var n=t[ah(e)];return null!=n&&null!=i&&(n=n[rh(i)]),n}}function ch(t){return t.coordinateSystem&&"cartesian2d"===t.coordinateSystem.type}function dh(t){return t.pipelineContext&&t.pipelineContext.large}function fh(t,e){return e.toGlobalCoord(e.dataToCoord("log"===e.type?1:0))}function ph(t,e){return jw(t,Yw(e))}function gh(t,e){var i,n,r,a=t.type,o=e.getMin(),s=e.getMax(),l=null!=o,u=null!=s,h=t.getExtent();"ordinal"===a?i=e.getCategories().length:(n=e.get("boundaryGap"),x(n)||(n=[n||0,n||0]),"boolean"==typeof n[0]&&(n=[0,0]),n[0]=oo(n[0],1),n[1]=oo(n[1],1),r=h[1]-h[0]||Math.abs(h[0])),null==o&&(o="ordinal"===a?i?0:0/0:h[0]-n[0]*r),null==s&&(s="ordinal"===a?i?i-1:0/0:h[1]+n[1]*r),"dataMin"===o?o=h[0]:"function"==typeof o&&(o=o({min:h[0],max:h[1]})),"dataMax"===s?s=h[1]:"function"==typeof s&&(s=s({min:h[0],max:h[1]})),(null==o||!isFinite(o))&&(o=0/0),(null==s||!isFinite(s))&&(s=0/0),t.setBlank(T(o)||T(s)||"ordinal"===a&&!t.getOrdinalMeta().categories.length),e.getNeedCrossZero()&&(o>0&&s>0&&!l&&(o=0),0>o&&0>s&&!u&&(s=0));var c=e.ecModel;if(c&&"time"===a){var d,p=oh("bar",c);if(f(p,function(t){d|=t.getBaseAxis()===e.axis}),d){var g=lh(p),v=vh(o,s,e,g);o=v.min,s=v.max}}return[o,s]}function vh(t,e,i,n){var r=i.axis.getExtent(),a=r[1]-r[0],o=hh(n,i.axis);if(void 0===o)return{min:t,max:e};var s=1/0;f(o,function(t){s=Math.min(t.offset,s)});var l=-1/0;f(o,function(t){l=Math.max(t.offset+t.width,l)}),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=1-(s+l)/a,d=h/c-h;return e+=d*(l/u),t-=d*(s/u),{min:t,max:e}}function mh(t,e){var i=gh(t,e),n=null!=e.getMin(),r=null!=e.getMax(),a=e.get("splitNumber");"log"===t.type&&(t.base=e.get("logBase"));var o=t.type;t.setExtent(i[0],i[1]),t.niceExtent({splitNumber:a,fixMin:n,fixMax:r,minInterval:"interval"===o||"time"===o?e.get("minInterval"):null,maxInterval:"interval"===o||"time"===o?e.get("maxInterval"):null});var s=e.get("interval");null!=s&&t.setInterval&&t.setInterval(s)}function yh(t,e){if(e=e||t.get("type"))switch(e){case"category":return new Tw(t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),[1/0,-1/0]);case"value":return new kw;default:return(Zu.getClass(e)||kw).create(t)}}function _h(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(i>0&&n>0||0>i&&0>n)}function xh(t){var e=t.getLabelModel().get("formatter"),i="category"===t.type?t.scale.getExtent()[0]:null;return"string"==typeof e?e=function(e){return function(i){return i=t.scale.getLabel(i),e.replace("{value}",null!=i?i:"")}}(e):"function"==typeof e?function(n,r){return null!=i&&(r=n-i),e(wh(t,n),r)}:function(e){return t.scale.getLabel(e)}}function wh(t,e){return"category"===t.type?t.scale.getLabel(e):e}function bh(t){var e=t.model,i=t.scale;if(e.get("axisLabel.show")&&!i.isBlank()){var n,r,a="category"===t.type,o=i.getExtent();a?r=i.count():(n=i.getTicks(),r=n.length);var s,l=t.getLabelModel(),u=xh(t),h=1;r>40&&(h=Math.ceil(r/40));for(var c=0;r>c;c+=h){var d=n?n[c]:o[0]+c,f=u(d),p=l.getTextRect(f),g=Sh(p,l.get("rotate")||0);s?s.union(g):s=g}return s}}function Sh(t,e){var i=e*Math.PI/180,n=t.plain(),r=n.width,a=n.height,o=r*Math.cos(i)+a*Math.sin(i),s=r*Math.sin(i)+a*Math.cos(i),l=new xi(n.x,n.y,o,s);return l}function Mh(t){var e=t.get("interval");return null==e?"auto":e}function Ih(t){return"category"===t.type&&0===Mh(t.getLabelModel())}function Ch(t,e){if("image"!==this.type){var i=this.style,n=this.shape;n&&"line"===n.symbolType?i.stroke=t:this.__isEmptyBrush?(i.stroke=t,i.fill=e||"#fff"):(i.fill&&(i.fill=t),i.stroke&&(i.stroke=t)),this.dirty(!1)}}function Th(t,e,i,n,r,a,o){var s=0===t.indexOf("empty");s&&(t=t.substr(5,1).toLowerCase()+t.substr(6));var l;return l=0===t.indexOf("image://")?aa(t.slice(8),new xi(e,i,n,r),o?"center":"cover"):0===t.indexOf("path://")?ra(t.slice(7),{},new xi(e,i,n,r),o?"center":"cover"):new sb({shape:{symbolType:t,x:e,y:i,width:n,height:r}}),l.__isEmptyBrush=s,l.setColor=Ch,l.setColor(a),l}function Dh(t){return Yu(t.getSource(),t)}function Ah(t,e){var i=e;Qa.isInstance(e)||(i=new Qa(e),c(i,Jw));var n=yh(i);return n.setExtent(t[0],t[1]),mh(n,i),n}function kh(t){c(t,Jw)}function Ph(t,e){return Math.abs(t-e)>1^-(1&s),l=l>>1^-(1&l),s+=r,l+=a,r=s,a=l,n.push([s/i,l/i])}return n}function Eh(t){return"category"===t.type?Nh(t):Vh(t)}function Rh(t,e){return"category"===t.type?Gh(t,e):{ticks:t.scale.getTicks()}}function Nh(t){var e=t.getLabelModel(),i=Fh(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:i.labelCategoryInterval}:i}function Fh(t,e){var i=Hh(t,"labels"),n=Mh(e),r=Wh(i,n);if(r)return r;var a,o;return w(n)?a=Zh(t,n):(o="auto"===n?Xh(t):n,a=qh(t,o)),Uh(i,n,{labels:a,labelCategoryInterval:o})}function Gh(t,e){var i=Hh(t,"ticks"),n=Mh(e),r=Wh(i,n);if(r)return r;var a,o;if((!e.get("show")||t.scale.isBlank())&&(a=[]),w(n))a=Zh(t,n,!0);else if("auto"===n){var s=Fh(t,t.getLabelModel());o=s.labelCategoryInterval,a=p(s.labels,function(t){return t.tickValue})}else o=n,a=qh(t,o,!0);return Uh(i,n,{ticks:a,tickCategoryInterval:o})}function Vh(t){var e=t.scale.getTicks(),i=xh(t);return{labels:p(e,function(e,n){return{formattedLabel:i(e,n),rawLabel:t.scale.getLabel(e),tickValue:e}})}}function Hh(t,e){return db(t)[e]||(db(t)[e]=[])}function Wh(t,e){for(var i=0;i40&&(s=Math.max(1,Math.floor(o/40)));for(var l=a[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(n)),c=Math.abs(u*Math.sin(n)),d=0,f=0;l<=a[1];l+=s){var p=0,g=0,v=Fi(i(l),e.font,"center","top");p=1.3*v.width,g=1.3*v.height,d=Math.max(d,p,7),f=Math.max(f,g,7)}var m=d/h,y=f/c;isNaN(m)&&(m=1/0),isNaN(y)&&(y=1/0);var _=Math.max(0,Math.floor(Math.min(m,y))),x=db(t.model),w=t.getExtent(),b=x.lastAutoInterval,S=x.lastTickCount;return null!=b&&null!=S&&Math.abs(b-_)<=1&&Math.abs(S-o)<=1&&b>_&&x.axisExtend0===w[0]&&x.axisExtend1===w[1]?_=b:(x.lastTickCount=o,x.lastAutoInterval=_,x.axisExtend0=w[0],x.axisExtend1=w[1]),_}function jh(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}function qh(t,e,i){function n(t){l.push(i?t:{formattedLabel:r(t),rawLabel:a.getLabel(t),tickValue:t})}var r=xh(t),a=t.scale,o=a.getExtent(),s=t.getLabelModel(),l=[],u=Math.max((e||0)+1,1),h=o[0],c=a.count();0!==h&&u>1&&c/u>2&&(h=Math.round(Math.ceil(h/u)*u));var d=Ih(t),f=s.get("showMinLabel")||d,p=s.get("showMaxLabel")||d;f&&h!==o[0]&&n(o[0]);for(var g=h;g<=o[1];g+=u)n(g);return p&&g-u!==o[1]&&n(o[1]),l}function Zh(t,e,i){var n=t.scale,r=xh(t),a=[];return f(n.getTicks(),function(t){var o=n.getLabel(t);e(t,o)&&a.push(i?t:{formattedLabel:r(t),rawLabel:o,tickValue:t})}),a}function Kh(t,e){var i=t[1]-t[0],n=e,r=i/n/2;t[0]+=r,t[1]-=r}function $h(t,e,i,n){function r(t,e){return t=so(t),e=so(e),d?t>e:e>t}var a=e.length;if(t.onBand&&!i&&a){var o,s,l=t.getExtent();if(1===a)e[0].coord=l[0],o=e[1]={coord:l[0]};else{var u=e[a-1].tickValue-e[0].tickValue,h=(e[a-1].coord-e[0].coord)/u;f(e,function(t){t.coord-=h/2});var c=t.scale.getExtent();s=1+c[1]-e[a-1].tickValue,o={coord:e[a-1].coord+h*s},e.push(o)}var d=l[0]>l[1];r(e[0].coord,l[0])&&(n?e[0].coord=l[0]:e.shift()),n&&r(l[0],e[0].coord)&&e.unshift({coord:l[0]}),r(l[1],o.coord)&&(n?o.coord=l[1]:e.pop()),n&&r(o.coord,l[1])&&e.push({coord:l[1]})}}function Qh(t,e){var i=t.mapDimension("defaultedLabel",!0),n=i.length;if(1===n)return Es(t,e,i[0]);if(n){for(var r=[],a=0;a0?i=n[0]:n[1]<0&&(i=n[1]),i}function uc(t,e,i,n){var r=0/0;t.stacked&&(r=i.get(i.getCalculationInfo("stackedOverDimension"),n)),isNaN(r)&&(r=t.valueStart);var a=t.baseDataOffset,o=[];return o[a]=i.get(t.baseDim,n),o[1-a]=r,e.dataToPoint(o)}function hc(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}function cc(t){return isNaN(t[0])||isNaN(t[1])}function dc(t,e,i,n,r,a,o,s,l,u){return"none"!==u&&u?fc.apply(this,arguments):pc.apply(this,arguments)}function fc(t,e,i,n,r,a,o,s,l,u,h){for(var c=0,d=i,f=0;n>f;f++){var p=e[d];if(d>=r||0>d)break;if(cc(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]);else if(l>0){var g=e[c],v="y"===u?1:0,m=(p[v]-g[v])*l;Ab(Pb,g),Pb[v]=g[v]+m,Ab(Lb,p),Lb[v]=p[v]-m,t.bezierCurveTo(Pb[0],Pb[1],Lb[0],Lb[1],p[0],p[1])}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function pc(t,e,i,n,r,a,o,s,l,u,h){for(var c=0,d=i,f=0;n>f;f++){var p=e[d];if(d>=r||0>d)break;if(cc(p)){if(h){d+=a;continue}break}if(d===i)t[a>0?"moveTo":"lineTo"](p[0],p[1]),Ab(Pb,p);else if(l>0){var g=d+a,v=e[g];if(h)for(;v&&cc(e[g]);)g+=a,v=e[g];var m=.5,y=e[c],v=e[g];if(!v||cc(v))Ab(Lb,p);else{cc(v)&&!h&&(v=p),j(kb,v,y);var _,x;if("x"===u||"y"===u){var w="x"===u?0:1;_=Math.abs(p[w]-y[w]),x=Math.abs(p[w]-v[w])}else _=Op(p,y),x=Op(p,v);m=x/(x+_),Db(Lb,p,kb,-l*(1-m))}Cb(Pb,Pb,s),Tb(Pb,Pb,o),Cb(Lb,Lb,s),Tb(Lb,Lb,o),t.bezierCurveTo(Pb[0],Pb[1],Lb[0],Lb[1],p[0],p[1]),Db(Pb,p,kb,l*m)}else t.lineTo(p[0],p[1]);c=d,d+=a}return f}function gc(t,e){var i=[1/0,1/0],n=[-1/0,-1/0];if(e)for(var r=0;rn[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}function vc(t,e,i){var n=t.getArea(),r=t.getBaseAxis().isHorizontal(),a=n.x,o=n.y,s=n.width,l=n.height,u=i.get("lineStyle.width")||2;a-=u/2,o-=u/2,s+=u,l+=u;var h=new ty({shape:{x:a,y:o,width:s,height:l}});return e&&(h.shape[r?"width":"height"]=0,Ga(h,{shape:{width:s,height:l}},i)),h}function mc(t,e,i){var n=t.getArea(),r=new Ym({shape:{cx:so(t.cx,1),cy:so(t.cy,1),r0:so(n.r0,1),r:so(n.r,1),startAngle:n.startAngle,endAngle:n.endAngle,clockwise:n.clockwise}});return e&&(r.shape.endAngle=n.startAngle,Ga(r,{shape:{endAngle:n.endAngle}},i)),r}function yc(t,e){if(t.length===e.length){for(var i=0;ir;r++)n.push(uc(i,t,e,r));return n}function wc(t,e,i){for(var n=e.getBaseAxis(),r="x"===n.dim||"radius"===n.dim?0:1,a=[],o=0;o=0;a--){var o=i[a].dimension,s=t.dimensions[o],l=t.getDimensionInfo(s);if(n=l&&l.coordDim,"x"===n||"y"===n){r=i[a];break}}if(r){var u=e.getAxis(n),h=p(r.stops,function(t){return{coord:u.toGlobalCoord(u.dataToCoord(t.value)),color:t.color}}),c=h.length,d=r.outerColors.slice();c&&h[0].coord>h[c-1].coord&&(h.reverse(),d.reverse());var g=10,v=h[0].coord-g,m=h[c-1].coord+g,y=m-v;if(.001>y)return"transparent";f(h,function(t){t.offset=(t.coord-v)/y}),h.push({offset:c?h[c-1].offset:.5,color:d[1]||"transparent"}),h.unshift({offset:c?h[0].offset:.5,color:d[0]||"transparent"});var _=new ly(0,0,0,0,h,!0);return _[n]=v,_[n+"2"]=m,_}}}function Sc(t,e,i){var n=t.get("showAllSymbol"),r="auto"===n;if(!n||r){var a=i.getAxesByScale("ordinal")[0];if(a&&(!r||!Mc(a,e))){var o=e.mapDimension(a.dim),s={};return f(a.getViewLabels(),function(t){s[t.tickValue]=1}),function(t){return!s.hasOwnProperty(e.get(o,t))}}}}function Mc(t,e){var i=t.getExtent(),n=Math.abs(i[1]-i[0])/t.scale.count();isNaN(n)&&(n=0);for(var r=e.count(),a=Math.max(1,Math.round(r/5)),o=0;r>o;o+=a)if(1.5*Jh.getSymbolSize(e,o)[t.isHorizontal()?1:0]>n)return!1;return!0}function Ic(t,e,i){if("cartesian2d"===t.type){var n=t.getBaseAxis().isHorizontal(),r=vc(t,e,i);if(!i.get("clip",!0)){var a=r.shape,o=Math.max(a.width,a.height);n?(a.y-=o,a.height+=2*o):(a.x-=o,a.width+=2*o)}return r}return mc(t,e,i)}function Cc(t){return this._axes[t]}function Tc(t){Gb.call(this,t)}function Dc(t,e){return e.type||(e.data?"category":"value")}function Ac(t,e){return t.getCoordSysModel()===e}function kc(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this.model=t}function Pc(t,e,i,n){function r(t){return t.dim+"_"+t.index}i.getAxesOnZeroOf=function(){return a?[a]:[]};var a,o=t[e],s=i.model,l=s.get("axisLine.onZero"),u=s.get("axisLine.onZeroAxisIndex");if(l){if(null!=u)Lc(o[u])&&(a=o[u]);else for(var h in o)if(o.hasOwnProperty(h)&&Lc(o[h])&&!n[r(o[h])]){a=o[h];break}a&&(n[r(a)]=!0)}}function Lc(t){return t&&"category"!==t.type&&"time"!==t.type&&_h(t)}function Oc(t,e){var i=t.getExtent(),n=i[0]+i[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return n-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return n-t+e}}function zc(t){return p(Zb,function(e){var i=t.getReferringComponents(e)[0];return i})}function Bc(t){return"cartesian2d"===t.get("coordinateSystem")}function Ec(t,e,i,n){var r,a,o=po(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return go(o-Kb/2)?(a=l?"bottom":"top",r="center"):go(o-1.5*Kb)?(a=l?"top":"bottom",r="center"):(a="middle",r=1.5*Kb>o&&o>Kb/2?l?"left":"right":l?"right":"left"),{rotation:o,textAlign:r,textVerticalAlign:a}}function Rc(t,e,i){if(!Ih(t.axis)){var n=t.get("axisLabel.showMinLabel"),r=t.get("axisLabel.showMaxLabel");e=e||[],i=i||[];var a=e[0],o=e[1],s=e[e.length-1],l=e[e.length-2],u=i[0],h=i[1],c=i[i.length-1],d=i[i.length-2];n===!1?(Nc(a),Nc(u)):Fc(a,o)&&(n?(Nc(o),Nc(h)):(Nc(a),Nc(u))),r===!1?(Nc(s),Nc(c)):Fc(l,s)&&(r?(Nc(l),Nc(d)):(Nc(s),Nc(c)))}}function Nc(t){t&&(t.ignore=!0)}function Fc(t,e){var i=t&&t.getBoundingRect().clone(),n=e&&e.getBoundingRect().clone();if(i&&n){var r=De([]);return Le(r,r,-t.rotation),i.applyTransform(ke([],r,t.getLocalTransform())),n.applyTransform(ke([],r,e.getLocalTransform())),i.intersect(n)}}function Gc(t){return"middle"===t||"center"===t}function Vc(t,e,i){var n=e.axis;if(e.get("axisTick.show")&&!n.scale.isBlank()){for(var r=e.getModel("axisTick"),a=r.getModel("lineStyle"),o=r.get("length"),l=n.getTicksCoords(),u=[],h=[],c=t._transform,d=[],f=0;f=0||t===e}function Zc(t){var e=Kc(t);if(e){var i=e.axisPointerModel,n=e.axis.scale,r=i.option,a=i.get("status"),o=i.get("value");null!=o&&(o=n.parse(o));var s=Qc(i);null==a&&(r.status=s?"show":"hide");var l=n.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==o||o>l[1])&&(o=l[1]),o=f&&((o>f||d>=0&&0>s)&&(o=f,s=d,r=l,a.length=0),SS(u,function(t){a.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})}))}}),{payloadBatch:a,snapToValue:r}}function dd(t,e,i,n){t[e.key]={value:i,payloadBatch:n}}function fd(t,e,i,n){var r=i.payloadBatch,a=e.axis,o=a.model,s=e.axisPointerModel;if(e.triggerTooltip&&r.length){var l=e.coordSys.model,u=Jc(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:a.dim,axisIndex:o.componentIndex,axisType:o.type,axisId:o.id,value:n,valueLabelOpt:{precision:s.get("label.precision"),formatter:s.get("label.formatter")},seriesDataIndices:r.slice()})}}function pd(t,e,i){var n=i.axesInfo=[];SS(e,function(e,i){var r=e.axisPointerModel.option,a=t[i];a?(!e.useHandle&&(r.status="show"),r.value=a.value,r.seriesDataIndices=(a.payloadBatch||[]).slice()):!e.useHandle&&(r.status="hide"),"show"===r.status&&n.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:r.value})})}function gd(t,e,i,n){if(_d(e)||!t.list.length)return void n({type:"hideTip"});var r=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};n({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:i.tooltipOption,position:i.position,dataIndexInside:r.dataIndexInside,dataIndex:r.dataIndex,seriesIndex:r.seriesIndex,dataByCoordSys:t.list})}function vd(t,e,i){var n=i.getZr(),r="axisPointerLastHighlights",a=IS(n)[r]||{},o=IS(n)[r]={};SS(t,function(t){var e=t.axisPointerModel.option;"show"===e.status&&SS(e.seriesDataIndices,function(t){var e=t.seriesIndex+" | "+t.dataIndex;o[e]=t})});var s=[],l=[];f(a,function(t,e){!o[e]&&l.push(t)}),f(o,function(t,e){!a[e]&&s.push(t)}),l.length&&i.dispatchAction({type:"downplay",escapeConnect:!0,batch:l}),s.length&&i.dispatchAction({type:"highlight",escapeConnect:!0,batch:s})}function md(t,e){for(var i=0;i<(t||[]).length;i++){var n=t[i];if(e.axis.dim===n.axisDim&&e.axis.model.componentIndex===n.axisIndex)return n}}function yd(t){var e=t.axis.model,i={},n=i.axisDim=t.axis.dim;return i.axisIndex=i[n+"AxisIndex"]=e.componentIndex,i.axisName=i[n+"AxisName"]=e.name,i.axisId=i[n+"AxisId"]=e.id,i}function _d(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function xd(t,e,i){if(!gp.node){var n=e.getZr();TS(n).records||(TS(n).records={}),wd(n,e);var r=TS(n).records[t]||(TS(n).records[t]={});r.handler=i}}function wd(t,e){function i(i,n){t.on(i,function(i){var r=Id(e);DS(TS(t).records,function(t){t&&n(t,i,r.dispatchAction)}),bd(r.pendings,e)})}TS(t).initialized||(TS(t).initialized=!0,i("click",_(Md,"click")),i("mousemove",_(Md,"mousemove")),i("globalout",Sd))}function bd(t,e){var i,n=t.showTip.length,r=t.hideTip.length;n?i=t.showTip[n-1]:r&&(i=t.hideTip[r-1]),i&&(i.dispatchAction=null,e.dispatchAction(i))}function Sd(t,e,i){t.handler("leave",null,i)}function Md(t,e,i,n){e.handler(t,i,n)}function Id(t){var e={showTip:[],hideTip:[]},i=function(n){var r=e[n.type];r?r.push(n):(n.dispatchAction=i,t.dispatchAction(n))};return{dispatchAction:i,pendings:e}}function Cd(t,e){if(!gp.node){var i=e.getZr(),n=(TS(i).records||{})[t];n&&(TS(i).records[t]=null)}}function Td(){}function Dd(t,e,i,n){Ad(kS(i).lastProp,n)||(kS(i).lastProp=n,e?Fa(i,n,t):(i.stopAnimation(),i.attr(n)))}function Ad(t,e){if(S(t)&&S(e)){var i=!0;return f(e,function(e,n){i=i&&Ad(t[n],e)}),!!i}return t===e}function kd(t,e){t[e.get("label.show")?"show":"hide"]()}function Pd(t){return{position:t.position.slice(),rotation:t.rotation||0}}function Ld(t,e,i){var n=e.get("z"),r=e.get("zlevel");t&&t.traverse(function(t){"group"!==t.type&&(null!=n&&(t.z=n),null!=r&&(t.zlevel=r),t.silent=i)})}function Od(t){var e,i=t.get("type"),n=t.getModel(i+"Style");return"line"===i?(e=n.getLineStyle(),e.fill=null):"shadow"===i&&(e=n.getAreaStyle(),e.stroke=null),e}function zd(t,e,i,n,r){var a=i.get("value"),o=Ed(a,e.axis,e.ecModel,i.get("seriesDataIndices"),{precision:i.get("label.precision"),formatter:i.get("label.formatter")}),s=i.getModel("label"),l=Ry(s.get("padding")||0),u=s.getFont(),h=Fi(o,u),c=r.position,d=h.width+l[1]+l[3],f=h.height+l[0]+l[2],p=r.align;"right"===p&&(c[0]-=d),"center"===p&&(c[0]-=d/2);var g=r.verticalAlign;"bottom"===g&&(c[1]-=f),"middle"===g&&(c[1]-=f/2),Bd(c,d,f,n);var v=s.get("backgroundColor");v&&"auto"!==v||(v=e.get("axisLine.lineStyle.color")),t.label={shape:{x:0,y:0,width:d,height:f,r:s.get("borderRadius")},position:c.slice(),style:{text:o,textFont:u,textFill:s.getTextColor(),textPosition:"inside",textPadding:l,fill:v,stroke:s.get("borderColor")||"transparent",lineWidth:s.get("borderWidth")||0,shadowBlur:s.get("shadowBlur"),shadowColor:s.get("shadowColor"),shadowOffsetX:s.get("shadowOffsetX"),shadowOffsetY:s.get("shadowOffsetY")},z2:10}}function Bd(t,e,i,n){var r=n.getWidth(),a=n.getHeight();t[0]=Math.min(t[0]+e,r)-e,t[1]=Math.min(t[1]+i,a)-i,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}function Ed(t,e,i,n,r){t=e.scale.parse(t);var a=e.scale.getLabel(t,{precision:r.precision}),o=r.formatter;if(o){var s={value:wh(e,t),axisDimension:e.dim,axisIndex:e.index,seriesData:[]};f(n,function(t){var e=i.getSeriesByIndex(t.seriesIndex),n=t.dataIndexInside,r=e&&e.getDataParams(n);r&&s.seriesData.push(r)}),b(o)?a=o.replace("{value}",a):w(o)&&(a=o(s))}return a}function Rd(t,e,i){var n=Te();return Le(n,n,i.rotation),Pe(n,n,i.position),Ha([t.dataToCoord(e),(i.labelOffset||0)+(i.labelDirection||1)*(i.labelMargin||0)],n)}function Nd(t,e,i,n,r,a){var o=$b.innerTextLayout(i.rotation,0,i.labelDirection);i.labelMargin=r.get("label.margin"),zd(e,n,r,a,{position:Rd(n.axis,t,i),align:o.textAlign,verticalAlign:o.textVerticalAlign})}function Fd(t,e,i){return i=i||0,{x1:t[i],y1:t[1-i],x2:e[i],y2:e[1-i]}}function Gd(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}function Vd(t,e){var i={};return i[e.dim+"AxisIndex"]=e.index,t.getCartesian(i)}function Hd(t){return"x"===t.dim?0:1}function Wd(t){var e="cubic-bezier(0.23, 1, 0.32, 1)",i="left "+t+"s "+e+",top "+t+"s "+e;return p(RS,function(t){return t+"transition:"+i}).join(";")}function Ud(t){var e=[],i=t.get("fontSize"),n=t.getTextColor();return n&&e.push("color:"+n),e.push("font:"+t.getFont()),i&&e.push("line-height:"+Math.round(3*i/2)+"px"),BS(["decoration","align"],function(i){var n=t.get(i);n&&e.push("text-"+i+":"+n)}),e.join(";")}function Xd(t){var e=[],i=t.get("transitionDuration"),n=t.get("backgroundColor"),r=t.getModel("textStyle"),a=t.get("padding");return i&&e.push(Wd(i)),n&&(gp.canvasSupported?e.push("background-Color:"+n):(e.push("background-Color:#"+Qe(n)),e.push("filter:alpha(opacity=70)"))),BS(["width","color","radius"],function(i){var n="border-"+i,r=ES(n),a=t.get(r);null!=a&&e.push(n+":"+a+("color"===i?"":"px"))}),e.push(Ud(r)),null!=a&&e.push("padding:"+Ry(a).join("px ")+"px"),e.join(";")+";"}function Yd(t,e){if(gp.wxa)return null;var i=document.createElement("div"),n=this._zr=e.getZr();this.el=i,this._x=e.getWidth()/2,this._y=e.getHeight()/2,t.appendChild(i),this._container=t,this._show=!1,this._hideTimeout;var r=this;i.onmouseenter=function(){r._enterable&&(clearTimeout(r._hideTimeout),r._show=!0),r._inContent=!0},i.onmousemove=function(e){if(e=e||window.event,!r._enterable){var i=n.handler;ye(t,e,!0),i.dispatch("mousemove",e)}},i.onmouseleave=function(){r._enterable&&r._show&&r.hideLater(r._hideDelay),r._inContent=!1}}function jd(t){this._zr=t.getZr(),this._show=!1,this._hideTimeout}function qd(t){for(var e=t.pop();t.length;){var i=t.pop();i&&(Qa.isInstance(i)&&(i=i.get("tooltip",!0)),"string"==typeof i&&(i={formatter:i}),e=new Qa(i,e,e.ecModel))}return e}function Zd(t,e){return t.dispatchAction||y(e.dispatchAction,e)}function Kd(t,e,i,n,r,a,o){var s=i.getOuterSize(),l=s.width,u=s.height;return null!=a&&(t+l+a>n?t-=l+a:t+=a),null!=o&&(e+u+o>r?e-=u+o:e+=o),[t,e]}function $d(t,e,i,n,r){var a=i.getOuterSize(),o=a.width,s=a.height;return t=Math.min(t+o,n)-o,e=Math.min(e+s,r)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function Qd(t,e,i){var n=i[0],r=i[1],a=5,o=0,s=0,l=e.width,u=e.height;switch(t){case"inside":o=e.x+l/2-n/2,s=e.y+u/2-r/2;break;case"top":o=e.x+l/2-n/2,s=e.y-r-a;break;case"bottom":o=e.x+l/2-n/2,s=e.y+u+a;break;case"left":o=e.x-n-a,s=e.y+u/2-r/2;break;case"right":o=e.x+l+a,s=e.y+u/2-r/2}return[o,s]}function Jd(t){return"center"===t||"middle"===t}function tf(t){Gn(t,"label",["show"])}function ef(t){return!(isNaN(parseFloat(t.x))&&isNaN(parseFloat(t.y)))}function nf(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}function rf(t,e,i,n,r,a){var o=[],s=Uu(e,n),l=s?e.getCalculationInfo("stackResultDimension"):n,u=hf(e,l,t),h=e.indicesOfNearest(l,u)[0];o[r]=e.get(i,h),o[a]=e.get(n,h);var c=uo(e.get(n,h));return c=Math.min(c,20),c>=0&&(o[a]=+o[a].toFixed(c)),o}function af(t,e){var i=t.getData(),r=t.coordinateSystem;if(e&&!nf(e)&&!x(e.coord)&&r){var a=r.dimensions,o=of(e,i,r,t);if(e=n(e),e.type&&qS[e.type]&&o.baseAxis&&o.valueAxis){var s=YS(a,o.baseAxis.dim),l=YS(a,o.valueAxis.dim);e.coord=qS[e.type](i,o.baseDataDim,o.valueDataDim,s,l),e.value=e.coord[l]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;2>h;h++)qS[u[h]]&&(u[h]=hf(i,i.mapDimension(a[h]),u[h]));e.coord=u}}return e}function of(t,e,i,n){var r={};return null!=t.valueIndex||null!=t.valueDim?(r.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,r.valueAxis=i.getAxis(sf(n,r.valueDataDim)),r.baseAxis=i.getOtherAxis(r.valueAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim)):(r.baseAxis=n.getBaseAxis(),r.valueAxis=i.getOtherAxis(r.baseAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim),r.valueDataDim=e.mapDimension(r.valueAxis.dim)),r}function sf(t,e){var i=t.getData(),n=i.dimensions;e=i.getDimension(e);for(var r=0;rn?t.coord&&t.coord[n]:t.value}function hf(t,e,i){if("average"===i){var n=0,r=0;return t.each(e,function(t){isNaN(t)||(n+=t,r++)}),n/r}return"median"===i?t.getMedian(e):t.getDataExtent(e,!0)["max"===i?1:0]}function cf(t){return isNaN(+t.cpx1)||isNaN(+t.cpy1)}function df(t){return"_"+t+"Type"}function ff(t,e,i){var n=e.getItemVisual(i,"color"),r=e.getItemVisual(i,t),a=e.getItemVisual(i,t+"Size");if(r&&"none"!==r){x(a)||(a=[a,a]);var o=Th(r,-a[0]/2,-a[1]/2,a[0],a[1],n);return o.name=t,o}}function pf(t){var e=new $S({name:"line",subPixelOptimize:!0});return gf(e.shape,t),e}function gf(t,e){t.x1=e[0][0],t.y1=e[0][1],t.x2=e[1][0],t.y2=e[1][1],t.percent=1;var i=e[2];i?(t.cpx1=i[0],t.cpy1=i[1]):(t.cpx1=0/0,t.cpy1=0/0)}function vf(){var t=this,e=t.childOfName("fromSymbol"),i=t.childOfName("toSymbol"),n=t.childOfName("label");if(e||i||!n.ignore){for(var r=1,a=this.parent;a;)a.scale&&(r/=a.scale[0]),a=a.parent;var o=t.childOfName("line");if(this.__dirty||o.__dirty){var s=o.shape.percent,l=o.pointAt(0),u=o.pointAt(s),h=j([],u,l);if(te(h,h),e){e.attr("position",l);var c=o.tangentAt(0);e.attr("rotation",Math.PI/2-Math.atan2(c[1],c[0])),e.attr("scale",[r*s,r*s])}if(i){i.attr("position",u);var c=o.tangentAt(1);i.attr("rotation",-Math.PI/2-Math.atan2(c[1],c[0])),i.attr("scale",[r*s,r*s])}if(!n.ignore){n.attr("position",u);var d,f,p,g=5*r;if("end"===n.__position)d=[h[0]*g+u[0],h[1]*g+u[1]],f=h[0]>.8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";else if("middle"===n.__position){var v=s/2,c=o.tangentAt(v),m=[c[1],-c[0]],y=o.pointAt(v);m[1]>0&&(m[0]=-m[0],m[1]=-m[1]),d=[y[0]+m[0]*g,y[1]+m[1]*g],f="center",p="bottom";var _=-Math.atan2(c[1],c[0]);u[0].8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";n.attr({style:{textVerticalAlign:n.__verticalAlign||p,textAlign:n.__textAlign||f},position:d,scale:[r,r]})}}}}function mf(t,e,i){Dg.call(this),this._createLine(t,e,i)}function yf(t){this._ctor=t||mf,this.group=new Dg}function _f(t,e,i,n){var r=e.getItemLayout(i);if(Sf(r)){var a=new t._ctor(e,i,n);e.setItemGraphicEl(i,a),t.group.add(a)}}function xf(t,e,i,n,r,a){var o=e.getItemGraphicEl(n);return Sf(i.getItemLayout(r))?(o?o.updateData(i,r,a):o=new t._ctor(i,r,a),i.setItemGraphicEl(r,o),void t.group.add(o)):void t.group.remove(o)}function wf(t){var e=t.hostModel;return{lineStyle:e.getModel("lineStyle").getLineStyle(),hoverLineStyle:e.getModel("emphasis.lineStyle").getLineStyle(),labelModel:e.getModel("label"),hoverLabelModel:e.getModel("emphasis.label")}}function bf(t){return isNaN(t[0])||isNaN(t[1])}function Sf(t){return!bf(t[0])&&!bf(t[1])}function Mf(t){return!isNaN(t)&&!isFinite(t)}function If(t,e,i,n){var r=1-t,a=n.dimensions[t];return Mf(e[r])&&Mf(i[r])&&e[t]===i[t]&&n.getAxis(a).containData(e[t])}function Cf(t,e){if("cartesian2d"===t.type){var i=e[0].coord,n=e[1].coord;if(i&&n&&(If(1,i,n,t)||If(0,i,n,t)))return!0}return lf(t,e[0])&&lf(t,e[1])}function Tf(t,e,i,n,r){var a,o=n.coordinateSystem,s=t.getItemModel(e),l=oo(s.get("x"),r.getWidth()),u=oo(s.get("y"),r.getHeight());if(isNaN(l)||isNaN(u)){if(n.getMarkerPosition)a=n.getMarkerPosition(t.getValues(t.dimensions,e));else{var h=o.dimensions,c=t.get(h[0],e),d=t.get(h[1],e);a=o.dataToPoint([c,d])}if("cartesian2d"===o.type){var f=o.getAxis("x"),p=o.getAxis("y"),h=o.dimensions;Mf(t.get(h[0],e))?a[0]=f.toGlobalCoord(f.getExtent()[i?0:1]):Mf(t.get(h[1],e))&&(a[1]=p.toGlobalCoord(p.getExtent()[i?0:1]))}isNaN(l)||(a[0]=l),isNaN(u)||(a[1]=u)}else a=[l,u];t.setItemLayout(e,a)}function Df(t,e,i){var n;n=t?p(t&&t.dimensions,function(t){var i=e.getData().getDimensionInfo(e.getData().mapDimension(t))||{};return s({name:t},i)}):[{name:"value",type:"float"}];var r=new ww(n,i),a=new ww(n,i),o=new ww([],i),l=p(i.get("data"),_(iM,e,t,i));t&&(l=v(l,_(Cf,t)));var u=t?uf:function(t){return t.value};return r.initData(p(l,function(t){return t[0]}),null,u),a.initData(p(l,function(t){return t[1]}),null,u),o.initData(p(l,function(t){return t[2]})),o.hasItemOption=!0,{from:r,to:a,line:o}}function Af(t){var e=t.type,i={number:"value",time:"time"};if(i[e]&&(t.axisType=i[e],delete t.type),kf(t),Pf(t,"controlPosition")){var n=t.controlStyle||(t.controlStyle={});Pf(n,"position")||(n.position=t.controlPosition),"none"!==n.position||Pf(n,"show")||(n.show=!1,delete n.position),delete t.controlPosition}f(t.data||[],function(t){S(t)&&!x(t)&&(!Pf(t,"value")&&Pf(t,"name")&&(t.value=t.name),kf(t))})}function kf(t){var e=t.itemStyle||(t.itemStyle={}),i=e.emphasis||(e.emphasis={}),n=t.label||t.label||{},r=n.normal||(n.normal={}),a={normal:1,emphasis:1};f(n,function(t,e){a[e]||Pf(r,e)||(r[e]=t)}),i.label&&!Pf(n,"emphasis")&&(n.emphasis=i.label,delete i.label)}function Pf(t,e){return t.hasOwnProperty(e)}function Lf(t,e){return Bo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()},t.get("padding"))}function Of(t,e,i,r){var a=ra(t.get(e).replace(/^path:\/\//,""),n(r||{}),new xi(i[0],i[1],i[2],i[3]),"center");return a}function zf(t,e,i,n,a,o){var s=e.get("color");if(a)a.setColor(s),i.add(a),o&&o.onUpdate(a);else{var l=t.get("symbol");a=Th(l,-1,-1,2,2,s),a.setStyle("strokeNoScale",!0),i.add(a),o&&o.onCreate(a)}var u=e.getItemStyle(["color","symbol","symbolSize"]);a.setStyle(u),n=r({rectHover:!0,z2:100},n,!0);var h=t.get("symbolSize");h=h instanceof Array?h.slice():[+h,+h],h[0]/=2,h[1]/=2,n.scale=h;var c=t.get("symbolOffset");if(c){var d=n.position=n.position||[0,0];d[0]+=oo(c[0],h[0]),d[1]+=oo(c[1],h[1])}var f=t.get("symbolRotate");return n.rotation=(f||0)*Math.PI/180||0,a.attr(n),a.updateTransform(),a}function Bf(t,e,i,n,r){if(!t.dragging){var a=n.getModel("checkpointStyle"),o=i.dataToCoord(n.getData().get(["value"],e));r||!a.get("animation",!0)?t.attr({position:[o,0]}):(t.stopAnimation(!0),t.animateTo({position:[o,0]},a.get("animationDuration",!0),a.get("animationEasing",!0)))}}function Ef(t){return document.createElementNS(cM,t)}function Rf(t){return gM(1e4*t)/1e4}function Nf(t){return wM>t&&t>-wM}function Ff(t,e){var i=e?t.textFill:t.fill;return null!=i&&i!==pM}function Gf(t,e){var i=e?t.textStroke:t.stroke;return null!=i&&i!==pM}function Vf(t,e){e&&Hf(t,"transform","matrix("+fM.call(e,",")+")")}function Hf(t,e,i){(!i||"linear"!==i.type&&"radial"!==i.type)&&t.setAttribute(e,i)}function Wf(t,e,i){t.setAttributeNS("http://www.w3.org/1999/xlink",e,i)}function Uf(t,e,i,n){if(Ff(e,i)){var r=i?e.textFill:e.fill;r="transparent"===r?pM:r,Hf(t,"fill",r),Hf(t,"fill-opacity",null!=e.fillOpacity?e.fillOpacity*e.opacity:e.opacity)}else Hf(t,"fill",pM);if(Gf(e,i)){var a=i?e.textStroke:e.stroke;a="transparent"===a?pM:a,Hf(t,"stroke",a);var o=i?e.textStrokeWidth:e.lineWidth,s=!i&&e.strokeNoScale?n.getLineScale():1;Hf(t,"stroke-width",o/s),Hf(t,"paint-order",i?"stroke":"fill"),Hf(t,"stroke-opacity",null!=e.strokeOpacity?e.strokeOpacity:e.opacity);var l=e.lineDash;l?(Hf(t,"stroke-dasharray",e.lineDash.join(",")),Hf(t,"stroke-dashoffset",gM(e.lineDashOffset||0))):Hf(t,"stroke-dasharray",""),e.lineCap&&Hf(t,"stroke-linecap",e.lineCap),e.lineJoin&&Hf(t,"stroke-linejoin",e.lineJoin),e.miterLimit&&Hf(t,"stroke-miterlimit",e.miterLimit)}else Hf(t,"stroke",pM)}function Xf(t){for(var e=[],i=t.data,n=t.len(),r=0;n>r;){var a=i[r++],o="",s=0;switch(a){case dM.M:o="M",s=2;break;case dM.L:o="L",s=2;break;case dM.Q:o="Q",s=4;break;case dM.C:o="C",s=6;break;case dM.A:var l=i[r++],u=i[r++],h=i[r++],c=i[r++],d=i[r++],f=i[r++],p=i[r++],g=i[r++],v=Math.abs(f),m=Nf(v-_M)||(g?f>=_M:-f>=_M),y=f>0?f%_M:f%_M+_M,_=!1;_=m?!0:Nf(v)?!1:y>=yM==!!g;var x=Rf(l+h*mM(d)),w=Rf(u+c*vM(d));m&&(f=g?_M-1e-4:-_M+1e-4,_=!0,9===r&&e.push("M",x,w));var b=Rf(l+h*mM(d+f)),S=Rf(u+c*vM(d+f));e.push("A",Rf(h),Rf(c),gM(p*xM),+_,+g,b,S);break;case dM.Z:o="Z";break;case dM.R:var b=Rf(i[r++]),S=Rf(i[r++]),M=Rf(i[r++]),I=Rf(i[r++]);e.push("M",b,S,"L",b+M,S,"L",b+M,S+I,"L",b,S+I,"L",b,S)}o&&e.push(o);for(var C=0;s>C;C++)e.push(Rf(i[r++]))}return e.join(" ")}function Yf(t,e,i,n,r,a,o){De(TM),e&&i&&Ae(TM,i);var s=n.textRotation;if(r&&s){var l=n.textOrigin;"center"===l?(a=r.width/2+r.x,o=r.height/2+r.y):l&&(a=l[0]+r.x,o=l[1]+r.y),TM[4]-=a,TM[5]-=o,Le(TM,TM,s),TM[4]+=a,TM[5]+=o}Vf(t,TM)}function jf(t,e,i){return"right"===e?t-i[1]:"center"===e?t+i[3]/2-i[1]/2:t+i[3]}function qf(t,e,i,n){Hf(t,"dominant-baseline","middle"),Hf(t,"text-anchor",DM[e]),Hf(t,"x",i),Hf(t,"y",n)}function Zf(){}function Kf(t,e){for(var i=0,n=e.length,r=0,a=0;n>i;i++){var o=e[i];if(o.removed){for(var s=[],l=a;lr;r++)i[t][r].h!==e&&n.push(i[t][r]);i[t]=n}i[t]&&0===i[t].length&&delete i[t]}else delete i[t];return this},trigger:function(t){var e=this._$handlers[t],i=this._$eventProcessor;if(e){var n=arguments,r=n.length;r>3&&(n=Ep.call(n,1));for(var a=e.length,o=0;a>o;){var s=e[o];if(i&&i.filter&&null!=s.query&&!i.filter(t,s.query))o++;else{switch(r){case 1:s.h.call(s.ctx);break;case 2:s.h.call(s.ctx,n[1]);break;case 3:s.h.call(s.ctx,n[1],n[2]);break;default:s.h.apply(s.ctx,n)}s.one?(e.splice(o,1),a--):o++}}}return i&&i.afterTrigger&&i.afterTrigger(t),this},triggerWithContext:function(t){var e=this._$handlers[t],i=this._$eventProcessor;if(e){var n=arguments,r=n.length;r>4&&(n=Ep.call(n,1,n.length-1));for(var a=n[n.length-1],o=e.length,s=0;o>s;){var l=e[s];if(i&&i.filter&&null!=l.query&&!i.filter(t,l.query))s++;else{switch(r){case 1:l.h.call(a);break;case 2:l.h.call(a,n[1]);break;case 3:l.h.call(a,n[1],n[2]);break;default:l.h.apply(a,n)}l.one?(e.splice(s,1),o--):s++}}}return i&&i.afterTrigger&&i.afterTrigger(t),this}};var Np=Math.log(2),Fp="undefined"!=typeof window&&!!window.addEventListener,Gp=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Vp="___zrEVENTSAVED",Hp=[],Wp=Fp?function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0}:function(t){t.returnValue=!1,t.cancelBubble=!0},Up=function(){this._track=[]};Up.prototype={constructor:Up,recognize:function(t,e,i){return this._doTrack(t,e,i),this._recognize(t)},clear:function(){return this._track.length=0,this},_doTrack:function(t,e,i){var n=t.touches;if(n){for(var r={points:[],touches:[],target:e,event:t},a=0,o=n.length;o>a;a++){var s=n[a],l=pe(i,s,{});r.points.push([l.zrX,l.zrY]),r.touches.push(s)}this._track.push(r)}},_recognize:function(t){for(var e in Xp)if(Xp.hasOwnProperty(e)){var i=Xp[e](this._track,t);if(i)return i}}};var Xp={pinch:function(t,e){var i=t.length;if(i){var n=(t[i-1]||{}).points,r=(t[i-2]||{}).points||n;if(r&&r.length>1&&n&&n.length>1){var a=we(n)/we(r);!isFinite(a)&&(a=1),e.pinchScale=a;var o=be(n);return e.pinchX=o[0],e.pinchY=o[1],{type:"pinch",target:t[0].target,event:e}}}}},Yp="silent";Ie.prototype.dispose=function(){};var jp=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],qp=function(t,e,i,n){Rp.call(this),this.storage=t,this.painter=e,this.painterRoot=n,i=i||new Ie,this.proxy=null,this._hovered={},this._lastTouchMoment,this._lastX,this._lastY,this._gestureMgr,le.call(this),this.setHandlerProxy(i)};qp.prototype={constructor:qp,setHandlerProxy:function(t){this.proxy&&this.proxy.dispose(),t&&(f(jp,function(e){t.on&&t.on(e,this[e],this)},this),t.handler=this),this.proxy=t},mousemove:function(t){var e=t.zrX,i=t.zrY,n=this._hovered,r=n.target;r&&!r.__zr&&(n=this.findHover(n.x,n.y),r=n.target);var a=this._hovered=this.findHover(e,i),o=a.target,s=this.proxy;s.setCursor&&s.setCursor(o?o.cursor:"default"),r&&o!==r&&this.dispatchToElement(n,"mouseout",t),this.dispatchToElement(a,"mousemove",t),o&&o!==r&&this.dispatchToElement(a,"mouseover",t)},mouseout:function(t){this.dispatchToElement(this._hovered,"mouseout",t);var e,i=t.toElement||t.relatedTarget;do i=i&&i.parentNode;while(i&&9!==i.nodeType&&!(e=i===this.painterRoot));!e&&this.trigger("globalout",{event:t})},resize:function(){this._hovered={}},dispatch:function(t,e){var i=this[t];i&&i.call(this,e)},dispose:function(){this.proxy.dispose(),this.storage=this.proxy=this.painter=null},setCursorStyle:function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},dispatchToElement:function(t,e,i){t=t||{};var n=t.target;if(!n||!n.silent){for(var r="on"+e,a=Se(e,t,i);n&&(n[r]&&(a.cancelBubble=n[r].call(n,a)),n.trigger(e,a),n=n.parent,!a.cancelBubble););a.cancelBubble||(this.trigger(e,a),this.painter&&this.painter.eachOtherLayer(function(t){"function"==typeof t[r]&&t[r].call(t,a),t.trigger&&t.trigger(e,a)}))}},findHover:function(t,e,i){for(var n=this.storage.getDisplayList(),r={x:t,y:e},a=n.length-1;a>=0;a--){var o;if(n[a]!==i&&!n[a].ignore&&(o=Ce(n[a],t,e))&&(!r.topTarget&&(r.topTarget=n[a]),o!==Yp)){r.target=n[a];break}}return r},processGesture:function(t,e){this._gestureMgr||(this._gestureMgr=new Up);var i=this._gestureMgr;"start"===e&&i.clear();var n=i.recognize(t,this.findHover(t.zrX,t.zrY,null).target,this.proxy.dom);if("end"===e&&i.clear(),n){var r=n.type;t.gestureEvent=r,this.dispatchToElement({target:n.target},r,n.event)}}},f(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){qp.prototype[t]=function(e){var i=this.findHover(e.zrX,e.zrY),n=i.target;if("mousedown"===t)this._downEl=n,this._downPoint=[e.zrX,e.zrY],this._upEl=n;else if("mouseup"===t)this._upEl=n;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||Op(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(i,t,e)}}),c(qp,Rp),c(qp,le);var Zp="undefined"==typeof Float32Array?Array:Float32Array,Kp=(Object.freeze||Object)({create:Te,identity:De,copy:Ae,mul:ke,translate:Pe,rotate:Le,scale:Oe,invert:ze,clone:Be}),$p=De,Qp=5e-5,Jp=function(t){t=t||{},t.position||(this.position=[0,0]),null==t.rotation&&(this.rotation=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},tg=Jp.prototype;tg.transform=null,tg.needLocalTransform=function(){return Ee(this.rotation)||Ee(this.position[0])||Ee(this.position[1])||Ee(this.scale[0]-1)||Ee(this.scale[1]-1)};var eg=[];tg.updateTransform=function(){var t=this.parent,e=t&&t.transform,i=this.needLocalTransform(),n=this.transform;if(!i&&!e)return void(n&&$p(n));n=n||Te(),i?this.getLocalTransform(n):$p(n),e&&(i?ke(n,t.transform,n):Ae(n,t.transform)),this.transform=n;var r=this.globalScaleRatio;if(null!=r&&1!==r){this.getGlobalScale(eg);var a=eg[0]<0?-1:1,o=eg[1]<0?-1:1,s=((eg[0]-a)*r+a)/eg[0]||0,l=((eg[1]-o)*r+o)/eg[1]||0;n[0]*=s,n[1]*=s,n[2]*=l,n[3]*=l}this.invTransform=this.invTransform||Te(),ze(this.invTransform,n)},tg.getLocalTransform=function(t){return Jp.getLocalTransform(this,t)},tg.setTransform=function(t){var e=this.transform,i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},tg.restoreTransform=function(t){var e=t.dpr||1;t.setTransform(e,0,0,e,0,0)};var ig=[],ng=Te();tg.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],i=t[2]*t[2]+t[3]*t[3],n=this.position,r=this.scale;Ee(e-1)&&(e=Math.sqrt(e)),Ee(i-1)&&(i=Math.sqrt(i)),t[0]<0&&(e=-e),t[3]<0&&(i=-i),n[0]=t[4],n[1]=t[5],r[0]=e,r[1]=i,this.rotation=Math.atan2(-t[1]/i,t[0]/e)}},tg.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(ke(ig,t.invTransform,e),e=ig);var i=this.origin;i&&(i[0]||i[1])&&(ng[4]=i[0],ng[5]=i[1],ke(ig,e,ng),ig[4]-=i[0],ig[5]-=i[1],e=ig),this.setLocalTransform(e)}},tg.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},tg.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&ae(i,i,n),i},tg.transformCoordToGlobal=function(t,e){var i=[t,e],n=this.transform; -return n&&ae(i,i,n),i},Jp.getLocalTransform=function(t,e){e=e||[],$p(e);var i=t.origin,n=t.scale||[1,1],r=t.rotation||0,a=t.position||[0,0];return i&&(e[4]-=i[0],e[5]-=i[1]),Oe(e,e,n),r&&Le(e,e,r),i&&(e[4]+=i[0],e[5]+=i[1]),e[4]+=a[0],e[5]+=a[1],e};var rg={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(-Math.pow(2,-10*(t-1))+2)},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),-(i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n)))},elasticOut:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin(2*(t-e)*Math.PI/n)+1)},elasticInOut:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?-.5*i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n):i*Math.pow(2,-10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?.5*t*t*((e+1)*t-e):.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-rg.bounceOut(1-t)},bounceOut:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return.5>t?.5*rg.bounceIn(2*t):.5*rg.bounceOut(2*t-1)+.5}};Re.prototype={constructor:Re,step:function(t,e){if(this._initialized||(this._startTime=t+this._delay,this._initialized=!0),this._paused)return void(this._pausedTime+=e);var i=(t-this._startTime-this._pausedTime)/this._life;if(!(0>i)){i=Math.min(i,1);var n=this.easing,r="string"==typeof n?rg[n]:n,a="function"==typeof r?r(i):i;return this.fire("frame",a),1===i?this.loop?(this.restart(t),"restart"):(this._needsRemove=!0,"destroy"):null}},restart:function(t){var e=(t-this._startTime-this._pausedTime)%this._life;this._startTime=t-e+this.gap,this._pausedTime=0,this._needsRemove=!1},fire:function(t,e){t="on"+t,this[t]&&this[t](this._target,e)},pause:function(){this._paused=!0},resume:function(){this._paused=!1}};var ag=function(){this.head=null,this.tail=null,this._len=0},og=ag.prototype;og.insert=function(t){var e=new sg(t);return this.insertEntry(e),e},og.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},og.remove=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},og.len=function(){return this._len},og.clear=function(){this.head=this.tail=null,this._len=0};var sg=function(t){this.value=t,this.next,this.prev},lg=function(t){this._list=new ag,this._map={},this._maxSize=t||10,this._lastRemovedEntry=null},ug=lg.prototype;ug.put=function(t,e){var i=this._list,n=this._map,r=null;if(null==n[t]){var a=i.len(),o=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=i.head;i.remove(s),delete n[s.key],r=s.value,this._lastRemovedEntry=s}o?o.value=e:o=new sg(e),o.key=t,i.insertEntry(o),n[t]=o}return r},ug.get=function(t){var e=this._map[t],i=this._list;return null!=e?(e!==i.tail&&(i.remove(e),i.insertEntry(e)),e.value):void 0},ug.clear=function(){this._list.clear(),this._map={}};var hg={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},cg=new lg(20),dg=null,fg=Je,pg=ti,gg=(Object.freeze||Object)({parse:qe,lift:$e,toHex:Qe,fastLerp:Je,fastMapToColor:fg,lerp:ti,mapToColor:pg,modifyHSL:ei,modifyAlpha:ii,stringify:ni}),vg=Array.prototype.slice,mg=function(t,e,i,n){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||ri,this._setter=n||ai,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};mg.prototype={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var r=this._getter(this._target,n);if(null==r)continue;0!==t&&i[n].push({time:0,value:fi(r)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},pause:function(){for(var t=0;ti;i++)t[i].call(this)},start:function(t,e){var i,n=this,r=0,a=function(){r--,r||n._doneCallback()};for(var o in this._tracks)if(this._tracks.hasOwnProperty(o)){var s=vi(this,t,a,this._tracks[o],o,e);s&&(this._clipList.push(s),r++,this.animation&&this.animation.addClip(s),i=s)}if(i){var l=i.onframe;i.onframe=function(t,e){l(t,e);for(var i=0;il;l++)s&&(s=s[o[l]]);s&&(i=s)}else i=r;if(!i)return void bg('Property "'+t+'" is not existed in element '+r.id);var c=r.animators,d=new mg(i,e);return d.during(function(){r.dirty(n)}).done(function(){c.splice(u(c,d),1)}),c.push(d),a&&a.animation.addAnimator(d),d},stopAnimation:function(t){for(var e=this.animators,i=e.length,n=0;i>n;n++)e[n].stop(t);return e.length=0,this},animateTo:function(t,e,i,n,r,a){mi(this,t,e,i,n,r,a)},animateFrom:function(t,e,i,n,r,a){mi(this,t,e,i,n,r,a,!0)}};var Mg=function(t){Jp.call(this,t),Rp.call(this,t),Sg.call(this,t),this.id=t.id||fp()};Mg.prototype={type:"element",name:"",__zr:null,ignore:!1,clipPath:null,isGroup:!1,drift:function(t,e){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.dirty(!1)},beforeUpdate:function(){},afterUpdate:function(){},update:function(){this.updateTransform()},traverse:function(){},attrKV:function(t,e){if("position"===t||"scale"===t||"origin"===t){if(e){var i=this[t];i||(i=this[t]=[]),i[0]=e[0],i[1]=e[1]}}else this[t]=e},hide:function(){this.ignore=!0,this.__zr&&this.__zr.refresh()},show:function(){this.ignore=!1,this.__zr&&this.__zr.refresh()},attr:function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(S(t))for(var i in t)t.hasOwnProperty(i)&&this.attrKV(i,t[i]);return this.dirty(!1),this},setClipPath:function(t){var e=this.__zr;e&&t.addSelfToZr(e),this.clipPath&&this.clipPath!==t&&this.removeClipPath(),this.clipPath=t,t.__zr=e,t.__clipTarget=this,this.dirty(!1)},removeClipPath:function(){var t=this.clipPath;t&&(t.__zr&&t.removeSelfFromZr(t.__zr),t.__zr=null,t.__clipTarget=null,this.clipPath=null,this.dirty(!1))},addSelfToZr:function(t){this.__zr=t;var e=this.animators;if(e)for(var i=0;in||i>s||l>a||r>u)},contain:function(t,e){var i=this;return t>=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new xi(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},xi.create=function(t){return new xi(t.x,t.y,t.width,t.height)};var Dg=function(t){t=t||{},Mg.call(this,t);for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};Dg.prototype={constructor:Dg,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i=0&&(i.splice(n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToStorage(t),t instanceof Dg&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var e=this.__zr,i=this.__storage,n=this._children,r=u(n,t);return 0>r?this:(n.splice(r,1),t.parent=null,i&&(i.delFromStorage(t),t instanceof Dg&&t.delChildrenFromStorage(i)),e&&e.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;en;n++)this._updateAndAddDisplayable(e[n],null,t);i.length=this._displayListLen,gp.canvasSupported&&Di(i,Ai)},_updateAndAddDisplayable:function(t,e,i){if(!t.ignore||i){t.beforeUpdate(),t.__dirty&&t.update(),t.afterUpdate();var n=t.clipPath;if(n){e=e?e.slice():[];for(var r=n,a=t;r;)r.parent=a,r.updateTransform(),e.push(r),a=r,r=r.clipPath}if(t.isGroup){for(var o=t._children,s=0;se;e++)this.delRoot(t[e]);else{var r=u(this._roots,t);r>=0&&(this.delFromStorage(t),this._roots.splice(r,1),t instanceof Dg&&t.delChildrenFromStorage(this))}},addToStorage:function(t){return t&&(t.__storage=this,t.dirty(!1)),this},delFromStorage:function(t){return t&&(t.__storage=null),this},dispose:function(){this._renderList=this._roots=null},displayableSortFunc:Ai};var Lg={shadowBlur:1,shadowOffsetX:1,shadowOffsetY:1,textShadowBlur:1,textShadowOffsetX:1,textShadowOffsetY:1,textBoxShadowBlur:1,textBoxShadowOffsetX:1,textBoxShadowOffsetY:1},Og=function(t,e,i){return Lg.hasOwnProperty(e)?i*=t.dpr:i},zg={NONE:0,STYLE_BIND:1,PLAIN_TEXT:2},Bg=9,Eg=[["shadowBlur",0],["shadowOffsetX",0],["shadowOffsetY",0],["shadowColor","#000"],["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]],Rg=function(t){this.extendFrom(t,!1)};Rg.prototype={constructor:Rg,fill:"#000",stroke:null,opacity:1,fillOpacity:null,strokeOpacity:null,lineDash:null,lineDashOffset:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,lineWidth:1,strokeNoScale:!1,text:null,font:null,textFont:null,fontStyle:null,fontWeight:null,fontSize:null,fontFamily:null,textTag:null,textFill:"#000",textStroke:null,textWidth:null,textHeight:null,textStrokeWidth:0,textLineHeight:null,textPosition:"inside",textRect:null,textOffset:null,textAlign:null,textVerticalAlign:null,textDistance:5,textShadowColor:"transparent",textShadowBlur:0,textShadowOffsetX:0,textShadowOffsetY:0,textBoxShadowColor:"transparent",textBoxShadowBlur:0,textBoxShadowOffsetX:0,textBoxShadowOffsetY:0,transformText:!1,textRotation:0,textOrigin:null,textBackgroundColor:null,textBorderColor:null,textBorderWidth:0,textBorderRadius:0,textPadding:null,rich:null,truncate:null,blend:null,bind:function(t,e,i){var n=this,r=i&&i.style,a=!r||t.__attrCachedBy!==zg.STYLE_BIND;t.__attrCachedBy=zg.STYLE_BIND;for(var o=0;o0},extendFrom:function(t,e){if(t)for(var i in t)!t.hasOwnProperty(i)||e!==!0&&(e===!1?this.hasOwnProperty(i):null==t[i])||(this[i]=t[i])},set:function(t,e){"string"==typeof t?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(t,e,i){for(var n="radial"===e.type?Pi:ki,r=n(t,e,i),a=e.colorStops,o=0;o=0&&i.splice(n,1),t.__hoverMir=null},clearHover:function(){for(var t=this._hoverElements,e=0;er;){var a=t[r],o=a.__from;o&&o.__zr?(r++,o.invisible||(a.transform=o.transform,a.invTransform=o.invTransform,a.__clipPaths=o.__clipPaths,this._doPaintEl(a,i,!0,n))):(t.splice(r,1),o.__hoverMir=null,e--)}i.ctx.restore()}},getHoverLayer:function(){return this.getLayer(av)},_paintList:function(t,e,i){if(this._redrawId===i){e=e||!1,this._updateLayerStatus(t);var n=this._doPaintList(t,e);if(this._needsManuallyCompositing&&this._compositeManually(),!n){var r=this;Wg(function(){r._paintList(t,e,i)})}}},_compositeManually:function(){var t=this.getLayer(ov).ctx,e=this._domRoot.width,i=this._domRoot.height;t.clearRect(0,0,e,i),this.eachBuiltinLayer(function(n){n.virtual&&t.drawImage(n.dom,0,0,e,i)})},_doPaintList:function(t,e){for(var i=[],n=0;n15)break}}a.__drawIndex=v,a.__drawIndex0&&t>n[0]){for(o=0;r-1>o&&!(n[o]t);o++);a=i[n[o]]}if(n.splice(o+1,0,t),i[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?s.insertBefore(e.dom,l.nextSibling):s.appendChild(e.dom)}else s.firstChild?s.insertBefore(e.dom,s.firstChild):s.appendChild(e.dom)},eachLayer:function(t,e){var i,n,r=this._zlevelList;for(n=0;n0?sv:0),this._needsManuallyCompositing),o.__builtin__||bg("ZLevel "+s+" has been used by unkown layer "+o.id),o!==r&&(o.__used=!0,o.__startIndex!==i&&(o.__dirty=!0),o.__startIndex=i,o.__drawIndex=o.incremental?-1:i,e(i),r=o),n.__dirty&&(o.__dirty=!0,o.incremental&&o.__drawIndex<0&&(o.__drawIndex=i))}e(i),this.eachBuiltinLayer(function(t){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)})},clear:function(){return this.eachBuiltinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},setBackgroundColor:function(t){this._backgroundColor=t},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?r(i[t],e,!0):i[t]=e;for(var n=0;n=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;io;o++){var s=i[o],l=s.step(t,e);l&&(r.push(l),a.push(s))}for(var o=0;n>o;)i[o]._needsRemove?(i[o]=i[n-1],i.pop(),n--):o++;n=r.length;for(var o=0;n>o;o++)a[o].fire(r[o]);this._time=t,this.onframe(e),this.trigger("frame",e),this.stage.update&&this.stage.update()},_startLoop:function(){function t(){e._running&&(Wg(t),!e._paused&&e._update())}var e=this;this._running=!0,Wg(t)},start:function(){this._time=(new Date).getTime(),this._pausedTime=0,this._startLoop()},stop:function(){this._running=!1},pause:function(){this._paused||(this._pauseStart=(new Date).getTime(),this._paused=!0)},resume:function(){this._paused&&(this._pausedTime+=(new Date).getTime()-this._pauseStart,this._paused=!1)},clear:function(){this._clips=[]},isFinished:function(){return!this._clips.length},animate:function(t,e){e=e||{};var i=new mg(t,e.loop,e.getter,e.setter);return this.addAnimator(i),i}},c(dv,Rp);var fv=300,pv=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],gv=["touchstart","touchend","touchmove"],vv={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},mv=p(pv,function(t){var e=t.replace("mouse","pointer");return vv[e]?e:t}),yv={mousemove:function(t){t=ye(this.dom,t),this.trigger("mousemove",t)},mouseout:function(t){t=ye(this.dom,t);var e=t.toElement||t.relatedTarget;if(e!==this.dom)for(;e&&9!==e.nodeType;){if(e===this.dom)return;e=e.parentNode}this.trigger("mouseout",t)},touchstart:function(t){t=ye(this.dom,t),t.zrByTouch=!0,this._lastTouchMoment=new Date,this.handler.processGesture(t,"start"),yv.mousemove.call(this,t),yv.mousedown.call(this,t),kn(this)},touchmove:function(t){t=ye(this.dom,t),t.zrByTouch=!0,this.handler.processGesture(t,"change"),yv.mousemove.call(this,t),kn(this)},touchend:function(t){t=ye(this.dom,t),t.zrByTouch=!0,this.handler.processGesture(t,"end"),yv.mouseup.call(this,t),+new Date-this._lastTouchMoment=0||n&&u(n,o)<0)){var s=e.getShallow(o);null!=s&&(r[t[a][0]]=s)}}return r}},Ev=Bv([["lineWidth","width"],["stroke","color"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]),Rv={getLineStyle:function(t){var e=Ev(this,t);return e.lineDash=this.getLineDash(e.lineWidth),e},getLineDash:function(t){null==t&&(t=1);var e=this.get("type"),i=Math.max(t,2),n=4*t;return"solid"===e||null==e?!1:"dashed"===e?[n,n]:[i,i]}},Nv=Bv([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),Fv={getAreaStyle:function(t,e){return Nv(this,t,e)}},Gv=Math.pow,Vv=Math.sqrt,Hv=1e-8,Wv=1e-4,Uv=Vv(3),Xv=1/3,Yv=V(),jv=V(),qv=V(),Zv=Math.min,Kv=Math.max,$v=Math.sin,Qv=Math.cos,Jv=2*Math.PI,tm=V(),em=V(),im=V(),nm=[],rm=[],am={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},om=[],sm=[],lm=[],um=[],hm=Math.min,cm=Math.max,dm=Math.cos,fm=Math.sin,pm=Math.sqrt,gm=Math.abs,vm="undefined"!=typeof Float32Array,mm=function(t){this._saveData=!t,this._saveData&&(this.data=[]),this._ctx=null};mm.prototype={constructor:mm,_xi:0,_yi:0,_x0:0,_y0:0,_ux:0,_uy:0,_len:0,_lineDash:null,_dashOffset:0,_dashIdx:0,_dashSum:0,setScale:function(t,e,i){i=i||0,this._ux=gm(i/xg/t)||0,this._uy=gm(i/xg/e)||0},getContext:function(){return this._ctx},beginPath:function(t){return this._ctx=t,t&&t.beginPath(),t&&(this.dpr=t.dpr),this._saveData&&(this._len=0),this._lineDash&&(this._lineDash=null,this._dashOffset=0),this},moveTo:function(t,e){return this.addData(am.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},lineTo:function(t,e){var i=gm(t-this._xi)>this._ux||gm(e-this._yi)>this._uy||this._len<5;return this.addData(am.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,r,a){return this.addData(am.C,t,e,i,n,r,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,r,a):this._ctx.bezierCurveTo(t,e,i,n,r,a)),this._xi=r,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(am.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,r,a){return this.addData(am.A,t,e,i,i,n,r-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,r,a),this._xi=dm(r)*i+t,this._yi=fm(r)*i+e,this},arcTo:function(t,e,i,n,r){return this._ctx&&this._ctx.arcTo(t,e,i,n,r),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(am.R,t,e,i,n),this},closePath:function(){this.addData(am.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;ii;i++)this.data[i]=t[i];this._len=e},appendPath:function(t){t instanceof Array||(t=[t]);for(var e=t.length,i=0,n=this._len,r=0;e>r;r++)i+=t[r].len();vm&&this.data instanceof Float32Array&&(this.data=new Float32Array(n+i));for(var r=0;e>r;r++)for(var a=t[r].data,o=0;oe.length&&(this._expandData(),e=this.data);for(var i=0;ia&&(a=r+a),a%=r,f-=a*h,p-=a*c;h>0&&t>=f||0>h&&f>=t||0===h&&(c>0&&e>=p||0>c&&p>=e);)n=this._dashIdx,i=o[n],f+=h*i,p+=c*i,this._dashIdx=(n+1)%g,h>0&&l>f||0>h&&f>l||c>0&&u>p||0>c&&p>u||s[n%2?"moveTo":"lineTo"](h>=0?hm(f,t):cm(f,t),c>=0?hm(p,e):cm(p,e));h=f-t,c=p-e,this._dashOffset=-pm(h*h+c*c)},_dashedBezierTo:function(t,e,i,n,r,a){var o,s,l,u,h,c=this._dashSum,d=this._dashOffset,f=this._lineDash,p=this._ctx,g=this._xi,v=this._yi,m=ur,y=0,_=this._dashIdx,x=f.length,w=0;for(0>d&&(d=c+d),d%=c,o=0;1>o;o+=.1)s=m(g,t,i,r,o+.1)-m(g,t,i,r,o),l=m(v,e,n,a,o+.1)-m(v,e,n,a,o),y+=pm(s*s+l*l);for(;x>_&&(w+=f[_],!(w>d));_++);for(o=(w-d)/y;1>=o;)u=m(g,t,i,r,o),h=m(v,e,n,a,o),_%2?p.moveTo(u,h):p.lineTo(u,h),o+=f[_]/y,_=(_+1)%x;_%2!==0&&p.lineTo(r,a),s=r-u,l=a-h,this._dashOffset=-pm(s*s+l*l)},_dashedQuadraticTo:function(t,e,i,n){var r=i,a=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,r,a)},toStatic:function(){var t=this.data;t instanceof Array&&(t.length=this._len,vm&&(this.data=new Float32Array(t)))},getBoundingRect:function(){om[0]=om[1]=lm[0]=lm[1]=Number.MAX_VALUE,sm[0]=sm[1]=um[0]=um[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,n=0,r=0,a=0;ac;){var d=s[c++];switch(1===c&&(n=s[c],r=s[c+1],e=n,i=r),d){case am.M:e=n=s[c++],i=r=s[c++],t.moveTo(n,r);break;case am.L:a=s[c++],o=s[c++],(gm(a-n)>l||gm(o-r)>u||c===h-1)&&(t.lineTo(a,o),n=a,r=o);break;case am.C:t.bezierCurveTo(s[c++],s[c++],s[c++],s[c++],s[c++],s[c++]),n=s[c-2],r=s[c-1];break;case am.Q:t.quadraticCurveTo(s[c++],s[c++],s[c++],s[c++]),n=s[c-2],r=s[c-1];break;case am.A:var f=s[c++],p=s[c++],g=s[c++],v=s[c++],m=s[c++],y=s[c++],_=s[c++],x=s[c++],w=g>v?g:v,b=g>v?1:g/v,S=g>v?v/g:1,M=Math.abs(g-v)>.001,I=m+y;M?(t.translate(f,p),t.rotate(_),t.scale(b,S),t.arc(0,0,w,m,I,1-x),t.scale(1/b,1/S),t.rotate(-_),t.translate(-f,-p)):t.arc(f,p,w,m,I,1-x),1===c&&(e=dm(m)*g+f,i=fm(m)*v+p),n=dm(I)*g+f,r=fm(I)*v+p;break;case am.R:e=n=s[c],i=r=s[c+1],t.rect(s[c++],s[c++],s[c++],s[c++]);break;case am.Z:t.closePath(),n=e,r=i}}}},mm.CMD=am;var ym=2*Math.PI,_m=2*Math.PI,xm=mm.CMD,wm=2*Math.PI,bm=1e-4,Sm=[-1,-1,-1],Mm=[-1,-1],Im=Vg.prototype.getCanvasPattern,Cm=Math.abs,Tm=new mm(!0);Gr.prototype={constructor:Gr,type:"path",__dirtyPath:!0,strokeContainThreshold:5,segmentIgnoreThreshold:0,subPixelOptimize:!1,brush:function(t,e){var i=this.style,n=this.path||Tm,r=i.hasStroke(),a=i.hasFill(),o=i.fill,s=i.stroke,l=a&&!!o.colorStops,u=r&&!!s.colorStops,h=a&&!!o.image,c=r&&!!s.image;if(i.bind(t,this,e),this.setTransform(t),this.__dirty){var d;l&&(d=d||this.getBoundingRect(),this._fillGradient=i.getGradient(t,o,d)),u&&(d=d||this.getBoundingRect(),this._strokeGradient=i.getGradient(t,s,d))}l?t.fillStyle=this._fillGradient:h&&(t.fillStyle=Im.call(o,t)),u?t.strokeStyle=this._strokeGradient:c&&(t.strokeStyle=Im.call(s,t));var f=i.lineDash,p=i.lineDashOffset,g=!!t.setLineDash,v=this.getGlobalScale();if(n.setScale(v[0],v[1],this.segmentIgnoreThreshold),this.__dirtyPath||f&&!g&&r?(n.beginPath(t),f&&!g&&(n.setLineDash(f),n.setLineDashOffset(p)),this.buildPath(n,this.shape,!1),this.path&&(this.__dirtyPath=!1)):(t.beginPath(),this.path.rebuildPath(t)),a)if(null!=i.fillOpacity){var m=t.globalAlpha;t.globalAlpha=i.fillOpacity*i.opacity,n.fill(t),t.globalAlpha=m}else n.fill(t);if(f&&g&&(t.setLineDash(f),t.lineDashOffset=p),r)if(null!=i.strokeOpacity){var m=t.globalAlpha;t.globalAlpha=i.strokeOpacity*i.opacity,n.stroke(t),t.globalAlpha=m}else n.stroke(t);f&&g&&t.setLineDash([]),null!=i.text&&(this.restoreTransform(t),this.drawRectText(t,this.getBoundingRect()))},buildPath:function(){},createPathProxy:function(){this.path=new mm},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var n=this.path;n||(n=this.path=new mm),this.__dirtyPath&&(n.beginPath(),this.buildPath(n,this.shape,!1)),t=n.getBoundingRect()}if(this._rect=t,e.hasStroke()){var r=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){r.copy(t);var a=e.lineWidth,o=e.strokeNoScale?this.getLineScale():1;e.hasFill()||(a=Math.max(a,this.strokeContainThreshold||4)),o>1e-10&&(r.width+=a/o,r.height+=a/o,r.x-=a/o/2,r.y-=a/o/2)}return r}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this.getBoundingRect(),r=this.style;if(t=i[0],e=i[1],n.contain(t,e)){var a=this.path.data;if(r.hasStroke()){var o=r.lineWidth,s=r.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(r.hasFill()||(o=Math.max(o,this.strokeContainThreshold)),Fr(a,o/s,t,e)))return!0}if(r.hasFill())return Nr(a,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=this.__dirtyText=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):wn.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(S(t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&Cm(t[0]-1)>1e-10&&Cm(t[3]-1)>1e-10?Math.sqrt(Cm(t[0]*t[3]-t[2]*t[1])):1}},Gr.extend=function(t){var e=function(e){Gr.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var n=this.shape;for(var r in i)!n.hasOwnProperty(r)&&i.hasOwnProperty(r)&&(n[r]=i[r])}t.init&&t.init.call(this,e)};h(e,Gr);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},h(Gr,wn);var Dm=mm.CMD,Am=[[],[],[]],km=Math.sqrt,Pm=Math.atan2,Lm=function(t,e){var i,n,r,a,o,s,l=t.data,u=Dm.M,h=Dm.C,c=Dm.L,d=Dm.R,f=Dm.A,p=Dm.Q;for(r=0,a=0;ro;o++){var s=Am[o];s[0]=l[r++],s[1]=l[r++],ae(s,s,e),l[a++]=s[0],l[a++]=s[1]}}},Om=Math.sqrt,zm=Math.sin,Bm=Math.cos,Em=Math.PI,Rm=function(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])},Nm=function(t,e){return(t[0]*e[0]+t[1]*e[1])/(Rm(t)*Rm(e))},Fm=function(t,e){return(t[0]*e[1]=11?function(){var e,i=this.__clipPaths,n=this.style;if(i)for(var r=0;ra;a++)r+=ee(t[a-1],t[a]);var o=r/2;o=i>o?i:o;for(var a=0;o>a;a++){var s,l,u,h=a/(o-1)*(e?i:i-1),c=Math.floor(h),d=h-c,f=t[c%i];e?(s=t[(c-1+i)%i],l=t[(c+1)%i],u=t[(c+2)%i]):(s=t[0===c?c:c-1],l=t[c>i-2?i-1:c+1],u=t[c>i-3?i-1:c+2]);var p=d*d,g=d*p;n.push([jr(s[0],f[0],l[0],u[0],d,p,g),jr(s[1],f[1],l[1],u[1],d,p,g)])}return n},Zm=function(t,e,i,n){var r,a,o,s,l=[],u=[],h=[],c=[];if(n){o=[1/0,1/0],s=[-1/0,-1/0];for(var d=0,f=t.length;f>d;d++)oe(o,o,t[d]),se(s,s,t[d]);oe(o,o,n[0]),se(s,s,n[1])}for(var d=0,f=t.length;f>d;d++){var p=t[d];if(i)r=t[d?d-1:f-1],a=t[(d+1)%f];else{if(0===d||d===f-1){l.push(W(t[d]));continue}r=t[d-1],a=t[d+1]}j(u,a,r),J(u,u,e);var g=ee(p,r),v=ee(p,a),m=g+v;0!==m&&(g/=m,v/=m),J(h,u,-g),J(c,u,v);var y=X([],p,h),_=X([],p,c);n&&(se(y,y,o),oe(y,y,s),se(_,_,o),oe(_,_,s)),l.push(y),l.push(_)}return i&&l.push(l.shift()),l},Km=Gr.extend({type:"polygon",shape:{points:null,smooth:!1,smoothConstraint:null},buildPath:function(t,e){qr(t,e,!0)}}),$m=Gr.extend({type:"polyline",shape:{points:null,smooth:!1,smoothConstraint:null},style:{stroke:"#000",fill:null},buildPath:function(t,e){qr(t,e,!1)}}),Qm=Math.round,Jm={},ty=Gr.extend({type:"rect",shape:{r:0,x:0,y:0,width:0,height:0},buildPath:function(t,e){var i,n,r,a;this.subPixelOptimize?(Kr(Jm,e,this.style),i=Jm.x,n=Jm.y,r=Jm.width,a=Jm.height,Jm.r=e.r,e=Jm):(i=e.x,n=e.y,r=e.width,a=e.height),e.r?en(t,e):t.rect(i,n,r,a),t.closePath()}}),ey={},iy=Gr.extend({type:"line",shape:{x1:0,y1:0,x2:0,y2:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i,n,r,a;this.subPixelOptimize?(Zr(ey,e,this.style),i=ey.x1,n=ey.y1,r=ey.x2,a=ey.y2):(i=e.x1,n=e.y1,r=e.x2,a=e.y2);var o=e.percent;0!==o&&(t.moveTo(i,n),1>o&&(r=i*(1-o)+r*o,a=n*(1-o)+a*o),t.lineTo(r,a))},pointAt:function(t){var e=this.shape;return[e.x1*(1-t)+e.x2*t,e.y1*(1-t)+e.y2*t]}}),ny=[],ry=Gr.extend({type:"bezier-curve",shape:{x1:0,y1:0,x2:0,y2:0,cpx1:0,cpy1:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.x1,n=e.y1,r=e.x2,a=e.y2,o=e.cpx1,s=e.cpy1,l=e.cpx2,u=e.cpy2,h=e.percent;0!==h&&(t.moveTo(i,n),null==l||null==u?(1>h&&(_r(i,o,r,h,ny),o=ny[1],r=ny[2],_r(n,s,a,h,ny),s=ny[1],a=ny[2]),t.quadraticCurveTo(o,s,r,a)):(1>h&&(fr(i,o,l,r,h,ny),o=ny[1],l=ny[2],r=ny[3],fr(n,s,u,a,h,ny),s=ny[1],u=ny[2],a=ny[3]),t.bezierCurveTo(o,s,l,u,r,a)))},pointAt:function(t){return Qr(this.shape,t,!1)},tangentAt:function(t){var e=Qr(this.shape,t,!0);return te(e,e)}}),ay=Gr.extend({type:"arc",shape:{cx:0,cy:0,r:0,startAngle:0,endAngle:2*Math.PI,clockwise:!0},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.cx,n=e.cy,r=Math.max(e.r,0),a=e.startAngle,o=e.endAngle,s=e.clockwise,l=Math.cos(a),u=Math.sin(a);t.moveTo(l*r+i,u*r+n),t.arc(i,n,r,a,o,!s)}}),oy=Gr.extend({type:"compound",shape:{paths:null},_updatePathDirty:function(){for(var t=this.__dirtyPath,e=this.shape.paths,i=0;i"'])/g,Fy={"&":"&","<":"<",">":">",'"':""","'":"'"},Gy=["a","b","c","d","e","f","g"],Vy=function(t,e){return"{"+t+(null==e?"":e)+"}" -},Hy=Xi,Wy=(Object.freeze||Object)({addCommas:So,toCamelCase:Mo,normalizeCssArray:Ry,encodeHTML:Io,formatTpl:Co,formatTplSimple:To,getTooltipMarker:Do,formatTime:ko,capitalFirst:Po,truncateText:Hy,getTextBoundingRect:Lo,getTextRect:Oo}),Uy=f,Xy=["left","right","top","bottom","width","height"],Yy=[["width","left","right"],["height","top","bottom"]],jy=zo,qy=(_(zo,"vertical"),_(zo,"horizontal"),{getBoxLayoutParams:function(){return{left:this.get("left"),top:this.get("top"),right:this.get("right"),bottom:this.get("bottom"),width:this.get("width"),height:this.get("height")}}}),Zy=qn(),Ky=Qa.extend({type:"component",id:"",name:"",mainType:"",subType:"",componentIndex:0,defaultOption:null,ecModel:null,dependentModels:[],uid:null,layoutMode:null,$constructor:function(t,e,i,n){Qa.call(this,t,e,i,n),this.uid=eo("ec_cpt_model")},init:function(t,e,i){this.mergeDefaultAndTheme(t,i)},mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,n=i?Ro(t):{},a=e.getTheme();r(t,a.get(this.mainType)),r(t,this.getDefaultOption()),i&&Eo(t,n,i)},mergeOption:function(t){r(this.option,t,!0);var e=this.layoutMode;e&&Eo(this.option,t,e)},optionUpdated:function(){},getDefaultOption:function(){var t=Zy(this);if(!t.defaultOption){for(var e=[],i=this.constructor;i;){var n=i.prototype.defaultOption;n&&e.push(n),i=i.superClass}for(var a={},o=e.length-1;o>=0;o--)a=r(a,e[o],!0);t.defaultOption=a}return t.defaultOption},getReferringComponents:function(t){return this.ecModel.queryComponents({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});or(Ky,{registerWhenExtend:!0}),io(Ky),no(Ky,Fo),c(Ky,qy);var $y="";"undefined"!=typeof navigator&&($y=navigator.platform||"");var Qy={color:["#c23531","#2f4554","#61a0a8","#d48265","#91c7ae","#749f83","#ca8622","#bda29a","#6e7074","#546570","#c4ccd3"],gradientColor:["#f6efa6","#d88273","#bf444c"],textStyle:{fontFamily:$y.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,animation:"auto",animationDuration:1e3,animationDurationUpdate:300,animationEasing:"exponentialOut",animationEasingUpdate:"cubicOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},Jy=qn(),t_={clearColorPalette:function(){Jy(this).colorIdx=0,Jy(this).colorNameMap={}},getColorFromPalette:function(t,e,i){e=e||this;var n=Jy(e),r=n.colorIdx||0,a=n.colorNameMap=n.colorNameMap||{};if(a.hasOwnProperty(t))return a[t];var o=Fn(this.get("color",!0)),s=this.get("colorLayer",!0),l=null!=i&&s?Go(s,i):o;if(l=l||o,l&&l.length){var u=l[r];return t&&(a[t]=u),n.colorIdx=(r+1)%l.length,u}}},e_={cartesian2d:function(t,e,i,n){var r=t.getReferringComponents("xAxis")[0],a=t.getReferringComponents("yAxis")[0];e.coordSysDims=["x","y"],i.set("x",r),i.set("y",a),Ho(r)&&(n.set("x",r),e.firstCategoryDimIndex=0),Ho(a)&&(n.set("y",a),e.firstCategoryDimIndex=1)},singleAxis:function(t,e,i,n){var r=t.getReferringComponents("singleAxis")[0];e.coordSysDims=["single"],i.set("single",r),Ho(r)&&(n.set("single",r),e.firstCategoryDimIndex=0)},polar:function(t,e,i,n){var r=t.getReferringComponents("polar")[0],a=r.findAxisModel("radiusAxis"),o=r.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],i.set("radius",a),i.set("angle",o),Ho(a)&&(n.set("radius",a),e.firstCategoryDimIndex=0),Ho(o)&&(n.set("angle",o),e.firstCategoryDimIndex=1)},geo:function(t,e){e.coordSysDims=["lng","lat"]},parallel:function(t,e,i,n){var r=t.ecModel,a=r.getComponent("parallel",t.get("parallelIndex")),o=e.coordSysDims=a.dimensions.slice();f(a.parallelAxisIndex,function(t,a){var s=r.getComponent("parallelAxis",t),l=o[a];i.set(l,s),Ho(s)&&null==e.firstCategoryDimIndex&&(n.set(l,s),e.firstCategoryDimIndex=a)})}},i_="original",n_="arrayRows",r_="objectRows",a_="keyedColumns",o_="unknown",s_="typedArray",l_="column",u_="row";Wo.seriesDataToSource=function(t){return new Wo({data:t,sourceFormat:I(t)?s_:i_,fromDataset:!1})},nr(Wo);var h_=qn(),c_="\x00_ec_inner",d_=Qa.extend({init:function(t,e,i,n){i=i||{},this.option=null,this._theme=new Qa(i),this._optionManager=n},setOption:function(t,e){O(!(c_ in t),"please use chart.getOption()"),this._optionManager.setOption(t,e),this.resetOption(null)},resetOption:function(t){var e=!1,i=this._optionManager;if(!t||"recreate"===t){var n=i.mountOption("recreate"===t);this.option&&"recreate"!==t?(this.restoreData(),this.mergeOption(n)):rs.call(this,n),e=!0}if(("timeline"===t||"media"===t)&&this.restoreData(),!t||"recreate"===t||"timeline"===t){var r=i.getTimelineOption(this);r&&(this.mergeOption(r),e=!0)}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this,this._api);a.length&&f(a,function(t){this.mergeOption(t,e=!0)},this)}return e},mergeOption:function(t){function e(e,n){var r=Fn(t[e]),s=Wn(a.get(e),r);Un(s),f(s,function(t){var i=t.option;S(i)&&(t.keyInfo.mainType=e,t.keyInfo.subType=os(e,i,t.exist))});var l=as(a,n);i[e]=[],a.set(e,[]),f(s,function(t,n){var r=t.exist,s=t.option;if(O(S(s)||r,"Empty component definition"),s){var u=Ky.getClass(e,t.keyInfo.subType,!0);if(r&&r.constructor===u)r.name=t.keyInfo.name,r.mergeOption(s,this),r.optionUpdated(s,!1);else{var h=o({dependentModels:l,componentIndex:n},t.keyInfo);r=new u(s,this,this,h),o(r,h),r.init(s,this,this,h),r.optionUpdated(null,!0)}}else r.mergeOption({},this),r.optionUpdated({},!1);a.get(e)[n]=r,i[e][n]=r.option},this),"series"===e&&ss(this,a.get("series"))}var i=this.option,a=this._componentsMap,s=[];Yo(this),f(t,function(t,e){null!=t&&(Ky.hasClass(e)?e&&s.push(e):i[e]=null==i[e]?n(t):r(i[e],t,!0))}),Ky.topologicalTravel(s,Ky.getAllClassMainTypes(),e,this),this._seriesIndicesMap=N(this._seriesIndices=this._seriesIndices||[])},getOption:function(){var t=n(this.option);return f(t,function(e,i){if(Ky.hasClass(i)){for(var e=Fn(e),n=e.length-1;n>=0;n--)Yn(e[n])&&e.splice(n,1);t[i]=e}}),delete t[c_],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap.get(t);return i?i[e||0]:void 0},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,r=t.name,a=this._componentsMap.get(e);if(!a||!a.length)return[];var o;if(null!=i)x(i)||(i=[i]),o=v(p(i,function(t){return a[t]}),function(t){return!!t});else if(null!=n){var s=x(n);o=v(a,function(t){return s&&u(n,t.id)>=0||!s&&t.id===n})}else if(null!=r){var l=x(r);o=v(a,function(t){return l&&u(r,t.name)>=0||!l&&t.name===r})}else o=a.slice();return ls(o,t)},findComponents:function(t){function e(t){var e=r+"Index",i=r+"Id",n=r+"Name";return!t||null==t[e]&&null==t[i]&&null==t[n]?null:{mainType:r,index:t[e],id:t[i],name:t[n]}}function i(e){return t.filter?v(e,t.filter):e}var n=t.query,r=t.mainType,a=e(n),o=a?this.queryComponents(a):this._componentsMap.get(r);return i(ls(o,t))},eachComponent:function(t,e,i){var n=this._componentsMap;if("function"==typeof t)i=e,e=t,n.each(function(t,n){f(t,function(t,r){e.call(i,n,t,r)})});else if(b(t))f(n.get(t),e,i);else if(S(t)){var r=this.findComponents(t);f(r,e,i)}},getSeriesByName:function(t){var e=this._componentsMap.get("series");return v(e,function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap.get("series")[t]},getSeriesByType:function(t){var e=this._componentsMap.get("series");return v(e,function(e){return e.subType===t})},getSeries:function(){return this._componentsMap.get("series").slice()},getSeriesCount:function(){return this._componentsMap.get("series").length},eachSeries:function(t,e){f(this._seriesIndices,function(i){var n=this._componentsMap.get("series")[i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){f(this._componentsMap.get("series"),t,e)},eachSeriesByType:function(t,e,i){f(this._seriesIndices,function(n){var r=this._componentsMap.get("series")[n];r.subType===t&&e.call(i,r,n)},this)},eachRawSeriesByType:function(t,e,i){return f(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return null==this._seriesIndicesMap.get(t.componentIndex)},getCurrentSeriesIndices:function(){return(this._seriesIndices||[]).slice()},filterSeries:function(t,e){var i=v(this._componentsMap.get("series"),t,e);ss(this,i)},restoreData:function(t){var e=this._componentsMap;ss(this,e.get("series"));var i=[];e.each(function(t,e){i.push(e)}),Ky.topologicalTravel(i,Ky.getAllClassMainTypes(),function(i){f(e.get(i),function(e){("series"!==i||!is(e,t))&&e.restoreData()})})}});c(d_,t_);var f_=["getDom","getZr","getWidth","getHeight","getDevicePixelRatio","dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL","getModel","getOption","getViewOfComponentModel","getViewOfSeriesModel"],p_={};hs.prototype={constructor:hs,create:function(t,e){var i=[];f(p_,function(n){var r=n.create(t,e);i=i.concat(r||[])}),this._coordinateSystems=i},update:function(t,e){f(this._coordinateSystems,function(i){i.update&&i.update(t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},hs.register=function(t,e){p_[t]=e},hs.get=function(t){return p_[t]};var g_=f,v_=n,m_=p,y_=r,__=/^(min|max)?(.+)$/;cs.prototype={constructor:cs,setOption:function(t,e){t&&f(Fn(t.series),function(t){t&&t.data&&I(t.data)&&B(t.data)}),t=v_(t);var i=this._optionBackup,n=ds.call(this,t,e,!i);this._newBaseOption=n.baseOption,i?(vs(i.baseOption,n.baseOption),n.timelineOptions.length&&(i.timelineOptions=n.timelineOptions),n.mediaList.length&&(i.mediaList=n.mediaList),n.mediaDefault&&(i.mediaDefault=n.mediaDefault)):this._optionBackup=n},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=m_(e.timelineOptions,v_),this._mediaList=m_(e.mediaList,v_),this._mediaDefault=v_(e.mediaDefault),this._currentMediaIndices=[],v_(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i.length){var n=t.getComponent("timeline");n&&(e=v_(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(){var t=this._api.getWidth(),e=this._api.getHeight(),i=this._mediaList,n=this._mediaDefault,r=[],a=[];if(!i.length&&!n)return a;for(var o=0,s=i.length;s>o;o++)fs(i[o].query,t,e)&&r.push(o);return!r.length&&n&&(r=[-1]),r.length&&!gs(r,this._currentMediaIndices)&&(a=m_(r,function(t){return v_(-1===t?n.option:i[t].option)})),this._currentMediaIndices=r,a}};var x_=f,w_=S,b_=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"],S_=function(t,e){x_(Ss(t.series),function(t){w_(t)&&bs(t)});var i=["xAxis","yAxis","radiusAxis","angleAxis","singleAxis","parallelAxis","radar"];e&&i.push("valueAxis","categoryAxis","logAxis","timeAxis"),x_(i,function(e){x_(Ss(t[e]),function(t){t&&(xs(t,"axisLabel"),xs(t.axisPointer,"label"))})}),x_(Ss(t.parallel),function(t){var e=t&&t.parallelAxisDefault;xs(e,"axisLabel"),xs(e&&e.axisPointer,"label")}),x_(Ss(t.calendar),function(t){ys(t,"itemStyle"),xs(t,"dayLabel"),xs(t,"monthLabel"),xs(t,"yearLabel")}),x_(Ss(t.radar),function(t){xs(t,"name")}),x_(Ss(t.geo),function(t){w_(t)&&(ws(t),x_(Ss(t.regions),function(t){ws(t)}))}),x_(Ss(t.timeline),function(t){ws(t),ys(t,"label"),ys(t,"itemStyle"),ys(t,"controlStyle",!0);var e=t.data;x(e)&&f(e,function(t){S(t)&&(ys(t,"label"),ys(t,"itemStyle"))})}),x_(Ss(t.toolbox),function(t){ys(t,"iconStyle"),x_(t.feature,function(t){ys(t,"iconStyle")})}),xs(Ms(t.axisPointer),"label"),xs(Ms(t.tooltip).axisPointer,"label")},M_=[["x","left"],["y","top"],["x2","right"],["y2","bottom"]],I_=["grid","geo","parallel","legend","toolbox","title","visualMap","dataZoom","timeline"],C_=function(t,e){S_(t,e),t.series=Fn(t.series),f(t.series,function(t){if(S(t)){var e=t.type;if("line"===e)null!=t.clipOverflow&&(t.clip=t.clipOverflow);else if("pie"===e||"gauge"===e)null!=t.clockWise&&(t.clockwise=t.clockWise);else if("gauge"===e){var i=Is(t,"pointer.color");null!=i&&Cs(t,"itemStyle.color",i)}Ts(t)}}),t.dataRange&&(t.visualMap=t.dataRange),f(I_,function(e){var i=t[e];i&&(x(i)||(i=[i]),f(i,function(t){Ts(t)}))})},T_=function(t){var e=N();t.eachSeries(function(t){var i=t.get("stack");if(i){var n=e.get(i)||e.set(i,[]),r=t.getData(),a={stackResultDimension:r.getCalculationInfo("stackResultDimension"),stackedOverDimension:r.getCalculationInfo("stackedOverDimension"),stackedDimension:r.getCalculationInfo("stackedDimension"),stackedByDimension:r.getCalculationInfo("stackedByDimension"),isStackedByIndex:r.getCalculationInfo("isStackedByIndex"),data:r,seriesModel:t};if(!a.stackedDimension||!a.isStackedByIndex&&!a.stackedByDimension)return;n.length&&r.setCalculationInfo("stackedOnSeries",n[n.length-1].seriesModel),n.push(a)}}),e.each(Ds)},D_=As.prototype;D_.pure=!1,D_.persistent=!0,D_.getSource=function(){return this._source};var A_={arrayRows_column:{pure:!0,count:function(){return Math.max(0,this._data.length-this._source.startIndex)},getItem:function(t){return this._data[t+this._source.startIndex]},appendData:Ls},arrayRows_row:{pure:!0,count:function(){var t=this._data[0];return t?Math.max(0,t.length-this._source.startIndex):0},getItem:function(t){t+=this._source.startIndex;for(var e=[],i=this._data,n=0;n=1)&&(t=1),t}var i=this._upstream,n=t&&t.skip;if(this._dirty&&i){var r=this.context;r.data=r.outputData=i.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this);var a;this._plan&&!n&&(a=this._plan(this.context));var o=e(this._modBy),s=this._modDataCount||0,l=e(t&&t.modBy),u=t&&t.modDataCount||0;(o!==l||s!==u)&&(a="reset");var h;(this._dirty||"reset"===a)&&(this._dirty=!1,h=Gs(this,n)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=i?i._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var d=this._dueIndex,f=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!n&&(h||f>d)){var p=this._progress;if(x(p))for(var g=0;gn?n++:null}function e(){var t=n%o*r+Math.ceil(n/o),e=n>=i?null:a>t?t:n;return n++,e}var i,n,r,a,o,s={reset:function(l,u,h,c){n=l,i=u,r=h,a=c,o=Math.ceil(a/r),s.next=r>1&&a>0?e:t}};return s}();z_.dirty=function(){this._dirty=!0,this._onDirty&&this._onDirty(this.context)},z_.unfinished=function(){return this._progress&&this._dueIndex":"",v=p+s.join(p||", ");return{renderMode:n,content:v,style:u}}function a(t){return{renderMode:n,content:Io(So(t)),style:u}}var o=this;n=n||"html";var s="html"===n?"
":"\n",l="richText"===n,u={},h=0,c=this.getData(),d=c.mapDimension("defaultedTooltip",!0),p=d.length,v=this.getRawValue(t),m=x(v),y=c.getItemVisual(t,"color");S(y)&&y.colorStops&&(y=(y.colorStops[0]||{}).color),y=y||"transparent";var _=p>1||m&&!p?r(v):a(p?Es(c,t,d[0]):m?v[0]:v),w=_.content,b=o.seriesIndex+"at"+h,M=Do({color:y,type:"item",renderMode:n,markerId:b});u[b]=y,++h;var I=c.getName(t),C=this.name;Xn(this)||(C=""),C=C?Io(C)+(e?": ":s):"";var T="string"==typeof M?M:M.content,D=e?T+C+w:C+T+(I?Io(I)+": "+w:w);return{html:D,markers:u}},isAnimationEnabled:function(){if(gp.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){this.dataTask.dirty()},getColorFromPalette:function(t,e,i){var n=this.ecModel,r=t_.getColorFromPalette.call(this,t,e,i);return r||(r=n.getColorFromPalette(t,e,i)),r},coordDimToDataDim:function(t){return this.getRawData().mapDimension(t,!0)},getProgressive:function(){return this.get("progressive")},getProgressiveThreshold:function(){return this.get("progressiveThreshold")},getAxisTooltipData:null,getTooltipPosition:null,pipeTask:null,preventIncremental:null,pipelineContext:null});c(R_,O_),c(R_,t_);var N_=function(){this.group=new Dg,this.uid=eo("viewComponent")};N_.prototype={constructor:N_,init:function(){},render:function(){},dispose:function(){},filterForExposedEvent:null};var F_=N_.prototype;F_.updateView=F_.updateLayout=F_.updateVisual=function(){},ir(N_),or(N_,{registerWhenExtend:!0});var G_=function(){var t=qn();return function(e){var i=t(e),n=e.pipelineContext,r=i.large,a=i.progressiveRender,o=i.large=n.large,s=i.progressiveRender=n.progressiveRender;return!!(r^o||a^s)&&"reset"}},V_=qn(),H_=G_();Zs.prototype={type:"chart",init:function(){},render:function(){},highlight:function(t,e,i,n){$s(t.getData(),n,"emphasis")},downplay:function(t,e,i,n){$s(t.getData(),n,"normal")},remove:function(){this.group.removeAll()},dispose:function(){},incrementalPrepareRender:null,incrementalRender:null,updateTransform:null,filterForExposedEvent:null};var W_=Zs.prototype;W_.updateView=W_.updateLayout=W_.updateVisual=function(t,e,i,n){this.render(t,e,i,n)},ir(Zs,["dispose"]),or(Zs,{registerWhenExtend:!0}),Zs.markUpdateMethod=function(t,e){V_(t).updateMethod=e};var U_={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},X_="\x00__throttleOriginMethod",Y_="\x00__throttleRate",j_="\x00__throttleType",q_={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var i=t.getData(),n=(t.visualColorAccessPath||"itemStyle.color").split("."),r=t.get(n)||t.getColorFromPalette(t.name,null,e.getSeriesCount());i.setVisual("color",r);var a=(t.visualBorderColorAccessPath||"itemStyle.borderColor").split("."),o=t.get(a);if(i.setVisual("borderColor",o),!e.isSeriesFiltered(t)){"function"!=typeof r||r instanceof sy||i.each(function(e){i.setItemVisual(e,"color",r(t.getDataParams(e)))});var s=function(t,e){var i=t.getItemModel(e),r=i.get(n,!0),o=i.get(a,!0);null!=r&&t.setItemVisual(e,"color",r),null!=o&&t.setItemVisual(e,"borderColor",o)};return{dataEach:i.hasItemOption?s:null}}}},Z_={legend:{selector:{all:"全选",inverse:"反选"}},toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}},K_=function(t,e){function i(t,e){if("string"!=typeof t)return t;var i=t;return f(e,function(t,e){i=i.replace(new RegExp("\\{\\s*"+e+"\\s*\\}","g"),t)}),i}function n(t){var e=o.get(t);if(null==e){for(var i=t.split("."),n=Z_.aria,r=0;rs)){var d=r();l=d?i(n("general.withTitle"),{title:d}):n("general.withoutTitle");var p=[],g=s>1?"series.multiple.prefix":"series.single.prefix";l+=i(n(g),{seriesCount:s}),e.eachSeries(function(t,e){if(c>e){var r,o=t.get("name"),l="series."+(s>1?"multiple":"single")+".";r=n(o?l+"withName":l+"withoutName"),r=i(r,{seriesId:t.seriesIndex,seriesName:t.get("name"),seriesType:a(t.subType)});var h=t.getData();window.data=h,r+=h.count()>u?i(n("data.partialData"),{displayCnt:u}):n("data.allData");for(var d=[],f=0;ff){var g=h.getName(f),v=Es(h,f);d.push(i(n(g?"data.withName":"data.withoutName"),{name:g,value:v}))}r+=d.join(n("data.separator.middle"))+n("data.separator.end"),p.push(r)}}),l+=p.join(n("series.multiple.separator.middle"))+n("series.multiple.separator.end"),t.setAttribute("aria-label",l)}}},$_=Math.PI,Q_=function(t,e){e=e||{},s(e,{text:"loading",color:"#c23531",textColor:"#000",maskColor:"rgba(255, 255, 255, 0.8)",zlevel:0});var i=new ty({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4}),n=new ay({shape:{startAngle:-$_/2,endAngle:-$_/2+.1,r:10},style:{stroke:e.color,lineCap:"round",lineWidth:5},zlevel:e.zlevel,z:10001}),r=new ty({style:{fill:"none",text:e.text,textPosition:"right",textDistance:10,textFill:e.textColor},zlevel:e.zlevel,z:10001});n.animateShape(!0).when(1e3,{endAngle:3*$_/2}).start("circularInOut"),n.animateShape(!0).when(1e3,{startAngle:3*$_/2}).delay(300).start("circularInOut");var a=new Dg;return a.add(n),a.add(r),a.add(i),a.resize=function(){var e=t.getWidth()/2,a=t.getHeight()/2;n.setShape({cx:e,cy:a});var o=n.shape.r;r.setShape({x:e-o,y:a-o,width:2*o,height:2*o}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},a.resize(),a},J_=il.prototype;J_.restoreData=function(t,e){t.restoreData(e),this._stageTaskMap.each(function(t){var e=t.overallTask;e&&e.dirty()})},J_.getPerformArgs=function(t,e){if(t.__pipeline){var i=this._pipelineMap.get(t.__pipeline.id),n=i.context,r=!e&&i.progressiveEnabled&&(!n||n.progressiveRender)&&t.__idxInPipeline>i.blockIndex,a=r?i.step:null,o=n&&n.modDataCount,s=null!=o?Math.ceil(o/a):null;return{step:a,modBy:s,modDataCount:o}}},J_.getPipeline=function(t){return this._pipelineMap.get(t)},J_.updateStreamModes=function(t,e){var i=this._pipelineMap.get(t.uid),n=t.getData(),r=n.count(),a=i.progressiveEnabled&&e.incrementalPrepareRender&&r>=i.threshold,o=t.get("large")&&r>=t.get("largeThreshold"),s="mod"===t.get("progressiveChunkMode")?r:null;t.pipelineContext=i.context={progressiveRender:a,modDataCount:s,large:o}},J_.restorePipelines=function(t){var e=this,i=e._pipelineMap=N();t.eachSeries(function(t){var n=t.getProgressive(),r=t.uid;i.set(r,{id:r,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:n&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(n||700),count:0}),pl(e,t,t.dataTask)})},J_.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.ecInstance.getModel(),i=this.api;f(this._allHandlers,function(n){var r=t.get(n.uid)||t.set(n.uid,[]);n.reset&&rl(this,n,r,e,i),n.overallReset&&al(this,n,r,e,i)},this)},J_.prepareView=function(t,e,i,n){var r=t.renderTask,a=r.context;a.model=e,a.ecModel=i,a.api=n,r.__block=!t.incrementalPrepareRender,pl(this,e,r)},J_.performDataProcessorTasks=function(t,e){nl(this,this._dataProcessorHandlers,t,e,{block:!0})},J_.performVisualTasks=function(t,e,i){nl(this,this._visualHandlers,t,e,i)},J_.performSeriesTasks=function(t){var e;t.eachSeries(function(t){e|=t.dataTask.perform()}),this.unfinished|=e},J_.plan=function(){this._pipelineMap.each(function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)})};var tx=J_.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},ex=dl(0);il.wrapStageHandler=function(t,e){return w(t)&&(t={overallReset:t,seriesType:gl(t)}),t.uid=eo("stageHandler"),e&&(t.visualType=e),t};var ix,nx={},rx={};vl(nx,d_),vl(rx,us),nx.eachSeriesByType=nx.eachRawSeriesByType=function(t){ix=t},nx.eachComponent=function(t){"series"===t.mainType&&t.subType&&(ix=t.subType)};var ax=["#37A2DA","#32C5E9","#67E0E3","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#E062AE","#E690D1","#e7bcf3","#9d96f5","#8378EA","#96BFFF"],ox={color:ax,colorLayer:[["#37A2DA","#ffd85c","#fd7b5f"],["#37A2DA","#67E0E3","#FFDB5C","#ff9f7f","#E062AE","#9d96f5"],["#37A2DA","#32C5E9","#9FE6B8","#FFDB5C","#ff9f7f","#fb7293","#e7bcf3","#8378EA","#96BFFF"],ax]},sx="#eee",lx=function(){return{axisLine:{lineStyle:{color:sx}},axisTick:{lineStyle:{color:sx}},axisLabel:{textStyle:{color:sx}},splitLine:{lineStyle:{type:"dashed",color:"#aaa"}},splitArea:{areaStyle:{color:sx}}}},ux=["#dd6b66","#759aa0","#e69d87","#8dc1a9","#ea7e53","#eedd78","#73a373","#73b9bc","#7289ab","#91ca8c","#f49f42"],hx={color:ux,backgroundColor:"#333",tooltip:{axisPointer:{lineStyle:{color:sx},crossStyle:{color:sx}}},legend:{textStyle:{color:sx}},textStyle:{color:sx},title:{textStyle:{color:sx}},toolbox:{iconStyle:{normal:{borderColor:sx}}},dataZoom:{textStyle:{color:sx}},visualMap:{textStyle:{color:sx}},timeline:{lineStyle:{color:sx},itemStyle:{normal:{color:ux[1]}},label:{normal:{textStyle:{color:sx}}},controlStyle:{normal:{color:sx,borderColor:sx}}},timeAxis:lx(),logAxis:lx(),valueAxis:lx(),categoryAxis:lx(),line:{symbol:"circle"},graph:{color:ux},gauge:{title:{textStyle:{color:sx}}},candlestick:{itemStyle:{normal:{color:"#FD1050",color0:"#0CF49B",borderColor:"#FD1050",borderColor0:"#0CF49B"}}}};hx.categoryAxis.splitLine.show=!1,Ky.extend({type:"dataset",defaultOption:{seriesLayoutBy:l_,sourceHeader:null,dimensions:null,source:null},optionUpdated:function(){Uo(this)}}),N_.extend({type:"dataset"});var cx=Gr.extend({type:"ellipse",shape:{cx:0,cy:0,rx:0,ry:0},buildPath:function(t,e){var i=.5522848,n=e.cx,r=e.cy,a=e.rx,o=e.ry,s=a*i,l=o*i;t.moveTo(n-a,r),t.bezierCurveTo(n-a,r-l,n-s,r-o,n,r-o),t.bezierCurveTo(n+s,r-o,n+a,r-l,n+a,r),t.bezierCurveTo(n+a,r+l,n+s,r+o,n,r+o),t.bezierCurveTo(n-s,r+o,n-a,r+l,n-a,r),t.closePath()}}),dx=/[\s,]+/;yl.prototype.parse=function(t,e){e=e||{};var i=ml(t);if(!i)throw new Error("Illegal svg");var n=new Dg;this._root=n;var r=i.getAttribute("viewBox")||"",a=parseFloat(i.getAttribute("width")||e.width),o=parseFloat(i.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(o)&&(o=null),bl(i,n,null,!0);for(var s=i.firstChild;s;)this._parseNode(s,n),s=s.nextSibling;var l,u;if(r){var h=z(r).split(dx);h.length>=4&&(l={x:parseFloat(h[0]||0),y:parseFloat(h[1]||0),width:parseFloat(h[2]),height:parseFloat(h[3])})}if(l&&null!=a&&null!=o&&(u=Cl(l,a,o),!e.ignoreViewBox)){var c=n;n=new Dg,n.add(c),c.scale=u.scale.slice(),c.position=u.position.slice()}return e.ignoreRootClip||null==a||null==o||n.setClipPath(new ty({shape:{x:0,y:0,width:a,height:o}})),{root:n,width:a,height:o,viewBoxRect:l,viewBoxTransform:u} -},yl.prototype._parseNode=function(t,e){var i=t.nodeName.toLowerCase();"defs"===i?this._isDefine=!0:"text"===i&&(this._isText=!0);var n;if(this._isDefine){var r=px[i];if(r){var a=r.call(this,t),o=t.getAttribute("id");o&&(this._defs[o]=a)}}else{var r=fx[i];r&&(n=r.call(this,t,e),e.add(n))}for(var s=t.firstChild;s;)1===s.nodeType&&this._parseNode(s,n),3===s.nodeType&&this._isText&&this._parseText(s,n),s=s.nextSibling;"defs"===i?this._isDefine=!1:"text"===i&&(this._isText=!1)},yl.prototype._parseText=function(t,e){if(1===t.nodeType){var i=t.getAttribute("dx")||0,n=t.getAttribute("dy")||0;this._textX+=parseFloat(i),this._textY+=parseFloat(n)}var r=new Hm({style:{text:t.textContent,transformText:!0},position:[this._textX||0,this._textY||0]});xl(e,r),bl(t,r,this._defs);var a=r.style.fontSize;a&&9>a&&(r.style.fontSize=9,r.scale=r.scale||[1,1],r.scale[0]*=a/9,r.scale[1]*=a/9);var o=r.getBoundingRect();return this._textX+=o.width,e.add(r),r};var fx={g:function(t,e){var i=new Dg;return xl(e,i),bl(t,i,this._defs),i},rect:function(t,e){var i=new ty;return xl(e,i),bl(t,i,this._defs),i.setShape({x:parseFloat(t.getAttribute("x")||0),y:parseFloat(t.getAttribute("y")||0),width:parseFloat(t.getAttribute("width")||0),height:parseFloat(t.getAttribute("height")||0)}),i},circle:function(t,e){var i=new Wm;return xl(e,i),bl(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),r:parseFloat(t.getAttribute("r")||0)}),i},line:function(t,e){var i=new iy;return xl(e,i),bl(t,i,this._defs),i.setShape({x1:parseFloat(t.getAttribute("x1")||0),y1:parseFloat(t.getAttribute("y1")||0),x2:parseFloat(t.getAttribute("x2")||0),y2:parseFloat(t.getAttribute("y2")||0)}),i},ellipse:function(t,e){var i=new cx;return xl(e,i),bl(t,i,this._defs),i.setShape({cx:parseFloat(t.getAttribute("cx")||0),cy:parseFloat(t.getAttribute("cy")||0),rx:parseFloat(t.getAttribute("rx")||0),ry:parseFloat(t.getAttribute("ry")||0)}),i},polygon:function(t,e){var i=t.getAttribute("points");i&&(i=wl(i));var n=new Km({shape:{points:i||[]}});return xl(e,n),bl(t,n,this._defs),n},polyline:function(t,e){var i=new Gr;xl(e,i),bl(t,i,this._defs);var n=t.getAttribute("points");n&&(n=wl(n));var r=new $m({shape:{points:n||[]}});return r},image:function(t,e){var i=new bn;return xl(e,i),bl(t,i,this._defs),i.setStyle({image:t.getAttribute("xlink:href"),x:t.getAttribute("x"),y:t.getAttribute("y"),width:t.getAttribute("width"),height:t.getAttribute("height")}),i},text:function(t,e){var i=t.getAttribute("x")||0,n=t.getAttribute("y")||0,r=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0;this._textX=parseFloat(i)+parseFloat(r),this._textY=parseFloat(n)+parseFloat(a);var o=new Dg;return xl(e,o),bl(t,o,this._defs),o},tspan:function(t,e){var i=t.getAttribute("x"),n=t.getAttribute("y");null!=i&&(this._textX=parseFloat(i)),null!=n&&(this._textY=parseFloat(n));var r=t.getAttribute("dx")||0,a=t.getAttribute("dy")||0,o=new Dg;return xl(e,o),bl(t,o,this._defs),this._textX+=r,this._textY+=a,o},path:function(t,e){var i=t.getAttribute("d")||"",n=Ur(i);return xl(e,n),bl(t,n,this._defs),n}},px={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||0,10),i=parseInt(t.getAttribute("y1")||0,10),n=parseInt(t.getAttribute("x2")||10,10),r=parseInt(t.getAttribute("y2")||0,10),a=new ly(e,i,n,r);return _l(t,a),a},radialgradient:function(){}},gx={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-align":"textAlign","alignment-baseline":"textBaseline"},vx=/url\(\s*#(.*?)\)/,mx=/(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.e,]*)\)/g,yx=/([^\s:;]+)\s*:\s*([^:;]+)/g,_x=N(),xx={registerMap:function(t,e,i){var n;return x(e)?n=e:e.svg?n=[{type:"svg",source:e.svg,specialAreas:e.specialAreas}]:(e.geoJson&&!e.features&&(i=e.specialAreas,e=e.geoJson),n=[{type:"geoJSON",source:e,specialAreas:i}]),f(n,function(t){var e=t.type;"geoJson"===e&&(e=t.type="geoJSON");var i=bx[e];i(t)}),_x.set(t,n)},retrieveMap:function(t){return _x.get(t)}},bx={geoJSON:function(t){var e=t.source;t.geoJSON=b(e)?"undefined"!=typeof JSON&&JSON.parse?JSON.parse(e):new Function("return ("+e+");")():e},svg:function(t){t.svgXML=ml(t.source)}},Sx=O,Mx=f,Ix=w,Cx=S,Tx=Ky.parseClassType,Dx="4.5.0",Ax={zrender:"4.1.2"},kx=1,Px=1e3,Lx=800,Ox=900,zx=5e3,Bx=1e3,Ex=1100,Rx=2e3,Nx=3e3,Fx=3500,Gx=4e3,Vx=5e3,Hx={PROCESSOR:{FILTER:Px,SERIES_FILTER:Lx,STATISTIC:zx},VISUAL:{LAYOUT:Bx,PROGRESSIVE_LAYOUT:Ex,GLOBAL:Rx,CHART:Nx,POST_CHART_LAYOUT:Fx,COMPONENT:Gx,BRUSH:Vx}},Wx="__flagInMainProcess",Ux="__optionUpdated",Xx=/^[a-zA-Z0-9_]+$/;Dl.prototype.on=Tl("on",!0),Dl.prototype.off=Tl("off",!0),Dl.prototype.one=Tl("one",!0),c(Dl,Rp);var Yx=Al.prototype;Yx._onframe=function(){if(!this._disposed){var t=this._scheduler;if(this[Ux]){var e=this[Ux].silent;this[Wx]=!0,Pl(this),jx.update.call(this),this[Wx]=!1,this[Ux]=!1,Bl.call(this,e),El.call(this,e)}else if(t.unfinished){var i=kx,n=this._model,r=this._api;t.unfinished=!1;do{var a=+new Date;t.performSeriesTasks(n),t.performDataProcessorTasks(n),Ol(this,n),t.performVisualTasks(n),Hl(this,this._model,r,"remain"),i-=+new Date-a}while(i>0&&t.unfinished);t.unfinished||this._zr.flush()}}},Yx.getDom=function(){return this._dom},Yx.getZr=function(){return this._zr},Yx.setOption=function(t,e,i){if(!this._disposed){var n;if(Cx(e)&&(i=e.lazyUpdate,n=e.silent,e=e.notMerge),this[Wx]=!0,!this._model||e){var r=new cs(this._api),a=this._theme,o=this._model=new d_;o.scheduler=this._scheduler,o.init(null,null,a,r)}this._model.setOption(t,Qx),i?(this[Ux]={silent:n},this[Wx]=!1):(Pl(this),jx.update.call(this),this._zr.flush(),this[Ux]=!1,this[Wx]=!1,Bl.call(this,n),El.call(this,n))}},Yx.setTheme=function(){console.error("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},Yx.getModel=function(){return this._model},Yx.getOption=function(){return this._model&&this._model.getOption()},Yx.getWidth=function(){return this._zr.getWidth()},Yx.getHeight=function(){return this._zr.getHeight()},Yx.getDevicePixelRatio=function(){return this._zr.painter.dpr||window.devicePixelRatio||1},Yx.getRenderedCanvas=function(t){if(gp.canvasSupported){t=t||{},t.pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor");var e=this._zr;return e.painter.getRenderedCanvas(t)}},Yx.getSvgDataUrl=function(){if(gp.svgSupported){var t=this._zr,e=t.storage.getDisplayList();return f(e,function(t){t.stopAnimation(!0)}),t.painter.pathToDataUrl()}},Yx.getDataURL=function(t){if(!this._disposed){t=t||{};var e=t.excludeComponents,i=this._model,n=[],r=this;Mx(e,function(t){i.eachComponent({mainType:t},function(t){var e=r._componentsMap[t.__viewId];e.group.ignore||(n.push(e),e.group.ignore=!0)})});var a="svg"===this._zr.painter.getType()?this.getSvgDataUrl():this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return Mx(n,function(t){t.group.ignore=!1}),a}},Yx.getConnectedDataURL=function(t){if(!this._disposed&&gp.canvasSupported){var e=this.group,i=Math.min,r=Math.max,a=1/0;if(rw[e]){var o=a,s=a,l=-a,u=-a,h=[],c=t&&t.pixelRatio||1;f(nw,function(a){if(a.group===e){var c=a.getRenderedCanvas(n(t)),d=a.getDom().getBoundingClientRect();o=i(d.left,o),s=i(d.top,s),l=r(d.right,l),u=r(d.bottom,u),h.push({dom:c,left:d.left,top:d.top})}}),o*=c,s*=c,l*=c,u*=c;var d=l-o,p=u-s,g=Cp();g.width=d,g.height=p;var v=zn(g);return t.connectedBackgroundColor&&v.add(new ty({shape:{x:0,y:0,width:d,height:p},style:{fill:t.connectedBackgroundColor}})),Mx(h,function(t){var e=new bn({style:{x:t.left*c-o,y:t.top*c-s,image:t.dom}});v.add(e)}),v.refreshImmediately(),g.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}},Yx.convertToPixel=_(kl,"convertToPixel"),Yx.convertFromPixel=_(kl,"convertFromPixel"),Yx.containPixel=function(t,e){if(!this._disposed){var i,n=this._model;return t=Zn(n,t),f(t,function(t,n){n.indexOf("Models")>=0&&f(t,function(t){var r=t.coordinateSystem;if(r&&r.containPoint)i|=!!r.containPoint(e);else if("seriesModels"===n){var a=this._chartsMap[t.__viewId];a&&a.containPoint&&(i|=a.containPoint(e,t))}},this)},this),!!i}},Yx.getVisual=function(t,e){var i=this._model;t=Zn(i,t,{defaultMainType:"series"});var n=t.seriesModel,r=n.getData(),a=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?r.indexOfRawIndex(t.dataIndex):null;return null!=a?r.getItemVisual(a,e):r.getVisual(e)},Yx.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},Yx.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]};var jx={prepareAndUpdate:function(t){Pl(this),jx.update.call(this,t)},update:function(t){var e=this._model,i=this._api,n=this._zr,r=this._coordSysMgr,a=this._scheduler;if(e){a.restoreData(e,t),a.performSeriesTasks(e),r.create(e,i),a.performDataProcessorTasks(e,t),Ol(this,e),r.update(e,i),Fl(e),a.performVisualTasks(e,t),Gl(this,e,i,t);var o=e.get("backgroundColor")||"transparent";if(gp.canvasSupported)n.setBackgroundColor(o);else{var s=qe(o);o=ni(s,"rgb"),0===s[3]&&(o="transparent")}Wl(e,i)}},updateTransform:function(t){var e=this._model,i=this,n=this._api;if(e){var r=[];e.eachComponent(function(a,o){var s=i.getViewOfComponentModel(o);if(s&&s.__alive)if(s.updateTransform){var l=s.updateTransform(o,e,n,t);l&&l.update&&r.push(s)}else r.push(s)});var a=N();e.eachSeries(function(r){var o=i._chartsMap[r.__viewId];if(o.updateTransform){var s=o.updateTransform(r,e,n,t);s&&s.update&&a.set(r.uid,1)}else a.set(r.uid,1)}),Fl(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0,dirtyMap:a}),Hl(i,e,n,t,a),Wl(e,this._api)}},updateView:function(t){var e=this._model;e&&(Zs.markUpdateMethod(t,"updateView"),Fl(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0}),Gl(this,this._model,this._api,t),Wl(e,this._api))},updateVisual:function(t){jx.update.call(this,t)},updateLayout:function(t){jx.update.call(this,t)}};Yx.resize=function(t){if(!this._disposed){this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var i=e.resetOption("media"),n=t&&t.silent;this[Wx]=!0,i&&Pl(this),jx.update.call(this),this[Wx]=!1,Bl.call(this,n),El.call(this,n)}}},Yx.showLoading=function(t,e){if(!this._disposed&&(Cx(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),iw[t])){var i=iw[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},Yx.hideLoading=function(){this._disposed||(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},Yx.makeActionFromEvent=function(t){var e=o({},t);return e.type=Kx[t.type],e},Yx.dispatchAction=function(t,e){if(!this._disposed&&(Cx(e)||(e={silent:!!e}),Zx[t.type]&&this._model)){if(this[Wx])return void this._pendingActions.push(t);zl.call(this,t,e.silent),e.flush?this._zr.flush(!0):e.flush!==!1&&gp.browser.weChat&&this._throttledZrFlush(),Bl.call(this,e.silent),El.call(this,e.silent)}},Yx.appendData=function(t){if(!this._disposed){var e=t.seriesIndex,i=this.getModel(),n=i.getSeriesByIndex(e);n.appendData(t),this._scheduler.unfinished=!0}},Yx.on=Tl("on",!1),Yx.off=Tl("off",!1),Yx.one=Tl("one",!1);var qx=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];Yx._initEvents=function(){Mx(qx,function(t){var e=function(e){var i,n=this.getModel(),r=e.target,a="globalout"===t;if(a)i={};else if(r&&null!=r.dataIndex){var s=r.dataModel||n.getSeriesByIndex(r.seriesIndex);i=s&&s.getDataParams(r.dataIndex,r.dataType,r)||{}}else r&&r.eventData&&(i=o({},r.eventData));if(i){var l=i.componentType,u=i.componentIndex;("markLine"===l||"markPoint"===l||"markArea"===l)&&(l="series",u=i.seriesIndex);var h=l&&null!=u&&n.getComponent(l,u),c=h&&this["series"===h.mainType?"_chartsMap":"_componentsMap"][h.__viewId];i.event=e,i.type=t,this._ecEventProcessor.eventInfo={targetEl:r,packedEvent:i,model:h,view:c},this.trigger(t,i)}};e.zrEventfulCallAtLast=!0,this._zr.on(t,e,this)},this),Mx(Kx,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},Yx.isDisposed=function(){return this._disposed},Yx.clear=function(){this._disposed||this.setOption({series:[]},!0)},Yx.dispose=function(){if(!this._disposed){this._disposed=!0,$n(this.getDom(),sw,"");var t=this._api,e=this._model;Mx(this._componentsViews,function(i){i.dispose(e,t)}),Mx(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete nw[this.id]}},c(Al,Rp),ql.prototype={constructor:ql,normalizeQuery:function(t){var e={},i={},n={};if(b(t)){var r=Tx(t);e.mainType=r.main||null,e.subType=r.sub||null}else{var a=["Index","Name","Id"],o={name:1,dataIndex:1,dataType:1};f(t,function(t,r){for(var s=!1,l=0;l0&&h===r.length-u.length){var c=r.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}o.hasOwnProperty(r)&&(i[r]=t,s=!0),s||(n[r]=t)})}return{cptQuery:e,dataQuery:i,otherQuery:n}},filter:function(t,e){function i(t,e,i,n){return null==t[i]||e[n||i]===t[i]}var n=this.eventInfo;if(!n)return!0;var r=n.targetEl,a=n.packedEvent,o=n.model,s=n.view;if(!o||!s)return!0;var l=e.cptQuery,u=e.dataQuery;return i(l,o,"mainType")&&i(l,o,"subType")&&i(l,o,"index","componentIndex")&&i(l,o,"name")&&i(l,o,"id")&&i(u,a,"name")&&i(u,a,"dataIndex")&&i(u,a,"dataType")&&(!s.filterForExposedEvent||s.filterForExposedEvent(t,e.otherQuery,r,a))},afterTrigger:function(){this.eventInfo=null}};var Zx={},Kx={},$x=[],Qx=[],Jx=[],tw=[],ew={},iw={},nw={},rw={},aw=new Date-0,ow=new Date-0,sw="_echarts_instance_",lw=Ql;hu(Rx,q_),nu(C_),ru(Ox,T_),du("default",Q_),ou({type:"highlight",event:"highlight",update:"highlight"},G),ou({type:"downplay",event:"downplay",update:"downplay"},G),iu("light",ox),iu("dark",hx);var uw={};wu.prototype={constructor:wu,add:function(t){return this._add=t,this},update:function(t){return this._update=t,this},remove:function(t){return this._remove=t,this},execute:function(){var t,e=this._old,i=this._new,n={},r={},a=[],o=[];for(bu(e,n,a,"_oldKeyGetter",this),bu(i,r,o,"_newKeyGetter",this),t=0;th;h++)this._add&&this._add(l[h]);else this._add&&this._add(l)}}}};var hw=N(["tooltip","label","itemName","itemId","seriesName"]),cw=S,dw="undefined",fw=-1,pw="e\x00\x00",gw={"float":typeof Float64Array===dw?Array:Float64Array,"int":typeof Int32Array===dw?Array:Int32Array,ordinal:Array,number:Array,time:Array},vw=typeof Uint32Array===dw?Array:Uint32Array,mw=typeof Int32Array===dw?Array:Int32Array,yw=typeof Uint16Array===dw?Array:Uint16Array,_w=["hasItemOption","_nameList","_idList","_invertedIndicesMap","_rawData","_chunkSize","_chunkCount","_dimValueGetter","_count","_rawCount","_nameDimIdx","_idDimIdx"],xw=["_extent","_approximateExtent","_rawExtent"],ww=function(t,e){t=t||["x","y"];for(var i={},n=[],r={},a=0;ah;h++){var c=r[h];o[c]||(o[c]=Fu()),n[c]||(n[c]=[]),ku(n,this._dimensionInfos[c],i,u,l),this._chunkCount=n[c].length}for(var d=new Array(a),f=s;l>f;f++){for(var p=f-s,g=Math.floor(f/i),v=f%i,m=0;a>m;m++){var c=r[m],y=this._dimValueGetterArrayRows(t[p]||d,c,p,m);n[c][g][v]=y;var _=o[c];y<_[0]&&(_[0]=y),y>_[1]&&(_[1]=y)}e&&(this._nameList[f]=e[p])}this._rawCount=this._count=l,this._extent={},Pu(this)},bw._initDataFromProvider=function(t,e){if(!(t>=e)){for(var i,n=this._chunkSize,r=this._rawData,a=this._storage,o=this.dimensions,s=o.length,l=this._dimensionInfos,u=this._nameList,h=this._idList,c=this._rawExtent,d=this._nameRepeatCount={},f=this._chunkCount,p=0;s>p;p++){var g=o[p];c[g]||(c[g]=Fu());var v=l[g];0===v.otherDims.itemName&&(i=this._nameDimIdx=p),0===v.otherDims.itemId&&(this._idDimIdx=p),a[g]||(a[g]=[]),ku(a,v,n,f,e),this._chunkCount=a[g].length}for(var m=new Array(s),y=t;e>y;y++){m=r.getItem(y,m);for(var _=Math.floor(y/n),x=y%n,w=0;s>w;w++){var g=o[w],b=a[g][_],S=this._dimValueGetter(m,g,y,w);b[x]=S;var M=c[g];SM[1]&&(M[1]=S)}if(!r.pure){var I=u[y];if(m&&null==I)if(null!=m.name)u[y]=I=m.name;else if(null!=i){var C=o[i],T=a[C][_];if(T){I=T[x];var D=l[C].ordinalMeta;D&&D.categories.length&&(I=D.categories[I])}}var A=null==m?null:m.id;null==A&&null!=I&&(d[I]=d[I]||0,A=I,d[I]>0&&(A+="__ec__"+d[I]),d[I]++),null!=A&&(h[y]=A)}}!r.persistent&&r.clean&&r.clean(),this._rawCount=this._count=e,this._extent={},Pu(this)}},bw.count=function(){return this._count},bw.getIndices=function(){var t,e=this._indices;if(e){var i=e.constructor,n=this._count;if(i===Array){t=new i(n);for(var r=0;n>r;r++)t[r]=e[r]}else t=new i(e.buffer,0,n)}else for(var i=Tu(this),t=new i(this.count()),r=0;r=0&&e=0&&en;n++)i.push(this.get(t[n],e));return i},bw.hasValue=function(t){for(var e=this._dimensionsSummary.dataDimsOnCoord,i=0,n=e.length;n>i;i++)if(isNaN(this.get(e[i],t)))return!1;return!0},bw.getDataExtent=function(t){t=this.getDimension(t);var e=this._storage[t],i=Fu();if(!e)return i;var n,r=this.count(),a=!this._indices;if(a)return this._rawExtent[t].slice();if(n=this._extent[t])return n.slice();n=i;for(var o=n[0],s=n[1],l=0;r>l;l++){var u=this._getFast(t,this.getRawIndex(l));o>u&&(o=u),u>s&&(s=u)}return n=[o,s],this._extent[t]=n,n},bw.getApproximateExtent=function(t){return t=this.getDimension(t),this._approximateExtent[t]||this.getDataExtent(t)},bw.setApproximateExtent=function(t,e){e=this.getDimension(e),this._approximateExtent[e]=t.slice()},bw.getCalculationInfo=function(t){return this._calculationInfo[t]},bw.setCalculationInfo=function(t,e){cw(t)?o(this._calculationInfo,t):this._calculationInfo[t]=e},bw.getSum=function(t){var e=this._storage[t],i=0;if(e)for(var n=0,r=this.count();r>n;n++){var a=this.get(t,n);isNaN(a)||(i+=a)}return i},bw.getMedian=function(t){var e=[];this.each(t,function(t){isNaN(t)||e.push(t)});var i=[].concat(e).sort(function(t,e){return t-e}),n=this.count();return 0===n?0:n%2===1?i[(n-1)/2]:(i[n/2]+i[n/2-1])/2},bw.rawIndexOf=function(t,e){var i=t&&this._invertedIndicesMap[t],n=i[e];return null==n||isNaN(n)?fw:n},bw.indexOfName=function(t){for(var e=0,i=this.count();i>e;e++)if(this.getName(e)===t)return e;return-1},bw.indexOfRawIndex=function(t){if(t>=this._rawCount||0>t)return-1;if(!this._indices)return t;var e=this._indices,i=e[t];if(null!=i&&i=n;){var a=(n+r)/2|0;if(e[a]t))return a;r=a-1}}return-1},bw.indicesOfNearest=function(t,e,i){var n=this._storage,r=n[t],a=[];if(!r)return a;null==i&&(i=1/0);for(var o=Number.MAX_VALUE,s=-1,l=0,u=this.count();u>l;l++){var h=e-this.get(t,l),c=Math.abs(h);i>=h&&o>=c&&((o>c||h>=0&&0>s)&&(o=c,s=h,a.length=0),a.push(l))}return a},bw.getRawIndex=Ou,bw.getRawDataItem=function(t){if(this._rawData.persistent)return this._rawData.getItem(this.getRawIndex(t));for(var e=[],i=0;io;o++)s[o]=this.get(t[o],a);s[o]=a,e.apply(i,s)}}},bw.filterSelf=function(t,e,i,n){if(this._count){"function"==typeof t&&(n=i,i=e,e=t,t=[]),i=i||n||this,t=p(Eu(t),this.getDimension,this);for(var r=this.count(),a=Tu(this),o=new a(r),s=[],l=t.length,u=0,h=t[0],c=0;r>c;c++){var d,f=this.getRawIndex(c);if(0===l)d=e.call(i,c);else if(1===l){var g=this._getFast(h,f);d=e.call(i,g,c)}else{for(var v=0;l>v;v++)s[v]=this._getFast(h,f);s[v]=c,d=e.apply(i,s)}d&&(o[u++]=f)}return r>u&&(this._indices=o),this._count=u,this._extent={},this.getRawIndex=this._indices?zu:Ou,this}},bw.selectRange=function(t){if(this._count){var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(i);var n=e.length;if(n){var r=this.count(),a=Tu(this),o=new a(r),s=0,l=e[0],u=t[l][0],h=t[l][1],c=!1;if(!this._indices){var d=0;if(1===n){for(var f=this._storage[e[0]],p=0;pm;m++){var y=g[m];(y>=u&&h>=y||isNaN(y))&&(o[s++]=d),d++}c=!0}else if(2===n){for(var f=this._storage[l],_=this._storage[e[1]],x=t[e[1]][0],w=t[e[1]][1],p=0;pm;m++){var y=g[m],S=b[m];(y>=u&&h>=y||isNaN(y))&&(S>=x&&w>=S||isNaN(S))&&(o[s++]=d),d++}c=!0}}if(!c)if(1===n)for(var m=0;r>m;m++){var M=this.getRawIndex(m),y=this._getFast(l,M);(y>=u&&h>=y||isNaN(y))&&(o[s++]=M)}else for(var m=0;r>m;m++){for(var I=!0,M=this.getRawIndex(m),p=0;n>p;p++){var C=e[p],y=this._getFast(i,M);(yt[C][1])&&(I=!1)}I&&(o[s++]=this.getRawIndex(m))}return r>s&&(this._indices=o),this._count=s,this._extent={},this.getRawIndex=this._indices?zu:Ou,this}}},bw.mapArray=function(t,e,i,n){"function"==typeof t&&(n=i,i=e,e=t,t=[]),i=i||n||this;var r=[];return this.each(t,function(){r.push(e&&e.apply(this,arguments))},i),r},bw.map=function(t,e,i,n){i=i||n||this,t=p(Eu(t),this.getDimension,this);var r=Ru(this,t);r._indices=this._indices,r.getRawIndex=r._indices?zu:Ou;for(var a=r._storage,o=[],s=this._chunkSize,l=t.length,u=this.count(),h=[],c=r._rawExtent,d=0;u>d;d++){for(var f=0;l>f;f++)h[f]=this.get(t[f],d);h[l]=d;var g=e&&e.apply(i,h);if(null!=g){"object"!=typeof g&&(o[0]=g,g=o);for(var v=this.getRawIndex(d),m=Math.floor(v/s),y=v%s,_=0;_b[1]&&(b[1]=w)}}}return r},bw.downSample=function(t,e,i,n){for(var r=Ru(this,[t]),a=r._storage,o=[],s=Math.floor(1/e),l=a[t],u=this.count(),h=this._chunkSize,c=r._rawExtent[t],d=new(Tu(this))(u),f=0,p=0;u>p;p+=s){s>u-p&&(s=u-p,o.length=s);for(var g=0;s>g;g++){var v=this.getRawIndex(p+g),m=Math.floor(v/h),y=v%h;o[g]=l[m][y]}var _=i(o),x=this.getRawIndex(Math.min(p+n(o,_)||0,u-1)),w=Math.floor(x/h),b=x%h;l[w][b]=_,_c[1]&&(c[1]=_),d[f++]=x}return r._count=f,r._indices=d,r.getRawIndex=zu,r},bw.getItemModel=function(t){var e=this.hostModel;return new Qa(this.getRawDataItem(t),e,e&&e.ecModel)},bw.diff=function(t){var e=this;return new wu(t?t.getIndices():[],this.getIndices(),function(e){return Bu(t,e)},function(t){return Bu(e,t)})},bw.getVisual=function(t){var e=this._visual;return e&&e[t]},bw.setVisual=function(t,e){if(cw(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},bw.setLayout=function(t,e){if(cw(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},bw.getLayout=function(t){return this._layout[t]},bw.getItemLayout=function(t){return this._itemLayouts[t]},bw.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?o(this._itemLayouts[t]||{},e):e},bw.clearItemLayouts=function(){this._itemLayouts.length=0},bw.getItemVisual=function(t,e,i){var n=this._itemVisuals[t],r=n&&n[e];return null!=r||i?r:this.getVisual(e)},bw.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{},r=this.hasItemVisual;if(this._itemVisuals[t]=n,cw(e))for(var a in e)e.hasOwnProperty(a)&&(n[a]=e[a],r[a]=!0);else n[e]=i,r[e]=!0},bw.clearAllVisual=function(){this._visual={},this._itemVisuals=[],this.hasItemVisual={}};var Sw=function(t){t.seriesIndex=this.seriesIndex,t.dataIndex=this.dataIndex,t.dataType=this.dataType};bw.setItemGraphicEl=function(t,e){var i=this.hostModel;e&&(e.dataIndex=t,e.dataType=this.dataType,e.seriesIndex=i&&i.seriesIndex,"group"===e.type&&e.traverse(Sw,e)),this._graphicEls[t]=e},bw.getItemGraphicEl=function(t){return this._graphicEls[t]},bw.eachItemGraphicEl=function(t,e){f(this._graphicEls,function(i,n){i&&t&&t.call(e,i,n)})},bw.cloneShallow=function(t){if(!t){var e=p(this.dimensions,this.getDimensionInfo,this);t=new ww(e,this.hostModel)}if(t._storage=this._storage,Au(t,this),this._indices){var i=this._indices.constructor;t._indices=new i(this._indices)}else t._indices=null;return t.getRawIndex=t._indices?zu:Ou,t},bw.wrapMethod=function(t,e){var i=this[t];"function"==typeof i&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=i.apply(this,arguments);return e.apply(this,[t].concat(P(arguments)))})},bw.TRANSFERABLE_METHODS=["cloneShallow","downSample","map"],bw.CHANGABLE_METHODS=["filterSelf","selectRange"];var Mw=function(t,e){return e=e||{},Gu(e.coordDimensions||[],t,{dimsDef:e.dimensionsDefine||t.dimensionsDefine,encodeDef:e.encodeDefine||t.encodeDefine,dimCount:e.dimensionsCount,generateCoord:e.generateCoord,generateCoordCount:e.generateCoordCount})};Zu.prototype.parse=function(t){return t},Zu.prototype.getSetting=function(t){return this._setting[t]},Zu.prototype.contain=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},Zu.prototype.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},Zu.prototype.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},Zu.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},Zu.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},Zu.prototype.getExtent=function(){return this._extent.slice()},Zu.prototype.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},Zu.prototype.isBlank=function(){return this._isBlank},Zu.prototype.setBlank=function(t){this._isBlank=t},Zu.prototype.getLabel=null,ir(Zu),or(Zu,{registerWhenExtend:!0}),Ku.createByAxisModel=function(t){var e=t.option,i=e.data,n=i&&p(i,Qu);return new Ku({categories:n,needCollect:!n,deduplication:e.dedplication!==!1})};var Iw=Ku.prototype;Iw.getOrdinal=function(t){return $u(this).get(t)},Iw.parseAndCollect=function(t){var e,i=this._needCollect;if("string"!=typeof t&&!i)return t;if(i&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var n=$u(this);return e=n.get(t),null==e&&(i?(e=this.categories.length,this.categories[e]=t,n.set(t,e)):e=0/0),e};var Cw=Zu.prototype,Tw=Zu.extend({type:"ordinal",init:function(t,e){(!t||x(t))&&(t=new Ku({categories:t})),this._ordinalMeta=t,this._extent=e||[0,t.categories.length-1]},parse:function(t){return"string"==typeof t?this._ordinalMeta.getOrdinal(t):Math.round(t)},contain:function(t){return t=this.parse(t),Cw.contain.call(this,t)&&null!=this._ordinalMeta.categories[t]},normalize:function(t){return Cw.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(Cw.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){return this.isBlank()?void 0:this._ordinalMeta.categories[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},getOrdinalMeta:function(){return this._ordinalMeta},niceTicks:G,niceExtent:G});Tw.create=function(){return new Tw};var Dw=so,Aw=so,kw=Zu.extend({type:"interval",_interval:0,_intervalPrecision:2,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),kw.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=th(t)},getTicks:function(){return nh(this._interval,this._extent,this._niceExtent,this._intervalPrecision)},getLabel:function(t,e){if(null==t)return"";var i=e&&e.precision;return null==i?i=ho(t)||0:"auto"===i&&(i=this._intervalPrecision),t=Aw(t,i,!0),So(t)},niceTicks:function(t,e,i){t=t||5;var n=this._extent,r=n[1]-n[0];if(isFinite(r)){0>r&&(r=-r,n.reverse());var a=Ju(n,t,e,i);this._intervalPrecision=a.intervalPrecision,this._interval=a.interval,this._niceExtent=a.niceTickExtent}},niceExtent:function(t){var e=this._extent;if(e[0]===e[1])if(0!==e[0]){var i=e[0];t.fixMax?e[0]-=i/2:(e[1]+=i/2,e[0]-=i/2)}else e[1]=1;var n=e[1]-e[0];isFinite(n)||(e[0]=0,e[1]=1),this.niceTicks(t.splitNumber,t.minInterval,t.maxInterval);var r=this._interval;t.fixMin||(e[0]=Aw(Math.floor(e[0]/r)*r)),t.fixMax||(e[1]=Aw(Math.ceil(e[1]/r)*r))}});kw.create=function(){return new kw};var Pw="__ec_stack_",Lw=.5,Ow="undefined"!=typeof Float32Array?Float32Array:Array,zw=({seriesType:"bar",plan:G_(),reset:function(t){function e(t,e){for(var i,c=t.count,d=new Ow(2*c),f=new Ow(c),p=[],g=[],v=0,m=0;null!=(i=t.next());)g[u]=e.get(o,i),g[1-u]=e.get(s,i),p=n.dataToPoint(g,null,p),d[v++]=p[0],d[v++]=p[1],f[m++]=i;e.setLayout({largePoints:d,largeDataIndices:f,barWidth:h,valueAxisStart:fh(r,a,!1),valueAxisHorizontal:l})}if(ch(t)&&dh(t)){var i=t.getData(),n=t.coordinateSystem,r=n.getBaseAxis(),a=n.getOtherAxis(r),o=i.mapDimension(a.dim),s=i.mapDimension(r.dim),l=a.isHorizontal(),u=l?0:1,h=hh(lh([t]),r,t).width; -return h>Lw||(h=Lw),{progress:e}}}},kw.prototype),Bw=Math.ceil,Ew=Math.floor,Rw=1e3,Nw=60*Rw,Fw=60*Nw,Gw=24*Fw,Vw=function(t,e,i,n){for(;n>i;){var r=i+n>>>1;t[r][1]a&&(a=e),null!=i&&a>i&&(a=i);var o=Ww.length,s=Vw(Ww,a,0,o),l=Ww[Math.min(s,o-1)],u=l[1];if("year"===l[0]){var h=r/u,c=_o(h/t,!0);u*=c}var d=this.getSetting("useUTC")?0:60*new Date(+n[0]||+n[1]).getTimezoneOffset()*1e3,f=[Math.round(Bw((n[0]-d)/u)*u+d),Math.round(Ew((n[1]-d)/u)*u+d)];ih(f,n),this._stepLvl=l,this._interval=u,this._niceExtent=f},parse:function(t){return+vo(t)}});f(["contain","normalize"],function(t){Hw.prototype[t]=function(e){return zw[t].call(this,this.parse(e))}});var Ww=[["hh:mm:ss",Rw],["hh:mm:ss",5*Rw],["hh:mm:ss",10*Rw],["hh:mm:ss",15*Rw],["hh:mm:ss",30*Rw],["hh:mm\nMM-dd",Nw],["hh:mm\nMM-dd",5*Nw],["hh:mm\nMM-dd",10*Nw],["hh:mm\nMM-dd",15*Nw],["hh:mm\nMM-dd",30*Nw],["hh:mm\nMM-dd",Fw],["hh:mm\nMM-dd",2*Fw],["hh:mm\nMM-dd",6*Fw],["hh:mm\nMM-dd",12*Fw],["MM-dd\nyyyy",Gw],["MM-dd\nyyyy",2*Gw],["MM-dd\nyyyy",3*Gw],["MM-dd\nyyyy",4*Gw],["MM-dd\nyyyy",5*Gw],["MM-dd\nyyyy",6*Gw],["week",7*Gw],["MM-dd\nyyyy",10*Gw],["week",14*Gw],["week",21*Gw],["month",31*Gw],["week",42*Gw],["month",62*Gw],["week",70*Gw],["quarter",95*Gw],["month",31*Gw*4],["month",31*Gw*5],["half-year",380*Gw/2],["month",31*Gw*8],["month",31*Gw*10],["year",380*Gw]];Hw.create=function(t){return new Hw({useUTC:t.ecModel.get("useUTC")})};var Uw=Zu.prototype,Xw=kw.prototype,Yw=ho,jw=so,qw=Math.floor,Zw=Math.ceil,Kw=Math.pow,$w=Math.log,Qw=Zu.extend({type:"log",base:10,$constructor:function(){Zu.apply(this,arguments),this._originalScale=new kw},getTicks:function(){var t=this._originalScale,e=this._extent,i=t.getExtent();return p(Xw.getTicks.call(this),function(n){var r=so(Kw(this.base,n));return r=n===e[0]&&t.__fixMin?ph(r,i[0]):r,r=n===e[1]&&t.__fixMax?ph(r,i[1]):r},this)},getLabel:Xw.getLabel,scale:function(t){return t=Uw.scale.call(this,t),Kw(this.base,t)},setExtent:function(t,e){var i=this.base;t=$w(t)/$w(i),e=$w(e)/$w(i),Xw.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,e=Uw.getExtent.call(this);e[0]=Kw(t,e[0]),e[1]=Kw(t,e[1]);var i=this._originalScale,n=i.getExtent();return i.__fixMin&&(e[0]=ph(e[0],n[0])),i.__fixMax&&(e[1]=ph(e[1],n[1])),e},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=$w(t[0])/$w(e),t[1]=$w(t[1])/$w(e),Uw.unionExtent.call(this,t)},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(1/0===i||0>=i)){var n=mo(i),r=t/i*n;for(.5>=r&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var a=[so(Zw(e[0]/n)*n),so(qw(e[1]/n)*n)];this._interval=n,this._niceExtent=a}},niceExtent:function(t){Xw.niceExtent.call(this,t);var e=this._originalScale;e.__fixMin=t.fixMin,e.__fixMax=t.fixMax}});f(["contain","normalize"],function(t){Qw.prototype[t]=function(e){return e=$w(e)/$w(this.base),Uw[t].call(this,e)}}),Qw.create=function(){return new Qw};var Jw={getMin:function(t){var e=this.option,i=t||null==e.rangeStart?e.min:e.rangeStart;return this.axis&&null!=i&&"dataMin"!==i&&"function"!=typeof i&&!T(i)&&(i=this.axis.scale.parse(i)),i},getMax:function(t){var e=this.option,i=t||null==e.rangeEnd?e.max:e.rangeEnd;return this.axis&&null!=i&&"dataMax"!==i&&"function"!=typeof i&&!T(i)&&(i=this.axis.scale.parse(i)),i},getNeedCrossZero:function(){var t=this.option;return null!=t.rangeStart||null!=t.rangeEnd?!1:!t.scale},getCoordSysModel:G,setRange:function(t,e){this.option.rangeStart=t,this.option.rangeEnd=e},resetRange:function(){this.option.rangeStart=this.option.rangeEnd=null}},tb=ta({type:"triangle",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,r=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+r,n+a),t.lineTo(i-r,n+a),t.closePath()}}),eb=ta({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,r=e.width/2,a=e.height/2;t.moveTo(i,n-a),t.lineTo(i+r,n),t.lineTo(i,n+a),t.lineTo(i-r,n),t.closePath()}}),ib=ta({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,r=e.width/5*3,a=Math.max(r,e.height),o=r/2,s=o*o/(a-o),l=n-a+o+s,u=Math.asin(s/o),h=Math.cos(u)*o,c=Math.sin(u),d=Math.cos(u),f=.6*o,p=.7*o;t.moveTo(i-h,l+s),t.arc(i,l,o,Math.PI-u,2*Math.PI+u),t.bezierCurveTo(i+h-c*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-h+c*f,l+s+d*f,i-h,l+s),t.closePath()}}),nb=ta({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.height,n=e.width,r=e.x,a=e.y,o=n/3*2;t.moveTo(r,a),t.lineTo(r+o,a+i),t.lineTo(r,a+i/4*3),t.lineTo(r-o,a+i),t.lineTo(r,a),t.closePath()}}),rb={line:iy,rect:ty,roundRect:ty,square:ty,circle:Wm,diamond:eb,pin:ib,arrow:nb,triangle:tb},ab={line:function(t,e,i,n,r){r.x1=t,r.y1=e+n/2,r.x2=t+i,r.y2=e+n/2},rect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r.height=n},roundRect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r.height=n,r.r=Math.min(i,n)/4},square:function(t,e,i,n,r){var a=Math.min(i,n);r.x=t,r.y=e,r.width=a,r.height=a},circle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.r=Math.min(i,n)/2},diamond:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r.height=n},pin:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r.height=n},arrow:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r.height=n},triangle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r.height=n}},ob={};f(rb,function(t,e){ob[e]=new t});var sb=ta({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},calculateTextPosition:function(t,e,i){var n=Ui(t,e,i),r=this.shape;return r&&"pin"===r.symbolType&&"inside"===e.textPosition&&(n.y=i.y+.4*i.height),n},buildPath:function(t,e,i){var n=e.symbolType;if("none"!==n){var r=ob[n];r||(n="rect",r=ob[n]),ab[n](e.x,e.y,e.width,e.height,r.shape),r.buildPath(t,r.shape,i)}}}),lb={isDimensionStacked:Uu,enableDataStack:Wu,getStackedDimension:Xu},ub=(Object.freeze||Object)({createList:Dh,getLayoutRect:Bo,dataStack:lb,createScale:Ah,mixinAxisModelCommonMethods:kh,completeDimensions:Gu,createDimensions:Mw,createSymbol:Th}),hb=1e-8;Oh.prototype={constructor:Oh,properties:null,getBoundingRect:function(){var t=this._rect;if(t)return t;for(var e=Number.MAX_VALUE,i=[e,e],n=[-e,-e],r=[],a=[],o=this.geometries,s=0;sn;n++)if("polygon"===i[n].type){var a=i[n].exterior,o=i[n].interiors;if(Lh(a,t[0],t[1])){for(var s=0;s<(o?o.length:0);s++)if(Lh(o[s]))continue t;return!0}}return!1},transformTo:function(t,e,i,n){var r=this.getBoundingRect(),a=r.width/r.height;i?n||(n=i/a):i=a*n;for(var o=new xi(t,e,i,n),s=r.calculateTransform(o),l=this.geometries,u=0;u0}),function(t){var e=t.properties,i=t.geometry,n=i.coordinates,r=[];"Polygon"===i.type&&r.push({type:"polygon",exterior:n[0],interiors:n.slice(1)}),"MultiPolygon"===i.type&&f(n,function(t){t[0]&&r.push({type:"polygon",exterior:t[0],interiors:t.slice(1)})});var a=new Oh(e.name,r,e.cp);return a.properties=e,a})},db=qn(),fb=[0,1],pb=function(t,e,i){this.dim=t,this.scale=e,this._extent=i||[0,0],this.inverse=!1,this.onBand=!1};pb.prototype={constructor:pb,contain:function(t){var e=this._extent,i=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return t>=i&&n>=t},containData:function(t){return this.contain(this.dataToCoord(t))},getExtent:function(){return this._extent.slice()},getPixelPrecision:function(t){return co(t||this.scale.getExtent(),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,e){var i=this._extent,n=this.scale;return t=n.normalize(t),this.onBand&&"ordinal"===n.type&&(i=i.slice(),Kh(i,n.count())),ao(t,fb,i,e)},coordToData:function(t,e){var i=this._extent,n=this.scale;this.onBand&&"ordinal"===n.type&&(i=i.slice(),Kh(i,n.count()));var r=ao(t,i,fb,e);return this.scale.scale(r)},pointToData:function(){},getTicksCoords:function(t){t=t||{};var e=t.tickModel||this.getTickModel(),i=Rh(this,e),n=i.ticks,r=p(n,function(t){return{coord:this.dataToCoord(t),tickValue:t}},this),a=e.get("alignWithLabel");return $h(this,r,a,t.clamp),r},getViewLabels:function(){return Eh(this).labels},getLabelModel:function(){return this.model.getModel("axisLabel")},getTickModel:function(){return this.model.getModel("axisTick")},getBandWidth:function(){var t=this._extent,e=this.scale.getExtent(),i=e[1]-e[0]+(this.onBand?1:0);0===i&&(i=1);var n=Math.abs(t[1]-t[0]);return Math.abs(n)/i},isHorizontal:null,getRotate:null,calculateCategoryInterval:function(){return Yh(this)}};var gb=cb,vb={};f(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend","defaults","clone","merge"],function(t){vb[t]=Ap[t]});var mb={};f(["extendShape","extendPath","makePath","makeImage","mergePath","resizePath","createIcon","setHoverStyle","setLabelStyle","setTextStyle","setText","getFont","updateProps","initProps","getTransform","clipPointsByRect","clipRectByRect","registerShape","getShapeClass","Group","Image","Text","Circle","Sector","Ring","Polygon","Polyline","Rect","Line","BezierCurve","Arc","IncrementalDisplayable","CompoundPath","LinearGradient","RadialGradient","BoundingRect"],function(t){mb[t]=Iy[t]}),R_.extend({type:"series.line",dependencies:["grid","polar"],getInitialData:function(){return Yu(this.getSource(),this)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clip:!0,label:{position:"top"},lineStyle:{width:2,type:"solid"},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}});var yb=Jh.prototype,_b=Jh.getSymbolSize=function(t,e){var i=t.getItemVisual(e,"symbolSize");return i instanceof Array?i.slice():[+i,+i]};yb._createSymbol=function(t,e,i,n,r){this.removeAll();var a=e.getItemVisual(i,"color"),o=Th(t,-1,-1,2,2,a,r);o.attr({z2:100,culling:!0,scale:tc(n)}),o.drift=ec,this._symbolType=t,this.add(o)},yb.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(t)},yb.getSymbolPath=function(){return this.childAt(0)},yb.getScale=function(){return this.childAt(0).scale},yb.highlight=function(){this.childAt(0).trigger("emphasis")},yb.downplay=function(){this.childAt(0).trigger("normal")},yb.setZ=function(t,e){var i=this.childAt(0);i.zlevel=t,i.z=e},yb.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":e.cursor},yb.updateData=function(t,e,i){this.silent=!1;var n=t.getItemVisual(e,"symbol")||"circle",r=t.hostModel,a=_b(t,e),o=n!==this._symbolType;if(o){var s=t.getItemVisual(e,"symbolKeepAspect");this._createSymbol(n,t,e,a,s)}else{var l=this.childAt(0);l.silent=!1,Fa(l,{scale:tc(a)},r,e)}if(this._updateCommon(t,e,a,i),o){var l=this.childAt(0),u=i&&i.fadeIn,h={scale:l.scale.slice()};u&&(h.style={opacity:l.style.opacity}),l.scale=[0,0],u&&(l.style.opacity=0),Ga(l,h,r,e)}this._seriesModel=r};var xb=["itemStyle"],wb=["emphasis","itemStyle"],bb=["label"],Sb=["emphasis","label"];yb._updateCommon=function(t,e,i,n){function r(e){return b?t.getName(e):Qh(t,e)}var a=this.childAt(0),s=t.hostModel,l=t.getItemVisual(e,"color");"image"!==a.type?a.useStyle({strokeNoScale:!0}):a.setStyle({opacity:null,shadowBlur:null,shadowOffsetX:null,shadowOffsetY:null,shadowColor:null});var u=n&&n.itemStyle,h=n&&n.hoverItemStyle,c=n&&n.symbolRotate,d=n&&n.symbolOffset,f=n&&n.labelModel,p=n&&n.hoverLabelModel,g=n&&n.hoverAnimation,v=n&&n.cursorStyle;if(!n||t.hasItemOption){var m=n&&n.itemModel?n.itemModel:t.getItemModel(e);u=m.getModel(xb).getItemStyle(["color"]),h=m.getModel(wb).getItemStyle(),c=m.getShallow("symbolRotate"),d=m.getShallow("symbolOffset"),f=m.getModel(bb),p=m.getModel(Sb),g=m.getShallow("hoverAnimation"),v=m.getShallow("cursor")}else h=o({},h);var y=a.style;a.attr("rotation",(c||0)*Math.PI/180||0),d&&a.attr("position",[oo(d[0],i[0]),oo(d[1],i[1])]),v&&a.attr("cursor",v),a.setColor(l,n&&n.symbolInnerColor),a.setStyle(u);var _=t.getItemVisual(e,"opacity");null!=_&&(y.opacity=_);var x=t.getItemVisual(e,"liftZ"),w=a.__z2Origin;null!=x?null==w&&(a.__z2Origin=a.z2,a.z2+=x):null!=w&&(a.z2=w,a.__z2Origin=null);var b=n&&n.useNameLabel;Ta(y,h,f,p,{labelFetcher:s,labelDataIndex:e,defaultText:r,isRectText:!0,autoColor:l}),a.__symbolOriginalScale=tc(i),a.hoverStyle=h,a.highDownOnUpdate=g&&s.isAnimationEnabled()?ic:null,Sa(a)},yb.fadeOut=function(t,e){var i=this.childAt(0);this.silent=i.silent=!0,!(e&&e.keepLabel)&&(i.style.text=null),Fa(i,{style:{opacity:0},scale:[0,0]},this._seriesModel,this.dataIndex,t)},h(Jh,Dg);var Mb=nc.prototype;Mb.updateData=function(t,e){e=ac(e);var i=this.group,n=t.hostModel,r=this._data,a=this._symbolCtor,o=oc(t);r||i.removeAll(),t.diff(r).add(function(n){var r=t.getItemLayout(n);if(rc(t,r,n,e)){var s=new a(t,n,o);s.attr("position",r),t.setItemGraphicEl(n,s),i.add(s)}}).update(function(s,l){var u=r.getItemGraphicEl(l),h=t.getItemLayout(s);return rc(t,h,s,e)?(u?(u.updateData(t,s,o),Fa(u,{position:h},n)):(u=new a(t,s),u.attr("position",h)),i.add(u),void t.setItemGraphicEl(s,u)):void i.remove(u)}).remove(function(t){var e=r.getItemGraphicEl(t);e&&e.fadeOut(function(){i.remove(e)})}).execute(),this._data=t},Mb.isPersistent=function(){return!0},Mb.updateLayout=function(){var t=this._data;t&&t.eachItemGraphicEl(function(e,i){var n=t.getItemLayout(i);e.attr("position",n)})},Mb.incrementalPrepareUpdate=function(t){this._seriesScope=oc(t),this._data=null,this.group.removeAll()},Mb.incrementalUpdate=function(t,e,i){function n(t){t.isGroup||(t.incremental=t.useHoverLayer=!0)}i=ac(i);for(var r=t.start;r0&&cc(i[r-1]);r--);for(;r>n&&cc(i[n]);n++);}for(;r>n;)n+=dc(t,i,n,r,r,1,a.min,a.max,e.smooth,e.smoothMonotone,e.connectNulls)+1}}),zb=Gr.extend({type:"ec-polygon",shape:{points:[],stackedOnPoints:[],smooth:0,stackedOnSmooth:0,smoothConstraint:!0,smoothMonotone:null,connectNulls:!1},brush:Xm(Gr.prototype.brush),buildPath:function(t,e){var i=e.points,n=e.stackedOnPoints,r=0,a=i.length,o=e.smoothMonotone,s=gc(i,e.smoothConstraint),l=gc(n,e.smoothConstraint);if(e.connectNulls){for(;a>0&&cc(i[a-1]);a--);for(;a>r&&cc(i[r]);r++);}for(;a>r;){var u=dc(t,i,r,a,a,1,s.min,s.max,e.smooth,o,e.connectNulls);dc(t,n,r+u-1,u,a,-1,l.min,l.max,e.stackedOnSmooth,o,e.connectNulls),r+=u+1,t.closePath()}}});Zs.extend({type:"line",init:function(){var t=new Dg,e=new nc;this.group.add(e.group),this._symbolDraw=e,this._lineGroup=t},render:function(t,e,i){var n=t.coordinateSystem,r=this.group,a=t.getData(),o=t.getModel("lineStyle"),l=t.getModel("areaStyle"),u=a.mapArray(a.getItemLayout),h="polar"===n.type,c=this._coordSys,d=this._symbolDraw,f=this._polyline,p=this._polygon,g=this._lineGroup,v=t.get("animation"),m=!l.isEmpty(),y=l.get("origin"),_=sc(n,a,y),x=xc(n,a,_),w=t.get("showSymbol"),b=w&&!h&&Sc(t,a,n),S=this._data;S&&S.eachItemGraphicEl(function(t,e){t.__temp&&(r.remove(t),S.setItemGraphicEl(e,null))}),w||d.remove(),r.add(g);var M,I=!h&&t.get("step");n&&n.getArea&&(M=n.getArea(),null!=M.width?(M.x-=.1,M.y-=.1,M.width+=.2,M.height+=.2):M.r0&&(M.r0-=.5,M.r1+=.5)),f&&c.type===n.type&&I===this._step?(m&&!p?p=this._newPolygon(u,x,n,v):p&&!m&&(g.remove(p),p=this._polygon=null),g.setClipPath(Ic(n,!1,t)),w&&d.updateData(a,{isIgnore:b,clipShape:M}),a.eachItemGraphicEl(function(t){t.stopAnimation(!0)}),yc(this._stackedOnPoints,x)&&yc(this._points,u)||(v?this._updateAnimation(a,x,n,i,I,y):(I&&(u=wc(u,n,I),x=wc(x,n,I)),f.setShape({points:u}),p&&p.setShape({points:u,stackedOnPoints:x})))):(w&&d.updateData(a,{isIgnore:b,clipShape:M}),I&&(u=wc(u,n,I),x=wc(x,n,I)),f=this._newPolyline(u,n,v),m&&(p=this._newPolygon(u,x,n,v)),g.setClipPath(Ic(n,!0,t)));var C=bc(a,n)||a.getVisual("color");f.useStyle(s(o.getLineStyle(),{fill:"none",stroke:C,lineJoin:"bevel"}));var T=t.get("smooth");if(T=_c(t.get("smooth")),f.setShape({smooth:T,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")}),p){var D=a.getCalculationInfo("stackedOnSeries"),A=0;p.useStyle(s(l.getAreaStyle(),{fill:C,opacity:.7,lineJoin:"bevel"})),D&&(A=_c(D.get("smooth"))),p.setShape({smooth:T,stackedOnSmooth:A,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")})}this._data=a,this._coordSys=n,this._stackedOnPoints=x,this._points=u,this._step=I,this._valueOrigin=y},dispose:function(){},highlight:function(t,e,i,n){var r=t.getData(),a=jn(r,n);if(!(a instanceof Array)&&null!=a&&a>=0){var o=r.getItemGraphicEl(a);if(!o){var s=r.getItemLayout(a);if(!s)return;o=new Jh(r,a),o.position=s,o.setZ(t.get("zlevel"),t.get("z")),o.ignore=isNaN(s[0])||isNaN(s[1]),o.__temp=!0,r.setItemGraphicEl(a,o),o.stopSymbolAnimation(!0),this.group.add(o)}o.highlight()}else Zs.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var r=t.getData(),a=jn(r,n);if(null!=a&&a>=0){var o=r.getItemGraphicEl(a);o&&(o.__temp?(r.setItemGraphicEl(a,null),this.group.remove(o)):o.downplay())}else Zs.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new Ob({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new zb({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_updateAnimation:function(t,e,i,n,r,a){var o=this._polyline,s=this._polygon,l=t.hostModel,u=Ib(this._data,t,this._stackedOnPoints,e,this._coordSys,i,this._valueOrigin,a),h=u.current,c=u.stackedOnCurrent,d=u.next,f=u.stackedOnNext;r&&(h=wc(u.current,i,r),c=wc(u.stackedOnCurrent,i,r),d=wc(u.next,i,r),f=wc(u.stackedOnNext,i,r)),o.shape.__points=u.current,o.shape.points=h,Fa(o,{shape:{points:d}},l),s&&(s.setShape({points:h,stackedOnPoints:c}),Fa(s,{shape:{points:d,stackedOnPoints:f}},l));for(var p=[],g=u.status,v=0;ve&&(e=t[i]);return isFinite(e)?e:0/0},min:function(t){for(var e=1/0,i=0;i1){var u;"string"==typeof i?u=Rb[i]:"function"==typeof i&&(u=i),u&&t.setData(e.downSample(e.mapDimension(a.dim),1/l,u,Nb))}}}}},Gb=function(t){this._axes={},this._dimList=[],this.name=t||""};Gb.prototype={constructor:Gb,type:"cartesian",getAxis:function(t){return this._axes[t]},getAxes:function(){return p(this._dimList,Cc,this)},getAxesByScale:function(t){return t=t.toLowerCase(),v(this.getAxes(),function(e){return e.scale.type===t})},addAxis:function(t){var e=t.dim;this._axes[e]=t,this._dimList.push(e)},dataToCoord:function(t){return this._dataCoordConvert(t,"dataToCoord")},coordToData:function(t){return this._dataCoordConvert(t,"coordToData")},_dataCoordConvert:function(t,e){for(var i=this._dimList,n=t instanceof Array?[]:{},r=0;re[1]&&e.reverse(),e},getOtherAxis:function(){this.grid.getOtherAxis()},pointToData:function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},toLocalCoord:null,toGlobalCoord:null},h(Vb,pb);var Hb={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#333",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},Wb={};Wb.categoryAxis=r({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},Hb),Wb.valueAxis=r({boundaryGap:[0,0],splitNumber:5},Hb),Wb.timeAxis=s({scale:!0,min:"dataMin",max:"dataMax"},Wb.valueAxis),Wb.logAxis=s({scale:!0,logBase:10},Wb.valueAxis);var Ub=["value","category","time","log"],Xb=function(t,e,i,n){f(Ub,function(o){e.extend({type:t+"Axis."+o,mergeDefaultAndTheme:function(e,n){var a=this.layoutMode,s=a?Ro(e):{},l=n.getTheme();r(e,l.get(o+"Axis")),r(e,this.getDefaultOption()),e.type=i(t,e),a&&Eo(e,s,a)},optionUpdated:function(){var t=this.option;"category"===t.type&&(this.__ordinalMeta=Ku.createByAxisModel(this))},getCategories:function(t){var e=this.option;return"category"===e.type?t?e.data:this.__ordinalMeta.categories:void 0},getOrdinalMeta:function(){return this.__ordinalMeta},defaultOption:a([{},Wb[o+"Axis"],n],!0)})}),Ky.registerSubTypeDefaulter(t+"Axis",_(i,t))},Yb=Ky.extend({type:"cartesian2dAxis",axis:null,init:function(){Yb.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){Yb.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){Yb.superApply(this,"restoreData",arguments),this.resetRange()},getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"grid",index:this.option.gridIndex,id:this.option.gridId})[0]}});r(Yb.prototype,Jw);var jb={offset:0};Xb("x",Yb,Dc,jb),Xb("y",Yb,Dc,jb),Ky.extend({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}});var qb=kc.prototype;qb.type="grid",qb.axisPointerEnabled=!0,qb.getRect=function(){return this._rect},qb.update=function(t,e){var i=this._axesMap;this._updateScale(t,this.model),f(i.x,function(t){mh(t.scale,t.model)}),f(i.y,function(t){mh(t.scale,t.model)});var n={};f(i.x,function(t){Pc(i,"y",t,n)}),f(i.y,function(t){Pc(i,"x",t,n)}),this.resize(this.model,e)},qb.resize=function(t,e,i){function n(){f(a,function(t){var e=t.isHorizontal(),i=e?[0,r.width]:[0,r.height],n=t.inverse?1:0;t.setExtent(i[n],i[1-n]),Oc(t,e?r.x:r.y)})}var r=Bo(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()});this._rect=r;var a=this._axesList;n(),!i&&t.get("containLabel")&&(f(a,function(t){if(!t.model.get("axisLabel.inside")){var e=bh(t);if(e){var i=t.isHorizontal()?"height":"width",n=t.model.get("axisLabel.margin");r[i]-=e[i]+n,"top"===t.position?r.y+=e.height+n:"left"===t.position&&(r.x+=e.width+n)}}}),n())},qb.getAxis=function(t,e){var i=this._axesMap[t];if(null!=i){if(null==e)for(var n in i)if(i.hasOwnProperty(n))return i[n];return i[e]}},qb.getAxes=function(){return this._axesList.slice()},qb.getCartesian=function(t,e){if(null!=t&&null!=e){var i="x"+t+"y"+e;return this._coordsMap[i]}S(t)&&(e=t.yAxisIndex,t=t.xAxisIndex);for(var n=0,r=this._coordsList;nu[1]?-1:1,c=["start"===r?u[0]-h*l:"end"===r?u[1]+h*l:(u[0]+u[1])/2,Gc(r)?t.labelOffset+a*l:0],d=e.get("nameRotate");null!=d&&(d=d*Kb/180);var f;Gc(r)?n=tS(t.rotation,null!=d?d:t.rotation,a):(n=Ec(t,r,d||0,u),f=t.axisNameAvailableWidth,null!=f&&(f=Math.abs(f/Math.sin(n.rotation)),!isFinite(f)&&(f=null)));var p=s.getFont(),g=e.get("nameTruncate",!0)||{},v=g.ellipsis,m=D(t.nameTruncateMaxWidth,g.maxWidth,f),y=null!=v&&null!=m?Hy(i,m,p,v,{minChar:2,placeholder:g.placeholder}):i,_=e.get("tooltip",!0),x=e.mainType,w={componentType:x,name:i,$vars:["name"]};w[x+"Index"]=e.componentIndex;var b=new Hm({anid:"name",__fullText:i,__truncatedText:y,position:c,rotation:n.rotation,silent:eS(e),z2:1,tooltip:_&&_.show?o({content:i,formatter:function(){return i},formatterParams:w},_):null});Aa(b.style,s,{text:y,textFont:p,textFill:s.getTextColor()||e.get("axisLine.lineStyle.color"),textAlign:s.get("align")||n.textAlign,textVerticalAlign:s.get("verticalAlign")||n.textVerticalAlign}),e.get("triggerEvent")&&(b.eventData=Jb(e),b.eventData.targetType="axisName",b.eventData.name=i),this._dumbGroup.add(b),b.updateTransform(),this.group.add(b),b.decomposeTransform()}}},Jb=$b.makeAxisEventDataBase=function(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e},tS=$b.innerTextLayout=function(t,e,i){var n,r,a=po(e-t);return go(a)?(r=i>0?"top":"bottom",n="center"):go(a-Kb)?(r=i>0?"bottom":"top",n="center"):(r="middle",n=a>0&&Kb>a?i>0?"right":"left":i>0?"left":"right"),{rotation:a,textAlign:n,textVerticalAlign:r}},eS=$b.isLabelSilent=function(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)},iS=f,nS=_,rS=pu({type:"axis",_axisPointer:null,axisPointerClass:null,render:function(t,e,i,n){this.axisPointerClass&&Zc(t),rS.superApply(this,"render",arguments),td(this,t,e,i,n,!0)},updateAxisPointer:function(t,e,i,n){td(this,t,e,i,n,!1)},remove:function(t,e){var i=this._axisPointer;i&&i.remove(e),rS.superApply(this,"remove",arguments)},dispose:function(t,e){ed(this,e),rS.superApply(this,"dispose",arguments)}}),aS=[];rS.registerAxisPointerClass=function(t,e){aS[t]=e},rS.getAxisPointerClass=function(t){return t&&aS[t]};var oS=["axisLine","axisTickLabel","axisName"],sS=["splitArea","splitLine"],lS=rS.extend({type:"cartesianAxis",axisPointerClass:"CartesianAxisPointer",render:function(t,e,i,n){this.group.removeAll();var r=this._axisGroup;if(this._axisGroup=new Dg,this.group.add(this._axisGroup),t.get("show")){var a=t.getCoordSysModel(),o=id(a,t),s=new $b(t,o);f(oS,s.add,s),this._axisGroup.add(s.getGroup()),f(sS,function(e){t.get(e+".show")&&this["_"+e](t,a)},this),Ua(r,this._axisGroup,t),lS.superCall(this,"render",t,e,i,n)}},remove:function(){this._splitAreaColors=null},_splitLine:function(t,e){var i=t.axis;if(!i.scale.isBlank()){var n=t.getModel("splitLine"),r=n.getModel("lineStyle"),a=r.get("color");a=x(a)?a:[a];for(var o=e.coordinateSystem.getRect(),l=i.isHorizontal(),u=0,h=i.getTicksCoords({tickModel:n}),c=[],d=[],f=r.getLineStyle(),p=0;p=0},getOrient:function(){return"vertical"===this.get("orient")?{index:1,name:"vertical"}:{index:0,name:"horizontal"}},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",inactiveBorderColor:"#ccc",itemStyle:{borderWidth:0},textStyle:{color:"#333"},selectedMode:!0,selector:!1,selectorLabel:{show:!0,borderRadius:10,padding:[3,5,3,5],fontSize:12,fontFamily:" sans-serif",color:"#666",borderWidth:1,borderColor:"#666"},emphasis:{selectorLabel:{show:!0,color:"#eee",backgroundColor:"#666"}},selectorPosition:"auto",selectorItemGap:7,selectorButtonGap:10,tooltip:{show:!1}}});ou("legendToggleSelect","legendselectchanged",_(nd,"toggleSelected")),ou("legendAllSelect","legendselectall",_(nd,"allSelect")),ou("legendInverseSelect","legendinverseselect",_(nd,"inverseSelect")),ou("legendSelect","legendselected",_(nd,"select")),ou("legendUnSelect","legendunselected",_(nd,"unSelect"));var dS=_,fS=f,pS=Dg,gS=pu({type:"legend.plain",newlineDisabled:!1,init:function(){this.group.add(this._contentGroup=new pS),this._backgroundEl,this.group.add(this._selectorGroup=new pS),this._isFirstRender=!0},getContentGroup:function(){return this._contentGroup},getSelectorGroup:function(){return this._selectorGroup},render:function(t,e,i){var n=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var r=t.get("align"),a=t.get("orient");r&&"auto"!==r||(r="right"===t.get("left")&&"vertical"===a?"right":"left");var o=t.get("selector",!0),l=t.get("selectorPosition",!0);!o||l&&"auto"!==l||(l="horizontal"===a?"end":"start"),this.renderInner(r,t,e,i,o,a,l);var u=t.getBoxLayoutParams(),h={width:i.getWidth(),height:i.getHeight()},c=t.get("padding"),d=Bo(u,h,c),f=this.layoutInner(t,r,d,n,o,l),p=Bo(s({width:f.width,height:f.height},u),h,c);this.group.attr("position",[p.x-f.x,p.y-f.y]),this.group.add(this._backgroundEl=rd(f,t))}},resetInner:function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl),this.getSelectorGroup().removeAll()},renderInner:function(t,e,i,n,r,a,o){var s=this.getContentGroup(),l=N(),u=e.get("selectedMode"),h=[];i.eachRawSeries(function(t){!t.get("legendHoverLink")&&h.push(t.id)}),fS(e.getData(),function(r,a){var o=r.get("name");if(!this.newlineDisabled&&(""===o||"\n"===o))return void s.add(new pS({newline:!0}));var c=i.getSeriesByName(o)[0];if(!l.get(o))if(c){var d=c.getData(),f=d.getVisual("color"),p=d.getVisual("borderColor");"function"==typeof f&&(f=f(c.getDataParams(0))),"function"==typeof p&&(p=p(c.getDataParams(0)));var g=d.getVisual("legendSymbol")||"roundRect",v=d.getVisual("symbol"),m=this._createItem(o,a,r,e,g,v,t,f,p,u);m.on("click",dS(od,o,n)).on("mouseover",dS(sd,c.name,null,n,h)).on("mouseout",dS(ld,c.name,null,n,h)),l.set(o,!0)}else i.eachRawSeries(function(i){if(!l.get(o)&&i.legendDataProvider){var s=i.legendDataProvider(),c=s.indexOfName(o);if(0>c)return;var d=s.getItemVisual(c,"color"),f=s.getItemVisual(c,"borderColor"),p="roundRect",g=this._createItem(o,a,r,e,p,null,t,d,f,u);g.on("click",dS(od,o,n)).on("mouseover",dS(sd,null,o,n,h)).on("mouseout",dS(ld,null,o,n,h)),l.set(o,!0)}},this)},this),r&&this._createSelector(r,e,n,a,o)},_createSelector:function(t,e,i){function n(t){var n=t.type,a=new Hm({style:{x:0,y:0,align:"center",verticalAlign:"middle"},onclick:function(){i.dispatchAction({type:"all"===n?"legendAllSelect":"legendInverseSelect"})}});r.add(a);var o=e.getModel("selectorLabel"),s=e.getModel("emphasis.selectorLabel");Ta(a.style,a.hoverStyle={},o,s,{defaultText:t.title,isRectText:!1}),Sa(a)}var r=this.getSelectorGroup();fS(t,function(t){n(t)})},_createItem:function(t,e,i,n,r,a,s,l,u,h){var c=n.get("itemWidth"),d=n.get("itemHeight"),f=n.get("inactiveColor"),p=n.get("inactiveBorderColor"),g=n.get("symbolKeepAspect"),v=n.getModel("itemStyle"),m=n.isSelected(t),y=new pS,_=i.getModel("textStyle"),x=i.get("icon"),w=i.getModel("tooltip"),b=w.parentModel;r=x||r;var S=Th(r,0,0,c,d,m?l:f,null==g?!0:g);if(y.add(ad(S,r,v,u,p,m)),!x&&a&&(a!==r||"none"===a)){var M=.8*d;"none"===a&&(a="circle");var I=Th(a,(c-M)/2,(d-M)/2,M,M,m?l:f,null==g?!0:g);y.add(ad(I,a,v,u,p,m))}var C="left"===s?c+5:-5,T=s,D=n.get("formatter"),A=t;"string"==typeof D&&D?A=D.replace("{name}",null!=t?t:""):"function"==typeof D&&(A=D(t)),y.add(new Hm({style:Aa({},_,{text:A,x:C,y:d/2,textFill:m?_.getTextColor():f,textAlign:T,textVerticalAlign:"middle"})}));var k=new ty({shape:y.getBoundingRect(),invisible:!0,tooltip:w.get("show")?o({content:t,formatter:b.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:n.componentIndex,name:t,$vars:["name"]}},w.option):null});return y.add(k),y.eachChild(function(t){t.silent=!0}),k.silent=!h,this.getContentGroup().add(y),Sa(y),y.__legendDataIndex=e,y},layoutInner:function(t,e,i,n,r,a){var o=this.getContentGroup(),s=this.getSelectorGroup();jy(t.get("orient"),o,t.get("itemGap"),i.width,i.height);var l=o.getBoundingRect(),u=[-l.x,-l.y];if(r){jy("horizontal",s,t.get("selectorItemGap",!0));var h=s.getBoundingRect(),c=[-h.x,-h.y],d=t.get("selectorButtonGap",!0),f=t.getOrient().index,p=0===f?"width":"height",g=0===f?"height":"width",v=0===f?"y":"x";"end"===a?c[f]+=l[p]+d:u[f]+=h[p]+d,c[1-f]+=l[g]/2-h[g]/2,s.attr("position",c),o.attr("position",u);var m={x:0,y:0};return m[p]=l[p]+d+h[p],m[g]=Math.max(l[g],h[g]),m[v]=Math.min(0,h[v]+c[1-f]),m}return o.attr("position",u),this.group.getBoundingRect()},remove:function(){this.getContentGroup().removeAll(),this._isFirstRender=!0}}),vS=function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var i=0;ii[r],f=[-h.x,-h.y];e||(f[n]=s.position[n]);var p=[0,0],g=[-c.x,-c.y],v=A(t.get("pageButtonGap",!0),t.get("itemGap",!0));if(d){var m=t.get("pageButtonPosition",!0);"end"===m?g[n]+=i[r]-c[r]:p[n]+=c[r]+v}g[1-n]+=h[a]/2-c[a]/2,s.attr("position",f),l.attr("position",p),u.attr("position",g);var y={x:0,y:0};if(y[r]=d?i[r]:h[r],y[a]=Math.max(h[a],c[a]),y[o]=Math.min(0,c[o]+g[1-n]),l.__rectSize=i[r],d){var _={x:0,y:0};_[r]=Math.max(i[r]-c[r]-v,0),_[a]=y[a],l.setClipPath(new ty({shape:_})),l.__rectSize=_[r]}else u.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var x=this._getPageInfo(t);return null!=x.pageIndex&&Fa(s,{position:x.contentPosition},d?t:!1),this._updatePageInfoView(t,x),y},_pageGo:function(t,e,i){var n=this._getPageInfo(e)[t];null!=n&&i.dispatchAction({type:"legendScroll",scrollDataIndex:n,legendId:e.id})},_updatePageInfoView:function(t,e){var i=this._controllerGroup;f(["pagePrev","pageNext"],function(n){var r=null!=e[n+"DataIndex"],a=i.childOfName(n);a&&(a.setStyle("fill",r?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),a.cursor=r?"pointer":"default")});var n=i.childOfName("pageText"),r=t.get("pageFormatter"),a=e.pageIndex,o=null!=a?a+1:0,s=e.pageCount;n&&r&&n.setStyle("text",b(r)?r.replace("{current}",o).replace("{total}",s):r({current:o,total:s}))},_getPageInfo:function(t){function e(t){if(t){var e=t.getBoundingRect(),i=e[l]+t.position[o];return{s:i,e:i+e[s],i:t.__legendDataIndex}}}function i(t,e){return t.e>=e&&t.s<=e+a}var n=t.get("scrollDataIndex",!0),r=this.getContentGroup(),a=this._containerGroup.__rectSize,o=t.getOrient().index,s=_S[o],l=xS[o],u=this._findTargetItemIndex(n),h=r.children(),c=h[u],d=h.length,f=d?1:0,p={contentPosition:r.position.slice(),pageCount:f,pageIndex:f-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!c)return p;var g=e(c);p.contentPosition[o]=-g.s;for(var v=u+1,m=g,y=g,_=null;d>=v;++v)_=e(h[v]),(!_&&y.e>m.s+a||_&&!i(_,m.s))&&(m=y.i>m.i?y:_,m&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=m.i),++p.pageCount)),y=_;for(var v=u-1,m=g,y=g,_=null;v>=-1;--v)_=e(h[v]),_&&i(y,_.s)||!(m.io||x(o))return{point:[]};var s=a.getItemGraphicEl(o),l=i.coordinateSystem;if(i.getTooltipPosition)n=i.getTooltipPosition(o)||[];else if(l&&l.dataToPoint)n=l.dataToPoint(a.getValues(p(l.dimensions,function(t){return a.mapDimension(t)}),o,!0))||[];else if(s){var u=s.getBoundingRect().clone();u.applyTransform(s.transform),n=[u.x+u.width/2,u.y+u.height/2]}return{point:n,el:s}},SS=f,MS=_,IS=qn(),CS=function(t,e,i){var n=t.currTrigger,r=[t.x,t.y],a=t,o=t.dispatchAction||y(i.dispatchAction,i),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){_d(r)&&(r=bS({seriesIndex:a.seriesIndex,dataIndex:a.dataIndex},e).point);var l=_d(r),u=a.axesInfo,h=s.axesInfo,c="leave"===n||_d(r),d={},f={},p={list:[],map:{}},g={showPointer:MS(dd,f),showTooltip:MS(fd,p)};SS(s.coordSysMap,function(t,e){var i=l||t.containPoint(r);SS(s.coordSysAxesInfo[e],function(t){var e=t.axis,n=md(u,t);if(!c&&i&&(!u||n)){var a=n&&n.value;null!=a||l||(a=e.pointToData(r)),null!=a&&hd(t,a,g,!1,d)}})});var v={};return SS(h,function(t,e){var i=t.linkGroup;i&&!f[e]&&SS(i.axesInfo,function(e,n){var r=f[n];if(e!==t&&r){var a=r.value;i.mapper&&(a=t.axis.scale.parse(i.mapper(a,yd(e),yd(t)))),v[t.key]=a}})}),SS(v,function(t,e){hd(h[e],t,g,!0,d)}),pd(f,h,d),gd(p,r,t,o),vd(h,o,i),d}},TS=(fu({type:"axisPointer",coordSysAxesInfo:null,defaultOption:{show:"auto",triggerOn:null,zlevel:0,z:50,type:"line",snap:!1,triggerTooltip:!0,value:null,status:null,link:[],animation:null,animationDurationUpdate:200,lineStyle:{color:"#aaa",width:1,type:"solid"},shadowStyle:{color:"rgba(150,150,150,0.3)"},label:{show:!0,formatter:null,precision:"auto",margin:3,color:"#fff",padding:[5,7,5,7],backgroundColor:"auto",borderColor:null,borderWidth:0,shadowBlur:3,shadowColor:"#aaa"},handle:{show:!1,icon:"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z",size:45,margin:50,color:"#333",shadowBlur:3,shadowColor:"#aaa",shadowOffsetX:0,shadowOffsetY:2,throttle:40}}}),qn()),DS=f,AS=pu({type:"axisPointer",render:function(t,e,i){var n=e.getComponent("tooltip"),r=t.get("triggerOn")||n&&n.get("triggerOn")||"mousemove|click";xd("axisPointer",i,function(t,e,i){"none"!==r&&("leave"===t||r.indexOf(t)>=0)&&i({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})})},remove:function(t,e){Cd(e.getZr(),"axisPointer"),AS.superApply(this._model,"remove",arguments)},dispose:function(t,e){Cd("axisPointer",e),AS.superApply(this._model,"dispose",arguments)}}),kS=qn(),PS=n,LS=y;Td.prototype={_group:null,_lastGraphicKey:null,_handle:null,_dragging:!1,_lastValue:null,_lastStatus:null,_payloadInfo:null,animationThreshold:15,render:function(t,e,i,n){var r=e.get("value"),a=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=i,n||this._lastValue!==r||this._lastStatus!==a){this._lastValue=r,this._lastStatus=a;var o=this._group,s=this._handle;if(!a||"hide"===a)return o&&o.hide(),void(s&&s.hide());o&&o.show(),s&&s.show();var l={};this.makeElOption(l,r,t,e,i);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(i),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(o){var c=_(Dd,e,h);this.updatePointerEl(o,l,c,e),this.updateLabelEl(o,l,c,e)}else o=this._group=new Dg,this.createPointerEl(o,l,t,e),this.createLabelEl(o,l,t,e),i.getZr().add(o);Ld(o,e,!0),this._renderHandle(r)}},remove:function(t){this.clear(t)},dispose:function(t){this.clear(t)},determineAnimation:function(t,e){var i=e.get("animation"),n=t.axis,r="category"===n.type,a=e.get("snap");if(!a&&!r)return!1;if("auto"===i||null==i){var o=this.animationThreshold;if(r&&n.getBandWidth()>o)return!0;if(a){var s=Kc(t).seriesDataCount,l=n.getExtent();return Math.abs(l[0]-l[1])/s>o}return!1}return i===!0},makeElOption:function(){},createPointerEl:function(t,e){var i=e.pointer;if(i){var n=kS(t).pointerEl=new Iy[i.type](PS(e.pointer));t.add(n)}},createLabelEl:function(t,e,i,n){if(e.label){var r=kS(t).labelEl=new ty(PS(e.label));t.add(r),kd(r,n)}},updatePointerEl:function(t,e,i){var n=kS(t).pointerEl;n&&e.pointer&&(n.setStyle(e.pointer.style),i(n,{shape:e.pointer.shape}))},updateLabelEl:function(t,e,i,n){var r=kS(t).labelEl;r&&(r.setStyle(e.label.style),i(r,{shape:e.label.shape,position:e.label.position}),kd(r,n))},_renderHandle:function(t){if(!this._dragging&&this.updateHandleTransform){var e=this._axisPointerModel,i=this._api.getZr(),n=this._handle,r=e.getModel("handle"),a=e.get("status");if(!r.get("show")||!a||"hide"===a)return n&&i.remove(n),void(this._handle=null);var o;this._handle||(o=!0,n=this._handle=ja(r.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){Wp(t.event)},onmousedown:LS(this._onHandleDragMove,this,0,0),drift:LS(this._onHandleDragMove,this),ondragend:LS(this._onHandleDragEnd,this)}),i.add(n)),Ld(n,e,!1);var s=["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"];n.setStyle(r.getItemStyle(null,s));var l=r.get("size");x(l)||(l=[l,l]),n.attr("scale",[l[0]/2,l[1]/2]),el(this,"_doDispatchAxisPointer",r.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,o)}},_moveHandleToValue:function(t,e){Dd(this._axisPointerModel,!e&&this._moveAnimation,this._handle,Pd(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},_onHandleDragMove:function(t,e){var i=this._handle;if(i){this._dragging=!0;var n=this.updateHandleTransform(Pd(i),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=n,i.stopAnimation(),i.attr(Pd(n)),kS(i).lastProp=null,this._doDispatchAxisPointer()}},_doDispatchAxisPointer:function(){var t=this._handle;if(t){var e=this._payloadInfo,i=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:e.cursorPoint[0],y:e.cursorPoint[1],tooltipOption:e.tooltipOption,axesInfo:[{axisDim:i.axis.dim,axisIndex:i.componentIndex}]})}},_onHandleDragEnd:function(){this._dragging=!1;var t=this._handle;if(t){var e=this._axisPointerModel.get("value");this._moveHandleToValue(e),this._api.dispatchAction({type:"hideTip"})}},getHandleTransform:null,updateHandleTransform:null,clear:function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),i=this._group,n=this._handle;e&&i&&(this._lastGraphicKey=null,i&&e.remove(i),n&&e.remove(n),this._group=null,this._handle=null,this._payloadInfo=null)},doClear:function(){},buildLabel:function(t,e,i){return i=i||0,{x:t[i],y:t[1-i],width:e[i],height:e[1-i]}}},Td.prototype.constructor=Td,ir(Td);var OS=Td.extend({makeElOption:function(t,e,i,n,r){var a=i.axis,o=a.grid,s=n.get("type"),l=Vd(o,a).getOtherAxis(a).getGlobalExtent(),u=a.toGlobalCoord(a.dataToCoord(e,!0));if(s&&"none"!==s){var h=Od(n),c=zS[s](a,u,l);c.style=h,t.graphicKey=c.type,t.pointer=c}var d=id(o.model,i);Nd(e,t,d,i,n,r)},getHandleTransform:function(t,e,i){var n=id(e.axis.grid.model,e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:Rd(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i){var n=i.axis,r=n.grid,a=n.getGlobalExtent(!0),o=Vd(r,n).getOtherAxis(n).getGlobalExtent(),s="x"===n.dim?0:1,l=t.position;l[s]+=e[s],l[s]=Math.min(a[1],l[s]),l[s]=Math.max(a[0],l[s]);var u=(o[1]+o[0])/2,h=[u,u];h[s]=l[s];var c=[{verticalAlign:"middle"},{align:"center"}];return{position:l,rotation:t.rotation,cursorPoint:h,tooltipOption:c[s]}}}),zS={line:function(t,e,i){var n=Fd([e,i[0]],[e,i[1]],Hd(t));return{type:"Line",subPixelOptimize:!0,shape:n}},shadow:function(t,e,i){var n=Math.max(1,t.getBandWidth()),r=i[1]-i[0];return{type:"Rect",shape:Gd([e-n/2,i[0]],[n,r],Hd(t))}}};rS.registerAxisPointerClass("CartesianAxisPointer",OS),nu(function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!x(e)&&(t.axisPointer.link=[e])}}),ru(Hx.PROCESSOR.STATISTIC,function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=Wc(t,e)}),ou({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},CS),fu({type:"tooltip",dependencies:["axisPointer"],defaultOption:{zlevel:0,z:60,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove|click",alwaysShowContent:!1,displayMode:"single",renderMode:"auto",confine:!1,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"rgba(50,50,50,0.7)",borderColor:"#333",borderRadius:4,borderWidth:0,padding:5,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:"#999",width:1,type:"dashed",textStyle:{}}},textStyle:{color:"#fff",fontSize:14}}});var BS=f,ES=Mo,RS=["","-webkit-","-moz-","-o-"],NS="position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;";Yd.prototype={constructor:Yd,_enterable:!0,update:function(){var t=this._container,e=t.currentStyle||document.defaultView.getComputedStyle(t),i=t.style;"absolute"!==i.position&&"absolute"!==e.position&&(i.position="relative")},show:function(t){clearTimeout(this._hideTimeout);var e=this.el;e.style.cssText=NS+Xd(t)+";left:"+this._x+"px;top:"+this._y+"px;"+(t.get("extraCssText")||""),e.style.display=e.innerHTML?"block":"none",e.style.pointerEvents=this._enterable?"auto":"none",this._show=!0},setContent:function(t){this.el.innerHTML=null==t?"":t},setEnterable:function(t){this._enterable=t},getSize:function(){var t=this.el;return[t.clientWidth,t.clientHeight]},moveTo:function(t,e){var i,n=this._zr; -n&&n.painter&&(i=n.painter.getViewportRootOffset())&&(t+=i.offsetLeft,e+=i.offsetTop);var r=this.el.style;r.left=t+"px",r.top=e+"px",this._x=t,this._y=e},hide:function(){this.el.style.display="none",this._show=!1},hideLater:function(t){!this._show||this._inContent&&this._enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(y(this.hide,this),t)):this.hide())},isShow:function(){return this._show},getOuterSize:function(){var t=this.el.clientWidth,e=this.el.clientHeight;if(document.defaultView&&document.defaultView.getComputedStyle){var i=document.defaultView.getComputedStyle(this.el);i&&(t+=parseInt(i.borderLeftWidth,10)+parseInt(i.borderRightWidth,10),e+=parseInt(i.borderTopWidth,10)+parseInt(i.borderBottomWidth,10))}return{width:t,height:e}}},jd.prototype={constructor:jd,_enterable:!0,update:function(){},show:function(){this._hideTimeout&&clearTimeout(this._hideTimeout),this.el.attr("show",!0),this._show=!0},setContent:function(t,e,i){this.el&&this._zr.remove(this.el);for(var n={},r=t,a="{marker",o="|}",s=r.indexOf(a);s>=0;){var l=r.indexOf(o),u=r.substr(s+a.length,l-s-a.length);n["marker"+u]=u.indexOf("sub")>-1?{textWidth:4,textHeight:4,textBorderRadius:2,textBackgroundColor:e[u],textOffset:[3,0]}:{textWidth:10,textHeight:10,textBorderRadius:5,textBackgroundColor:e[u]},r=r.substr(l+1),s=r.indexOf("{marker")}this.el=new Hm({style:{rich:n,text:t,textLineHeight:20,textBackgroundColor:i.get("backgroundColor"),textBorderRadius:i.get("borderRadius"),textFill:i.get("textStyle.color"),textPadding:i.get("padding")},z:i.get("z")}),this._zr.add(this.el);var h=this;this.el.on("mouseover",function(){h._enterable&&(clearTimeout(h._hideTimeout),h._show=!0),h._inContent=!0}),this.el.on("mouseout",function(){h._enterable&&h._show&&h.hideLater(h._hideDelay),h._inContent=!1})},setEnterable:function(t){this._enterable=t},getSize:function(){var t=this.el.getBoundingRect();return[t.width,t.height]},moveTo:function(t,e){this.el&&this.el.attr("position",[t,e])},hide:function(){this.el&&this.el.hide(),this._show=!1},hideLater:function(t){!this._show||this._inContent&&this._enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(y(this.hide,this),t)):this.hide())},isShow:function(){return this._show},getOuterSize:function(){var t=this.getSize();return{width:t[0],height:t[1]}}};var FS=y,GS=f,VS=oo,HS=new ty({shape:{x:-1,y:-1,width:2,height:2}});pu({type:"tooltip",init:function(t,e){if(!gp.node){var i=t.getComponent("tooltip"),n=i.get("renderMode");this._renderMode=Jn(n);var r;"html"===this._renderMode?(r=new Yd(e.getDom(),e),this._newLine="
"):(r=new jd(e),this._newLine="\n"),this._tooltipContent=r}},render:function(t,e,i){if(!gp.node){this.group.removeAll(),this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastDataByCoordSys=null,this._alwaysShowContent=t.get("alwaysShowContent");var n=this._tooltipContent;n.update(),n.setEnterable(t.get("enterable")),this._initGlobalListener(),this._keepShow()}},_initGlobalListener:function(){var t=this._tooltipModel,e=t.get("triggerOn");xd("itemTooltip",this._api,FS(function(t,i,n){"none"!==e&&(e.indexOf(t)>=0?this._tryShow(i,n):"leave"===t&&this._hide(n))},this))},_keepShow:function(){var t=this._tooltipModel,e=this._ecModel,i=this._api;if(null!=this._lastX&&null!=this._lastY&&"none"!==t.get("triggerOn")){var n=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){!i.isDisposed()&&n.manuallyShowTip(t,e,i,{x:n._lastX,y:n._lastY})})}},manuallyShowTip:function(t,e,i,n){if(n.from!==this.uid&&!gp.node){var r=Zd(n,i);this._ticket="";var a=n.dataByCoordSys;if(n.tooltip&&null!=n.x&&null!=n.y){var o=HS;o.position=[n.x,n.y],o.update(),o.tooltip=n.tooltip,this._tryShow({offsetX:n.x,offsetY:n.y,target:o},r)}else if(a)this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,event:{},dataByCoordSys:n.dataByCoordSys,tooltipOption:n.tooltipOption},r);else if(null!=n.seriesIndex){if(this._manuallyAxisShowTip(t,e,i,n))return;var s=bS(n,e),l=s.point[0],u=s.point[1];null!=l&&null!=u&&this._tryShow({offsetX:l,offsetY:u,position:n.position,target:s.el,event:{}},r)}else null!=n.x&&null!=n.y&&(i.dispatchAction({type:"updateAxisPointer",x:n.x,y:n.y}),this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,target:i.getZr().findHover(n.x,n.y).target,event:{}},r))}},manuallyHideTip:function(t,e,i,n){var r=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&r.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=null,n.from!==this.uid&&this._hide(Zd(n,i))},_manuallyAxisShowTip:function(t,e,i,n){var r=n.seriesIndex,a=n.dataIndex,o=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=r&&null!=a&&null!=o){var s=e.getSeriesByIndex(r);if(s){var l=s.getData(),t=qd([l.getItemModel(a),s,(s.coordinateSystem||{}).model,t]);if("axis"===t.get("trigger"))return i.dispatchAction({type:"updateAxisPointer",seriesIndex:r,dataIndex:a,position:n.position}),!0}}},_tryShow:function(t,e){var i=t.target,n=this._tooltipModel;if(n){this._lastX=t.offsetX,this._lastY=t.offsetY;var r=t.dataByCoordSys;r&&r.length?this._showAxisTooltip(r,t):i&&null!=i.dataIndex?(this._lastDataByCoordSys=null,this._showSeriesItemTooltip(t,i,e)):i&&i.tooltip?(this._lastDataByCoordSys=null,this._showComponentItemTooltip(t,i,e)):(this._lastDataByCoordSys=null,this._hide(e))}},_showOrMove:function(t,e){var i=t.get("showDelay");e=y(e,this),clearTimeout(this._showTimout),i>0?this._showTimout=setTimeout(e,i):e()},_showAxisTooltip:function(t,e){var i=this._ecModel,n=this._tooltipModel,a=[e.offsetX,e.offsetY],o=[],s=[],l=qd([e.tooltipOption,n]),u=this._renderMode,h=this._newLine,c={};GS(t,function(t){GS(t.dataByAxis,function(t){var e=i.getComponent(t.axisDim+"Axis",t.axisIndex),n=t.value,a=[];if(e&&null!=n){var l=Ed(n,e.axis,i,t.seriesDataIndices,t.valueLabelOpt);f(t.seriesDataIndices,function(o){var h=i.getSeriesByIndex(o.seriesIndex),d=o.dataIndexInside,f=h&&h.getDataParams(d);if(f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=wh(e.axis,n),f.axisValueLabel=l,f){s.push(f);var p,g=h.formatTooltip(d,!0,null,u);if(S(g)){p=g.html;var v=g.markers;r(c,v)}else p=g;a.push(p)}});var d=l;o.push("html"!==u?a.join(h):(d?Io(d)+h:"")+a.join(h))}})},this),o.reverse(),o=o.join(this._newLine+this._newLine);var d=e.position;this._showOrMove(l,function(){this._updateContentNotChangedOnAxis(t)?this._updatePosition(l,d,a[0],a[1],this._tooltipContent,s):this._showTooltipContent(l,o,s,Math.random(),a[0],a[1],d,void 0,c)})},_showSeriesItemTooltip:function(t,e,i){var n=this._ecModel,r=e.seriesIndex,a=n.getSeriesByIndex(r),o=e.dataModel||a,s=e.dataIndex,l=e.dataType,u=o.getData(),h=qd([u.getItemModel(s),o,a&&(a.coordinateSystem||{}).model,this._tooltipModel]),c=h.get("trigger");if(null==c||"item"===c){var d,f,p=o.getDataParams(s,l),g=o.formatTooltip(s,!1,l,this._renderMode);S(g)?(d=g.html,f=g.markers):(d=g,f=null);var v="item_"+o.name+"_"+s;this._showOrMove(h,function(){this._showTooltipContent(h,d,p,v,t.offsetX,t.offsetY,t.position,t.target,f)}),i({type:"showTip",dataIndexInside:s,dataIndex:u.getRawIndex(s),seriesIndex:r,from:this.uid})}},_showComponentItemTooltip:function(t,e,i){var n=e.tooltip;if("string"==typeof n){var r=n;n={content:r,formatter:r}}var a=new Qa(n,this._tooltipModel,this._ecModel),o=a.get("content"),s=Math.random();this._showOrMove(a,function(){this._showTooltipContent(a,o,a.get("formatterParams")||{},s,t.offsetX,t.offsetY,t.position,e)}),i({type:"showTip",from:this.uid})},_showTooltipContent:function(t,e,i,n,r,a,o,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent,h=t.get("formatter");o=o||t.get("position");var c=e;if(h&&"string"==typeof h)c=Co(h,i,!0);else if("function"==typeof h){var d=FS(function(e,n){e===this._ticket&&(u.setContent(n,l,t),this._updatePosition(t,o,r,a,u,i,s))},this);this._ticket=n,c=h(i,n,d)}u.setContent(c,l,t),u.show(t),this._updatePosition(t,o,r,a,u,i,s)}},_updatePosition:function(t,e,i,n,r,a,o){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=r.getSize(),h=t.get("align"),c=t.get("verticalAlign"),d=o&&o.getBoundingRect().clone();if(o&&d.applyTransform(o.transform),"function"==typeof e&&(e=e([i,n],a,r.el,d,{viewSize:[s,l],contentSize:u.slice()})),x(e))i=VS(e[0],s),n=VS(e[1],l);else if(S(e)){e.width=u[0],e.height=u[1];var f=Bo(e,{width:s,height:l});i=f.x,n=f.y,h=null,c=null}else if("string"==typeof e&&o){var p=Qd(e,d,u);i=p[0],n=p[1]}else{var p=Kd(i,n,r,s,l,h?null:20,c?null:20);i=p[0],n=p[1]}if(h&&(i-=Jd(h)?u[0]/2:"right"===h?u[0]:0),c&&(n-=Jd(c)?u[1]/2:"bottom"===c?u[1]:0),t.get("confine")){var p=$d(i,n,r,s,l);i=p[0],n=p[1]}r.moveTo(i,n)},_updateContentNotChangedOnAxis:function(t){var e=this._lastDataByCoordSys,i=!!e&&e.length===t.length;return i&&GS(e,function(e,n){var r=e.dataByAxis||{},a=t[n]||{},o=a.dataByAxis||[];i&=r.length===o.length,i&&GS(r,function(t,e){var n=o[e]||{},r=t.seriesDataIndices||[],a=n.seriesDataIndices||[];i&=t.value===n.value&&t.axisType===n.axisType&&t.axisId===n.axisId&&r.length===a.length,i&&GS(r,function(t,e){var n=a[e];i&=t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})})}),this._lastDataByCoordSys=t,!!i},_hide:function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},dispose:function(t,e){gp.node||(this._tooltipContent.hide(),Cd("itemTooltip",e))}}),ou({type:"showTip",event:"showTip",update:"tooltip:manuallyShowTip"},function(){}),ou({type:"hideTip",event:"hideTip",update:"tooltip:manuallyHideTip"},function(){});var WS=So,US=Io,XS=fu({type:"marker",dependencies:["series","grid","polar","geo"],init:function(t,e,i){this.mergeDefaultAndTheme(t,i),this._mergeOption(t,i,!1,!0)},isAnimationEnabled:function(){if(gp.node)return!1;var t=this.__hostSeries;return this.getShallow("animation")&&t&&t.isAnimationEnabled()},mergeOption:function(t,e){this._mergeOption(t,e,!1,!1)},_mergeOption:function(t,e,i,n){var r=this.constructor,a=this.mainType+"Model";i||e.eachSeries(function(t){var i=t.get(this.mainType,!0),s=t[a];return i&&i.data?(s?s._mergeOption(i,e,!0):(n&&tf(i),f(i.data,function(t){t instanceof Array?(tf(t[0]),tf(t[1])):tf(t)}),s=new r(i,this,e),o(s,{mainType:this.mainType,seriesIndex:t.seriesIndex,name:t.name,createdBySelf:!0}),s.__hostSeries=t),void(t[a]=s)):void(t[a]=null)},this)},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=x(i)?p(i,WS).join(", "):WS(i),r=e.getName(t),a=US(this.name);return(null!=i||r)&&(a+="
"),r&&(a+=US(r),null!=i&&(a+=" : ")),null!=i&&(a+=US(n)),a},getData:function(){return this._data},setData:function(t){this._data=t}});c(XS,O_),XS.extend({type:"markLine",defaultOption:{zlevel:0,z:5,symbol:["circle","arrow"],symbolSize:[8,16],precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end"},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"}});var YS=u,jS=_,qS={min:jS(rf,"min"),max:jS(rf,"max"),average:jS(rf,"average")},ZS=iy.prototype,KS=ry.prototype,$S=ta({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){this[cf(e)?"_buildPathLine":"_buildPathCurve"](t,e)},_buildPathLine:ZS.buildPath,_buildPathCurve:KS.buildPath,pointAt:function(t){return this[cf(this.shape)?"_pointAtLine":"_pointAtCurve"](t)},_pointAtLine:ZS.pointAt,_pointAtCurve:KS.pointAt,tangentAt:function(t){var e=this.shape,i=cf(e)?[e.x2-e.x1,e.y2-e.y1]:this._tangentAtCurve(t);return te(i,i)},_tangentAtCurve:KS.tangentAt}),QS=["fromSymbol","toSymbol"],JS=mf.prototype;JS.beforeUpdate=vf,JS._createLine=function(t,e,i){var n=t.hostModel,r=t.getItemLayout(e),a=pf(r);a.shape.percent=0,Ga(a,{shape:{percent:1}},n,e),this.add(a);var o=new Hm({name:"label",lineLabelOriginalOpacity:1});this.add(o),f(QS,function(i){var n=ff(i,t,e);this.add(n),this[df(i)]=t.getItemVisual(e,i)},this),this._updateCommonStl(t,e,i)},JS.updateData=function(t,e,i){var n=t.hostModel,r=this.childOfName("line"),a=t.getItemLayout(e),o={shape:{}};gf(o.shape,a),Fa(r,o,n,e),f(QS,function(i){var n=t.getItemVisual(e,i),r=df(i);if(this[r]!==n){this.remove(this.childOfName(i));var a=ff(i,t,e);this.add(a)}this[r]=n},this),this._updateCommonStl(t,e,i)},JS._updateCommonStl=function(t,e,i){var n=t.hostModel,r=this.childOfName("line"),a=i&&i.lineStyle,o=i&&i.hoverLineStyle,l=i&&i.labelModel,u=i&&i.hoverLabelModel;if(!i||t.hasItemOption){var h=t.getItemModel(e);a=h.getModel("lineStyle").getLineStyle(),o=h.getModel("emphasis.lineStyle").getLineStyle(),l=h.getModel("label"),u=h.getModel("emphasis.label")}var c=t.getItemVisual(e,"color"),d=k(t.getItemVisual(e,"opacity"),a.opacity,1);r.useStyle(s({strokeNoScale:!0,fill:"none",stroke:c,opacity:d},a)),r.hoverStyle=o,f(QS,function(t){var e=this.childOfName(t);e&&(e.setColor(c),e.setStyle({opacity:d}))},this);var p,g,v=l.getShallow("show"),m=u.getShallow("show"),y=this.childOfName("label");if((v||m)&&(p=c||"#000",g=n.getFormattedLabel(e,"normal",t.dataType),null==g)){var _=n.getRawValue(e);g=null==_?t.getName(e):isFinite(_)?so(_):_}var x=v?g:null,w=m?A(n.getFormattedLabel(e,"emphasis",t.dataType),g):null,b=y.style;(null!=x||null!=w)&&(Aa(y.style,l,{text:x},{autoColor:p}),y.__textAlign=b.textAlign,y.__verticalAlign=b.textVerticalAlign,y.__position=l.get("position")||"middle"),y.hoverStyle=null!=w?{text:w,textFill:u.getTextColor(!0),fontStyle:u.getShallow("fontStyle"),fontWeight:u.getShallow("fontWeight"),fontSize:u.getShallow("fontSize"),fontFamily:u.getShallow("fontFamily")}:{text:null},y.ignore=!v&&!m,Sa(this)},JS.highlight=function(){this.trigger("emphasis")},JS.downplay=function(){this.trigger("normal")},JS.updateLayout=function(t,e){this.setLinePoints(t.getItemLayout(e))},JS.setLinePoints=function(t){var e=this.childOfName("line");gf(e.shape,t),e.dirty()},h(mf,Dg);var tM=yf.prototype;tM.isPersistent=function(){return!0},tM.updateData=function(t){var e=this,i=e.group,n=e._lineData;e._lineData=t,n||i.removeAll();var r=wf(t);t.diff(n).add(function(i){_f(e,t,i,r)}).update(function(i,a){xf(e,n,t,a,i,r)}).remove(function(t){i.remove(n.getItemGraphicEl(t))}).execute()},tM.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl(function(e,i){e.updateLayout(t,i)},this)},tM.incrementalPrepareUpdate=function(t){this._seriesScope=wf(t),this._lineData=null,this.group.removeAll()},tM.incrementalUpdate=function(t,e){function i(t){t.isGroup||(t.incremental=t.useHoverLayer=!0)}for(var n=t.start;n=0&&"number"==typeof h&&(h=+h.toFixed(Math.min(m,20))),g.coord[f]=v.coord[f]=h,a=[g,v,{type:l,valueIndex:a.valueIndex,value:h}]}return a=[af(t,a[0]),af(t,a[1]),o({},a[2])],a[2].type=a[2].type||"",r(a[2],a[0]),r(a[2],a[1]),a};eM.extend({type:"markLine",updateTransform:function(t,e,i){e.eachSeries(function(t){var e=t.markLineModel;if(e){var n=e.getData(),r=e.__from,a=e.__to;r.each(function(e){Tf(r,e,!0,t,i),Tf(a,e,!1,t,i)}),n.each(function(t){n.setItemLayout(t,[r.getItemLayout(t),a.getItemLayout(t)])}),this.markerGroupMap.get(t.id).updateLayout()}},this)},renderSeries:function(t,e,i,n){function r(e,i,r){var a=e.getItemModel(i);Tf(e,i,r,t,n),e.setItemVisual(i,{symbolSize:a.get("symbolSize")||g[r?0:1],symbol:a.get("symbol",!0)||p[r?0:1],color:a.get("itemStyle.color")||s.getVisual("color")})}var a=t.coordinateSystem,o=t.id,s=t.getData(),l=this.markerGroupMap,u=l.get(o)||l.set(o,new yf);this.group.add(u.group);var h=Df(a,t,e),c=h.from,d=h.to,f=h.line;e.__from=c,e.__to=d,e.setData(f);var p=e.get("symbol"),g=e.get("symbolSize");x(p)||(p=[p,p]),"number"==typeof g&&(g=[g,g]),h.from.each(function(t){r(c,t,!0),r(d,t,!1)}),f.each(function(t){var e=f.getItemModel(t).get("lineStyle.color");f.setItemVisual(t,{color:e||c.getItemVisual(t,"color")}),f.setItemLayout(t,[c.getItemLayout(t),d.getItemLayout(t)]),f.setItemVisual(t,{fromSymbolSize:c.getItemVisual(t,"symbolSize"),fromSymbol:c.getItemVisual(t,"symbol"),toSymbolSize:d.getItemVisual(t,"symbolSize"),toSymbol:d.getItemVisual(t,"symbol")})}),u.updateData(f),h.line.eachItemGraphicEl(function(t){t.traverse(function(t){t.dataModel=e})}),u.__keep=!0,u.group.silent=e.get("silent")||t.get("silent")}}),nu(function(t){t.markLine=t.markLine||{}});var nM=function(t){var e=t&&t.timeline;x(e)||(e=e?[e]:[]),f(e,function(t){t&&Af(t)})};Ky.registerSubTypeDefaulter("timeline",function(){return"slider"}),ou({type:"timelineChange",event:"timelineChanged",update:"prepareAndUpdate"},function(t,e){var i=e.getComponent("timeline");return i&&null!=t.currentIndex&&(i.setCurrentIndex(t.currentIndex),!i.get("loop",!0)&&i.isIndexMax()&&i.setPlayState(!1)),e.resetOption("timeline"),s({currentIndex:i.option.currentIndex},t)}),ou({type:"timelinePlayChange",event:"timelinePlayChanged",update:"update"},function(t,e){var i=e.getComponent("timeline");i&&null!=t.playState&&i.setPlayState(t.playState)});var rM=Ky.extend({type:"timeline",layoutMode:"box",defaultOption:{zlevel:0,z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},init:function(t,e,i){this._data,this._names,this.mergeDefaultAndTheme(t,i),this._initData()},mergeOption:function(){rM.superApply(this,"mergeOption",arguments),this._initData()},setCurrentIndex:function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),0>t&&(t=0)),this.option.currentIndex=t},getCurrentIndex:function(){return this.option.currentIndex},isIndexMax:function(){return this.getCurrentIndex()>=this._data.count()-1},setPlayState:function(t){this.option.autoPlay=!!t},getPlayState:function(){return!!this.option.autoPlay},_initData:function(){var t=this.option,e=t.data||[],i=t.axisType,r=this._names=[];if("category"===i){var a=[];f(e,function(t,e){var i,o=Vn(t);S(t)?(i=n(t),i.value=e):i=e,a.push(i),b(o)||null!=o&&!isNaN(o)||(o=""),r.push(o+"")}),e=a}var o={category:"ordinal",time:"time"}[i]||"number",s=this._data=new ww([{name:"value",type:o}],this);s.initData(e,r)},getData:function(){return this._data},getCategories:function(){return"category"===this.get("axisType")?this._names.slice():void 0}}),aM=rM.extend({type:"timeline.slider",defaultOption:{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"emptyCircle",symbolSize:10,lineStyle:{show:!0,width:2,color:"#304654"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#304654"},itemStyle:{color:"#304654",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:13,color:"#c23531",borderWidth:5,borderColor:"rgba(194,53,49, 0.5)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:22,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z",prevIcon:"path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z",color:"#304654",borderColor:"#304654",borderWidth:1},emphasis:{label:{show:!0,color:"#c23531"},itemStyle:{color:"#c23531"},controlStyle:{color:"#c23531",borderColor:"#c23531",borderWidth:2}},data:[]}});c(aM,O_);var oM=N_.extend({type:"timeline"}),sM=function(t,e,i,n){pb.call(this,t,e,i),this.type=n||"value",this.model=null};sM.prototype={constructor:sM,getLabelModel:function(){return this.model.getModel("label")},isHorizontal:function(){return"horizontal"===this.model.get("orient")}},h(sM,pb);var lM=y,uM=f,hM=Math.PI;oM.extend({type:"timeline.slider",init:function(t,e){this.api=e,this._axis,this._viewRect,this._timer,this._currentPointer,this._mainGroup,this._labelGroup},render:function(t,e,i){if(this.model=t,this.api=i,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var n=this._layout(t,i),r=this._createGroup("mainGroup"),a=this._createGroup("labelGroup"),o=this._axis=this._createAxis(n,t);t.formatTooltip=function(t){return Io(o.scale.getLabel(t))},uM(["AxisLine","AxisTick","Control","CurrentPointer"],function(e){this["_render"+e](n,r,o,t)},this),this._renderAxisLabel(n,a,o,t),this._position(n,t)}this._doPlayStop()},remove:function(){this._clearTimer(),this.group.removeAll()},dispose:function(){this._clearTimer()},_layout:function(t,e){var i=t.get("label.position"),n=t.get("orient"),r=Lf(t,e);null==i||"auto"===i?i="horizontal"===n?r.y+r.height/2=0||"+"===i?"left":"right"},o={horizontal:i>=0||"+"===i?"top":"bottom",vertical:"middle"},s={horizontal:0,vertical:hM/2},l="vertical"===n?r.height:r.width,u=t.getModel("controlStyle"),h=u.get("show",!0),c=h?u.get("itemSize"):0,d=h?u.get("itemGap"):0,f=c+d,p=t.get("label.rotate")||0;p=p*hM/180;var g,v,m,y,_=u.get("position",!0),x=h&&u.get("showPlayBtn",!0),w=h&&u.get("showPrevBtn",!0),b=h&&u.get("showNextBtn",!0),S=0,M=l;return"left"===_||"bottom"===_?(x&&(g=[0,0],S+=f),w&&(v=[S,0],S+=f),b&&(m=[M-c,0],M-=f)):(x&&(g=[M-c,0],M-=f),w&&(v=[0,0],S+=f),b&&(m=[M-c,0],M-=f)),y=[S,M],t.get("inverse")&&y.reverse(),{viewRect:r,mainLength:l,orient:n,rotation:s[n],labelRotation:p,labelPosOpt:i,labelAlign:t.get("label.align")||a[n],labelBaseline:t.get("label.verticalAlign")||t.get("label.baseline")||o[n],playPosition:g,prevBtnPosition:v,nextBtnPosition:m,axisExtent:y,controlSize:c,controlGap:d}},_position:function(t){function e(t){var e=t.position;t.origin=[h[0][0]-e[0],h[1][0]-e[1]]}function i(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function n(t,e,i,n,r){t[n]+=i[n][r]-e[n][r]}var r=this._mainGroup,a=this._labelGroup,o=t.viewRect;if("vertical"===t.orient){var s=Te(),l=o.x,u=o.y+o.height;Pe(s,s,[-l,-u]),Le(s,s,-hM/2),Pe(s,s,[l,u]),o=o.clone(),o.applyTransform(s)}var h=i(o),c=i(r.getBoundingRect()),d=i(a.getBoundingRect()),f=r.position,p=a.position;p[0]=f[0]=h[0][0];var g=t.labelPosOpt;if(isNaN(g)){var v="+"===g?0:1;n(f,c,h,1,v),n(p,d,h,1,1-v)}else{var v=g>=0?0:1;n(f,c,h,1,v),p[1]=f[1]+g}r.attr("position",f),a.attr("position",p),r.rotation=a.rotation=t.rotation,e(r),e(a)},_createAxis:function(t,e){var i=e.getData(),n=e.get("axisType"),r=yh(e,n);r.getTicks=function(){return i.mapArray(["value"],function(t){return t})};var a=i.getDataExtent("value");r.setExtent(a[0],a[1]),r.niceTicks();var o=new sM("value",r,t.axisExtent,n);return o.model=e,o},_createGroup:function(t){var e=this["_"+t]=new Dg;return this.group.add(e),e},_renderAxisLine:function(t,e,i,n){var r=i.getExtent();n.get("lineStyle.show")&&e.add(new iy({shape:{x1:r[0],y1:0,x2:r[1],y2:0},style:o({lineCap:"round"},n.getModel("lineStyle").getLineStyle()),silent:!0,z2:1}))},_renderAxisTick:function(t,e,i,n){var r=n.getData(),a=i.scale.getTicks();uM(a,function(t){var a=i.dataToCoord(t),o=r.getItemModel(t),s=o.getModel("itemStyle"),l=o.getModel("emphasis.itemStyle"),u={position:[a,0],onclick:lM(this._changeTimeline,this,t)},h=zf(o,s,e,u);Sa(h,l.getItemStyle()),o.get("tooltip")?(h.dataIndex=t,h.dataModel=n):h.dataIndex=h.dataModel=null},this)},_renderAxisLabel:function(t,e,i,n){var r=i.getLabelModel();if(r.get("show")){var a=n.getData(),o=i.getViewLabels();uM(o,function(n){var r=n.tickValue,o=a.getItemModel(r),s=o.getModel("label"),l=o.getModel("emphasis.label"),u=i.dataToCoord(n.tickValue),h=new Hm({position:[u,0],rotation:t.labelRotation-t.rotation,onclick:lM(this._changeTimeline,this,r),silent:!1});Aa(h.style,s,{text:n.formattedLabel,textAlign:t.labelAlign,textVerticalAlign:t.labelBaseline}),e.add(h),Sa(h,Aa({},l))},this)}},_renderControl:function(t,e,i,n){function r(t,i,r,h){if(t){var c={position:t,origin:[a/2,0],rotation:h?-o:0,rectHover:!0,style:s,onclick:r},d=Of(n,i,u,c);e.add(d),Sa(d,l)}}var a=t.controlSize,o=t.rotation,s=n.getModel("controlStyle").getItemStyle(),l=n.getModel("emphasis.controlStyle").getItemStyle(),u=[0,-a/2,a,a],h=n.getPlayState(),c=n.get("inverse",!0);r(t.nextBtnPosition,"controlStyle.nextIcon",lM(this._changeTimeline,this,c?"-":"+")),r(t.prevBtnPosition,"controlStyle.prevIcon",lM(this._changeTimeline,this,c?"+":"-")),r(t.playPosition,"controlStyle."+(h?"stopIcon":"playIcon"),lM(this._handlePlayClick,this,!h),!0)},_renderCurrentPointer:function(t,e,i,n){var r=n.getData(),a=n.getCurrentIndex(),o=r.getItemModel(a).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=lM(s._handlePointerDrag,s),t.ondragend=lM(s._handlePointerDragend,s),Bf(t,a,i,n,!0)},onUpdate:function(t){Bf(t,a,i,n)}};this._currentPointer=zf(o,o,this._mainGroup,{},this._currentPointer,l)},_handlePlayClick:function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},_handlePointerDrag:function(t,e,i){this._clearTimer(),this._pointerChangeTimeline([i.offsetX,i.offsetY])},_handlePointerDragend:function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},_pointerChangeTimeline:function(t,e){var i=this._toAxisCoord(t)[0],n=this._axis,r=lo(n.getExtent().slice());i>r[1]&&(i=r[1]),is&&(n=s,e=a)}),e},_clearTimer:function(){this._timer&&(clearTimeout(this._timer),this._timer=null)},_changeTimeline:function(t){var e=this.model.getCurrentIndex();"+"===t?t=e+1:"-"===t&&(t=e-1),this.api.dispatchAction({type:"timelineChange",currentIndex:t,from:this.uid})}}),nu(nM);var cM="http://www.w3.org/2000/svg",dM=mm.CMD,fM=Array.prototype.join,pM="none",gM=Math.round,vM=Math.sin,mM=Math.cos,yM=Math.PI,_M=2*Math.PI,xM=180/yM,wM=1e-4,bM={};bM.brush=function(t){var e=t.style,i=t.__svgEl;i||(i=Ef("path"),t.__svgEl=i),t.path||t.createPathProxy();var n=t.path;if(t.__dirtyPath){n.beginPath(),n.subPixelOptimize=!1,t.buildPath(n,t.shape),t.__dirtyPath=!1;var r=Xf(n);r.indexOf("NaN")<0&&Hf(i,"d",r)}Uf(i,e,!1,t),Vf(i,t.transform),null!=e.text&&AM(t,t.getBoundingRect())};var SM={};SM.brush=function(t){var e=t.style,i=e.image;if(i instanceof HTMLImageElement){var n=i.src;i=n}if(i){var r=e.x||0,a=e.y||0,o=e.width,s=e.height,l=t.__svgEl;l||(l=Ef("image"),t.__svgEl=l),i!==t.__imageSrc&&(Wf(l,"href",i),t.__imageSrc=i),Hf(l,"width",o),Hf(l,"height",s),Hf(l,"x",r),Hf(l,"y",a),Vf(l,t.transform),null!=e.text&&AM(t,t.getBoundingRect())}};var MM={},IM=new xi,CM={},TM=[],DM={left:"start",right:"end",center:"middle",middle:"middle"},AM=function(t,e){var i=t.style,n=t.transform,r=t instanceof Hm||i.transformText;t.__dirty&&nn(i,!0);var a=i.text;if(null!=a&&(a+=""),xn(a,i)){null==a&&(a=""),!r&&n&&(IM.copy(e),IM.applyTransform(n),e=IM);var o=t.__textSvgEl;o||(o=Ef("text"),t.__textSvgEl=o);var s=o.style,l=i.font||Zg,u=o.__computedFont;l!==o.__styleFont&&(s.font=o.__styleFont=l,u=o.__computedFont=s.font);var h=i.textPadding,c=i.textLineHeight,d=t.__textCotentBlock;(!d||t.__dirtyText)&&(d=t.__textCotentBlock=$i(a,u,h,c,i.truncate));var f=d.outerHeight,p=d.lineHeight;pn(CM,t,i,e);var g=CM.baseX,v=CM.baseY,m=CM.textAlign||"left",y=CM.textVerticalAlign;Yf(o,r,n,i,e,g,v);var _=Wi(v,f,y),x=g,w=_;h&&(x=jf(g,m,h),w+=h[0]),w+=p/2,Uf(o,i,!0,t);var b=d.canCacheByTextString,S=t.__tspanList||(t.__tspanList=[]),M=S.length;if(b&&t.__canCacheByTextString&&t.__text===a){if(t.__dirtyText&&M)for(var I=0;M>I;++I)qf(S[I],m,x,w+I*p)}else{t.__text=a,t.__canCacheByTextString=b;for(var C=d.lines,T=C.length,I=0;T>I;I++){var D=S[I],A=C[I];D?D.__zrText!==A&&(D.innerHTML="",D.appendChild(document.createTextNode(A))):(D=S[I]=Ef("tspan"),o.appendChild(D),D.appendChild(document.createTextNode(A))),qf(D,m,x,w+I*p)}if(M>T){for(;M>I;I++)o.removeChild(S[I]);S.length=T}}}};MM.drawRectText=AM,MM.brush=function(t){var e=t.style;null!=e.text&&AM(t,!1)},Zf.prototype={diff:function(t,e,i){function n(){for(var i=-1*s;s>=i;i+=2){var n,l=u[i-1],h=u[i+1],c=(h?h.newPos:0)-i;l&&(u[i-1]=void 0);var d=l&&l.newPos+1=0&&o>c;if(d||f){if(!d||f&&l.newPos=a&&c+1>=o)return Kf(r,n.components,e,t);u[i]=n}else u[i]=void 0}s++}i||(i=function(t,e){return t===e}),this.equals=i;var r=this;t=t.slice(),e=e.slice();var a=e.length,o=t.length,s=1,l=a+o,u=[{newPos:-1,components:[]}],h=this.extractCommon(u[0],e,t,0);if(u[0].newPos+1>=a&&h+1>=o){for(var c=[],d=0;d=s;){var f=n();if(f)return f}},pushComponent:function(t,e,i){var n=t[t.length-1];n&&n.added===e&&n.removed===i?t[t.length-1]={count:n.count+1,added:e,removed:i}:t.push({count:1,added:e,removed:i})},extractCommon:function(t,e,i,n){for(var r=e.length,a=i.length,o=t.newPos,s=o-n,l=0;r>o+1&&a>s+1&&this.equals(e[o+1],i[s+1]);)o++,s++,l++;return l&&t.components.push({count:l}),t.newPos=o,s},tokenize:function(t){return t.slice()},join:function(t){return t.slice()}};var kM=new Zf,PM=function(t,e,i){return kM.diff(t,e,i)},LM="0",OM="1";Qf.prototype.createElement=Ef,Qf.prototype.getDefs=function(t){var e=this._svgRoot,i=this._svgRoot.getElementsByTagName("defs"); -return 0===i.length?t?(i=e.insertBefore(this.createElement("defs"),e.firstChild),i.contains||(i.contains=function(t){var e=i.children;if(!e)return!1;for(var n=e.length-1;n>=0;--n)if(e[n]===t)return!0;return!1}),i):null:i[0]},Qf.prototype.update=function(t,e){if(t){var i=this.getDefs(!1);if(t[this._domName]&&i.contains(t[this._domName]))"function"==typeof e&&e(t);else{var n=this.add(t);n&&(t[this._domName]=n)}}},Qf.prototype.addDom=function(t){var e=this.getDefs(!0);e.appendChild(t)},Qf.prototype.removeDom=function(t){var e=this.getDefs(!1);e&&t[this._domName]&&(e.removeChild(t[this._domName]),t[this._domName]=null)},Qf.prototype.getDoms=function(){var t=this.getDefs(!1);if(!t)return[];var e=[];return f(this._tagNames,function(i){var n=t.getElementsByTagName(i);e=e.concat([].slice.call(n))}),e},Qf.prototype.markAllUnused=function(){var t=this.getDoms(),e=this;f(t,function(t){t[e._markLabel]=LM})},Qf.prototype.markUsed=function(t){t&&(t[this._markLabel]=OM)},Qf.prototype.removeUnused=function(){var t=this.getDefs(!1);if(t){var e=this.getDoms(),i=this;f(e,function(e){e[i._markLabel]!==OM&&t.removeChild(e)})}},Qf.prototype.getSvgProxy=function(t){return t instanceof Gr?bM:t instanceof bn?SM:t instanceof Hm?MM:bM},Qf.prototype.getTextSvgElement=function(t){return t.__textSvgEl},Qf.prototype.getSvgElement=function(t){return t.__svgEl},h(Jf,Qf),Jf.prototype.addWithoutUpdate=function(t,e){if(e&&e.style){var i=this;f(["fill","stroke"],function(n){if(e.style[n]&&("linear"===e.style[n].type||"radial"===e.style[n].type)){var r,a=e.style[n],o=i.getDefs(!0);a._dom?(r=a._dom,o.contains(a._dom)||i.addDom(r)):r=i.add(a),i.markUsed(e);var s=r.getAttribute("id");t.setAttribute(n,"url(#"+s+")")}})}},Jf.prototype.add=function(t){var e;if("linear"===t.type)e=this.createElement("linearGradient");else{if("radial"!==t.type)return bg("Illegal gradient type."),null;e=this.createElement("radialGradient")}return t.id=t.id||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-gradient-"+t.id),this.updateDom(t,e),this.addDom(e),e},Jf.prototype.update=function(t){var e=this;Qf.prototype.update.call(this,t,function(){var i=t.type,n=t._dom.tagName;"linear"===i&&"linearGradient"===n||"radial"===i&&"radialGradient"===n?e.updateDom(t,t._dom):(e.removeDom(t),e.add(t))})},Jf.prototype.updateDom=function(t,e){if("linear"===t.type)e.setAttribute("x1",t.x),e.setAttribute("y1",t.y),e.setAttribute("x2",t.x2),e.setAttribute("y2",t.y2);else{if("radial"!==t.type)return void bg("Illegal gradient type.");e.setAttribute("cx",t.x),e.setAttribute("cy",t.y),e.setAttribute("r",t.r)}t.global?e.setAttribute("gradientUnits","userSpaceOnUse"):e.setAttribute("gradientUnits","objectBoundingBox"),e.innerHTML="";for(var i=t.colorStops,n=0,r=i.length;r>n;++n){var a=this.createElement("stop");a.setAttribute("offset",100*i[n].offset+"%");var o=i[n].color;if(o.indexOf(!1)){var s=qe(o)[3],l=Qe(o);a.setAttribute("stop-color","#"+l),a.setAttribute("stop-opacity",s)}else a.setAttribute("stop-color",i[n].color);e.appendChild(a)}t._dom=e},Jf.prototype.markUsed=function(t){if(t.style){var e=t.style.fill;e&&e._dom&&Qf.prototype.markUsed.call(this,e._dom),e=t.style.stroke,e&&e._dom&&Qf.prototype.markUsed.call(this,e._dom)}},h(tp,Qf),tp.prototype.update=function(t){var e=this.getSvgElement(t);e&&this.updateDom(e,t.__clipPaths,!1);var i=this.getTextSvgElement(t);i&&this.updateDom(i,t.__clipPaths,!0),this.markUsed(t)},tp.prototype.updateDom=function(t,e,i){if(e&&e.length>0){var n,r,a=this.getDefs(!0),o=e[0],s=i?"_textDom":"_dom";o[s]?(r=o[s].getAttribute("id"),n=o[s],a.contains(n)||a.appendChild(n)):(r="zr"+this._zrId+"-clip-"+this.nextId,++this.nextId,n=this.createElement("clipPath"),n.setAttribute("id",r),a.appendChild(n),o[s]=n);var l=this.getSvgProxy(o);if(o.transform&&o.parent.invTransform&&!i){var u=Array.prototype.slice.call(o.transform);ke(o.transform,o.parent.invTransform,o.transform),l.brush(o),o.transform=u}else l.brush(o);var h=this.getSvgElement(o);n.innerHTML="",n.appendChild(h.cloneNode()),t.setAttribute("clip-path","url(#"+r+")"),e.length>1&&this.updateDom(n,e.slice(1),i)}else t&&t.setAttribute("clip-path","none")},tp.prototype.markUsed=function(t){var e=this;t.__clipPaths&&f(t.__clipPaths,function(t){t._dom&&Qf.prototype.markUsed.call(e,t._dom),t._textDom&&Qf.prototype.markUsed.call(e,t._textDom)})},h(ep,Qf),ep.prototype.addWithoutUpdate=function(t,e){if(e&&ip(e.style)){var i;if(e._shadowDom){i=e._shadowDom;var n=this.getDefs(!0);n.contains(e._shadowDom)||this.addDom(i)}else i=this.add(e);this.markUsed(e);var r=i.getAttribute("id");t.style.filter="url(#"+r+")"}},ep.prototype.add=function(t){var e=this.createElement("filter");return t._shadowDomId=t._shadowDomId||this.nextId++,e.setAttribute("id","zr"+this._zrId+"-shadow-"+t._shadowDomId),this.updateDom(t,e),this.addDom(e),e},ep.prototype.update=function(t,e){var i=e.style;if(ip(i)){var n=this;Qf.prototype.update.call(this,e,function(){n.updateDom(e,e._shadowDom)})}else this.remove(t,e)},ep.prototype.remove=function(t,e){null!=e._shadowDomId&&(this.removeDom(t),t.style.filter="")},ep.prototype.updateDom=function(t,e){var i=e.getElementsByTagName("feDropShadow");i=0===i.length?this.createElement("feDropShadow"):i[0];var n,r,a,o,s=t.style,l=t.scale?t.scale[0]||1:1,u=t.scale?t.scale[1]||1:1;if(s.shadowBlur||s.shadowOffsetX||s.shadowOffsetY)n=s.shadowOffsetX||0,r=s.shadowOffsetY||0,a=s.shadowBlur,o=s.shadowColor;else{if(!s.textShadowBlur)return void this.removeDom(e,s);n=s.textShadowOffsetX||0,r=s.textShadowOffsetY||0,a=s.textShadowBlur,o=s.textShadowColor}i.setAttribute("dx",n/l),i.setAttribute("dy",r/u),i.setAttribute("flood-color",o);var h=a/2/l,c=a/2/u,d=h+" "+c;i.setAttribute("stdDeviation",d),e.setAttribute("x","-100%"),e.setAttribute("y","-100%"),e.setAttribute("width",Math.ceil(a/2*200)+"%"),e.setAttribute("height",Math.ceil(a/2*200)+"%"),e.appendChild(i),t._shadowDom=e},ep.prototype.markUsed=function(t){t._shadowDom&&Qf.prototype.markUsed.call(this,t._shadowDom)};var zM=function(t,e,i,n){this.root=t,this.storage=e,this._opts=i=o({},i||{});var r=Ef("svg");r.setAttribute("xmlns","http://www.w3.org/2000/svg"),r.setAttribute("version","1.1"),r.setAttribute("baseProfile","full"),r.style.cssText="user-select:none;position:absolute;left:0;top:0;",this.gradientManager=new Jf(n,r),this.clipPathManager=new tp(n,r),this.shadowManager=new ep(n,r);var a=document.createElement("div");a.style.cssText="overflow:hidden;position:relative",this._svgRoot=r,this._viewport=a,t.appendChild(a),a.appendChild(r),this.resize(i.width,i.height),this._visibleList=[]};zM.prototype={constructor:zM,getType:function(){return"svg"},getViewportRoot:function(){return this._viewport},getViewportRootOffset:function(){var t=this.getViewportRoot();return t?{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}:void 0},refresh:function(){var t=this.storage.getDisplayList(!0);this._paintList(t)},setBackgroundColor:function(t){this._viewport.style.background=t},_paintList:function(t){this.gradientManager.markAllUnused(),this.clipPathManager.markAllUnused(),this.shadowManager.markAllUnused();var e,i=this._svgRoot,n=this._visibleList,r=t.length,a=[];for(e=0;r>e;e++){var o=t[e],s=rp(o),l=hp(o)||up(o);o.invisible||(o.__dirty&&(s&&s.brush(o),this.clipPathManager.update(o),o.style&&(this.gradientManager.update(o.style.fill),this.gradientManager.update(o.style.stroke),this.shadowManager.update(l,o)),o.__dirty=!1),a.push(o))}var u,h=PM(n,a);for(e=0;e=0;--n)if(e[n]===t)return!0;return!1}),i}return null}return i[0]},resize:function(t,e){var i=this._viewport;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n.height=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!==t||this._height!==e){this._width=t,this._height=e;var r=i.style;r.width=t+"px",r.height=e+"px";var a=this._svgRoot;a.setAttribute("width",t),a.setAttribute("height",e)}},getWidth:function(){return this._width},getHeight:function(){return this._height},_getSize:function(t){var e=this._opts,i=["width","height"][t],n=["clientWidth","clientHeight"][t],r=["paddingLeft","paddingTop"][t],a=["paddingRight","paddingBottom"][t];if(null!=e[i]&&"auto"!==e[i])return parseFloat(e[i]);var o=this.root,s=document.defaultView.getComputedStyle(o);return(o[n]||np(s[i])||np(o.style[i]))-(np(s[r])||0)-(np(s[a])||0)|0},dispose:function(){this.root.innerHTML="",this._svgRoot=this._viewport=this.storage=null},clear:function(){this._viewport&&this.root.removeChild(this._viewport)},pathToDataUrl:function(){this.refresh();var t=this._svgRoot.outerHTML;return"data:image/svg+xml;charset=UTF-8,"+t}},f(["getLayer","insertLayer","eachLayer","eachBuiltinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","toDataURL","pathToImage"],function(t){zM.prototype[t]=cp(t)}),Rn("svg",zM),t.version=Dx,t.dependencies=Ax,t.PRIORITY=Hx,t.init=Kl,t.connect=$l,t.disConnect=Ql,t.disconnect=lw,t.dispose=Jl,t.getInstanceByDom=tu,t.getInstanceById=eu,t.registerTheme=iu,t.registerPreprocessor=nu,t.registerProcessor=ru,t.registerPostUpdate=au,t.registerAction=ou,t.registerCoordinateSystem=su,t.getCoordinateSystemDimensions=lu,t.registerLayout=uu,t.registerVisual=hu,t.registerLoading=du,t.extendComponentModel=fu,t.extendComponentView=pu,t.extendSeriesModel=gu,t.extendChartView=vu,t.setCanvasCreator=mu,t.registerMap=yu,t.getMap=_u,t.dataTool=uw,t.zrender=Iv,t.number=Ey,t.format=Wy,t.throttle=tl,t.helper=ub,t.matrix=Kp,t.vector=Bp,t.color=gg,t.parseGeoJSON=cb,t.parseGeoJson=gb,t.util=vb,t.graphic=mb,t.List=ww,t.Model=Qa,t.Axis=pb,t.env=gp}); \ No newline at end of file diff --git a/src/JT808.DotNetty.CleintBenchmark/wwwroot/index.html b/src/JT808.DotNetty.CleintBenchmark/wwwroot/index.html deleted file mode 100644 index 8c6a6e5..0000000 --- a/src/JT808.DotNetty.CleintBenchmark/wwwroot/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - 收发查看 - - - - - - -
-
- - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpDecoder.cs b/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpDecoder.cs deleted file mode 100644 index 9dff52c..0000000 --- a/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpDecoder.cs +++ /dev/null @@ -1,20 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using System.Collections.Generic; -using JT808.Protocol; -using DotNetty.Transport.Channels; - -namespace JT808.DotNetty.Client.Codecs -{ - public class JT808ClientTcpDecoder : ByteToMessageDecoder - { - protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) - { - byte[] buffer = new byte[input.Capacity + 2]; - input.ReadBytes(buffer, 1, input.Capacity); - buffer[0] = JT808Package.BeginFlag; - buffer[input.Capacity + 1] = JT808Package.EndFlag; - output.Add(buffer); - } - } -} diff --git a/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpEncoder.cs b/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpEncoder.cs deleted file mode 100644 index a30070e..0000000 --- a/src/JT808.DotNetty.Client/Codecs/JT808ClientTcpEncoder.cs +++ /dev/null @@ -1,54 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using JT808.Protocol; -using DotNetty.Transport.Channels; -using Microsoft.Extensions.Logging; -using JT808.DotNetty.Client.Metadata; -using JT808.DotNetty.Client.Services; -using System; -using JT808.Protocol.Exceptions; - -namespace JT808.DotNetty.Client.Codecs -{ - public class JT808ClientTcpEncoder : MessageToByteEncoder - { - private readonly ILogger logger; - private readonly JT808SendAtomicCounterService jT808SendAtomicCounterService; - private readonly JT808Serializer JT808Serializer; - - public JT808ClientTcpEncoder( - IJT808Config jT808Config, - JT808SendAtomicCounterService jT808SendAtomicCounterService,ILoggerFactory loggerFactory) - { - logger=loggerFactory.CreateLogger(); - this.jT808SendAtomicCounterService = jT808SendAtomicCounterService; - JT808Serializer = jT808Config.GetSerializer(); - } - - protected override void Encode(IChannelHandlerContext context, JT808ClientRequest message, IByteBuffer output) - { - if (message.Package != null) - { - try - { - var sendData = JT808Serializer.Serialize(message.Package,version: message.Version, minBufferSize:message.MinBufferSize); - output.WriteBytes(sendData); - jT808SendAtomicCounterService.MsgSuccessIncrement(); - } - catch (JT808Exception ex) - { - logger.LogError(ex, context.Channel.Id.AsShortText()); - } - catch (Exception ex) - { - logger.LogError(ex,$" context.Channel.Id.AsShortText()"); - } - } - else if (message.HexData != null) - { - output.WriteBytes(message.HexData); - jT808SendAtomicCounterService.MsgSuccessIncrement(); - } - } - } -} diff --git a/src/JT808.DotNetty.Client/Handlers/JT808TcpClientConnectionHandler.cs b/src/JT808.DotNetty.Client/Handlers/JT808TcpClientConnectionHandler.cs deleted file mode 100644 index 86af42b..0000000 --- a/src/JT808.DotNetty.Client/Handlers/JT808TcpClientConnectionHandler.cs +++ /dev/null @@ -1,103 +0,0 @@ -using DotNetty.Handlers.Timeout; -using DotNetty.Transport.Channels; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using JT808.Protocol.MessageBody; -using Microsoft.Extensions.Logging; -using System; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Client.Handlers -{ - /// - /// JT808客户端连接通道处理程序 - /// - public class JT808TcpClientConnectionHandler : ChannelHandlerAdapter - { - private readonly ILogger logger; - private readonly JT808TcpClient jT808TcpClient; - - public JT808TcpClientConnectionHandler( - JT808TcpClient jT808TcpClient) - { - logger = jT808TcpClient.LoggerFactory.CreateLogger(); - this.jT808TcpClient = jT808TcpClient; - } - - /// - /// 通道激活 - /// - /// - public override void ChannelActive(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($"<<<{ channelId } Successful client connection to server."); - base.ChannelActive(context); - } - - /// - /// 设备主动断开 - /// - /// - public override void ChannelInactive(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($">>>{ channelId } The client disconnects from the server."); - - base.ChannelInactive(context); - } - - /// - /// 服务器主动断开 - /// - /// - /// - public override Task CloseAsync(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($"<<<{ channelId } The server disconnects from the client."); - - return base.CloseAsync(context); - } - - public override void ChannelReadComplete(IChannelHandlerContext context)=> context.Flush(); - - /// - /// 超时策略 - /// - /// - /// - public override void UserEventTriggered(IChannelHandlerContext context, object evt) - { - IdleStateEvent idleStateEvent = evt as IdleStateEvent; - if (idleStateEvent != null) - { - if(idleStateEvent.State== IdleState.WriterIdle) - { - string channelId = context.Channel.Id.AsShortText(); - logger.LogInformation($"{idleStateEvent.State.ToString()}>>>{channelId}"); - if(jT808TcpClient.DeviceConfig.Version== JT808Version.JTT2019) - { - jT808TcpClient.Send(JT808MsgId.终端心跳.Create2019(jT808TcpClient.DeviceConfig.TerminalPhoneNo,new JT808_0x0002())); - } - else - { - jT808TcpClient.Send(JT808MsgId.终端心跳.Create(jT808TcpClient.DeviceConfig.TerminalPhoneNo, new JT808_0x0002())); - } - } - } - base.UserEventTriggered(context, evt); - } - - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) - { - string channelId = context.Channel.Id.AsShortText(); - logger.LogError(exception,$"{channelId} {exception.Message}" ); - context.CloseAsync(); - } - } -} - diff --git a/src/JT808.DotNetty.Client/Handlers/JT808TcpClientHandler.cs b/src/JT808.DotNetty.Client/Handlers/JT808TcpClientHandler.cs deleted file mode 100644 index 376a486..0000000 --- a/src/JT808.DotNetty.Client/Handlers/JT808TcpClientHandler.cs +++ /dev/null @@ -1,30 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Transport.Channels; -using System; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.DependencyInjection; -using JT808.DotNetty.Client.Services; - -namespace JT808.DotNetty.Client.Handlers -{ - /// - /// JT808客户端处理程序 - /// - internal class JT808TcpClientHandler : SimpleChannelInboundHandler - { - private readonly ILogger logger; - private readonly JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService; - public JT808TcpClientHandler(JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService,JT808TcpClient jT808TcpClient) - { - logger = jT808TcpClient.LoggerFactory.CreateLogger(); - this.jT808ReceiveAtomicCounterService= jT808ReceiveAtomicCounterService; - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, byte[] msg) - { - if(logger.IsEnabled(LogLevel.Trace)) - logger.LogTrace("accept msg<<<" + ByteBufferUtil.HexDump(msg)); - jT808ReceiveAtomicCounterService.MsgSuccessIncrement(); - } - } -} diff --git a/src/JT808.DotNetty.Client/JT808.DotNetty.Client.csproj b/src/JT808.DotNetty.Client/JT808.DotNetty.Client.csproj deleted file mode 100644 index 23b3342..0000000 --- a/src/JT808.DotNetty.Client/JT808.DotNetty.Client.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Client - JT808.DotNetty.Client - 基于DotNetty实现的JT808DotNetty的客户端工具 - 基于DotNetty实现的JT808DotNetty的客户端工具 - - - - - - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.Client/JT808ClientDotnettyExtensions.cs b/src/JT808.DotNetty.Client/JT808ClientDotnettyExtensions.cs deleted file mode 100644 index f935bcc..0000000 --- a/src/JT808.DotNetty.Client/JT808ClientDotnettyExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.Client.Services; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; -using JT808.Protocol; -using Microsoft.Extensions.Configuration; - -namespace JT808.DotNetty.Client -{ - public static class JT808ClientDotnettyExtensions - { - public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder) - { - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.Configure((options)=> { }); - jT808Builder.Services.AddHostedService(); - return jT808Builder; - } - public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder, IConfiguration Configuration) - { - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.Configure(Configuration.GetSection("JT808ReportOptions")); - jT808Builder.Services.AddHostedService(); - return jT808Builder; - } - - public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder, Action reportAction) - { - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.AddSingleton(); - jT808Builder.Services.Configure(reportAction); - jT808Builder.Services.AddHostedService(); - return jT808Builder; - } - } -} diff --git a/src/JT808.DotNetty.Client/JT808DeviceConfig.cs b/src/JT808.DotNetty.Client/JT808DeviceConfig.cs deleted file mode 100644 index 63cd606..0000000 --- a/src/JT808.DotNetty.Client/JT808DeviceConfig.cs +++ /dev/null @@ -1,30 +0,0 @@ -using JT808.Protocol; -using JT808.Protocol.Enums; -using JT808.Protocol.Interfaces; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Client -{ - public class JT808DeviceConfig - { - public JT808DeviceConfig(string terminalPhoneNo, string tcpHost,int tcpPort, JT808Version version= JT808Version.JTT2013) - { - TerminalPhoneNo = terminalPhoneNo; - TcpHost = tcpHost; - TcpPort = tcpPort; - Version = version; - } - public JT808Version Version { get; private set; } - 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.DotNetty.Client/JT808ReportOptions.cs b/src/JT808.DotNetty.Client/JT808ReportOptions.cs deleted file mode 100644 index 6305ffd..0000000 --- a/src/JT808.DotNetty.Client/JT808ReportOptions.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace JT808.DotNetty.Client -{ - public class JT808ReportOptions:IOptions - { - public string FileName { get; set; } = $"JT808Report.{DateTime.Now.ToString("yyyyMMddHHssmm")}.txt"; - public string FilePath { get; set; } = AppDomain.CurrentDomain.BaseDirectory; - public string FileFullPath { get { return Path.Combine(FilePath, FileName); } } - public int Interval { get; set; } = 3; - public JT808ReportOptions Value => this; - - public void FileExistsAndCreate() - { - if(!File.Exists(FileFullPath)) - { - File.Create(FileFullPath).Close(); - } - } - } -} diff --git a/src/JT808.DotNetty.Client/JT808TcpClient.cs b/src/JT808.DotNetty.Client/JT808TcpClient.cs deleted file mode 100644 index b51a4b4..0000000 --- a/src/JT808.DotNetty.Client/JT808TcpClient.cs +++ /dev/null @@ -1,112 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using DotNetty.Handlers.Timeout; -using DotNetty.Transport.Bootstrapping; -using DotNetty.Transport.Channels; -using DotNetty.Transport.Channels.Sockets; -using JT808.DotNetty.Client.Handlers; -using Microsoft.Extensions.Logging; -using System; -using System.Runtime.InteropServices; -using Microsoft.Extensions.DependencyInjection; -using System.Net; -using JT808.DotNetty.Client.Metadata; -using JT808.DotNetty.Client.Codecs; -using JT808.DotNetty.Client.Services; -using JT808.Protocol; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Client -{ - public sealed class JT808TcpClient : IDisposable - { - private MultithreadEventLoopGroup group; - - private IChannel clientChannel; - - private bool disposed = false; - - public JT808DeviceConfig DeviceConfig { get; private set; } - - public ILoggerFactory LoggerFactory { get; private set; } - - public JT808TcpClient(JT808DeviceConfig deviceConfig, IServiceProvider serviceProvider) - { - DeviceConfig = deviceConfig; - LoggerFactory = serviceProvider.GetRequiredService(); - JT808SendAtomicCounterService jT808SendAtomicCounterService = serviceProvider.GetRequiredService(); - JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService = serviceProvider.GetRequiredService(); - IJT808Config jT808Config = serviceProvider.GetRequiredService(); - group = new MultithreadEventLoopGroup(1); - Bootstrap bootstrap = new Bootstrap(); - bootstrap.Group(group); - bootstrap.Channel(); - bootstrap - .Option(ChannelOption.Allocator, new UnpooledByteBufferAllocator()) - .Handler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast("jt808TcpBuffer", new DelimiterBasedFrameDecoder(65535, - 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)); - })); - Task.Run(async () => - { - clientChannel = await bootstrap.ConnectAsync(IPAddress.Parse(DeviceConfig.TcpHost), DeviceConfig.TcpPort); - }); - } - - public 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) - { - 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.DotNetty.Client/JT808TcpClientExtensions.cs b/src/JT808.DotNetty.Client/JT808TcpClientExtensions.cs deleted file mode 100644 index 56de2fc..0000000 --- a/src/JT808.DotNetty.Client/JT808TcpClientExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using JT808.DotNetty.Client.Metadata; -using JT808.Protocol; -using JT808.Protocol.MessageBody; -using System; -using System.Collections.Generic; -using System.Text; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; - -namespace JT808.DotNetty.Client -{ - public static class JT808TcpClientExtensions - { - public static void Send(this JT808TcpClient client, JT808Package package, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096) - { - package.Header.TerminalPhoneNo = client.DeviceConfig.TerminalPhoneNo; - JT808ClientRequest request = new JT808ClientRequest(package, version, minBufferSize); - client.Send(request); - } - } - -} diff --git a/src/JT808.DotNetty.Client/JT808TcpClientFactory.cs b/src/JT808.DotNetty.Client/JT808TcpClientFactory.cs deleted file mode 100644 index 40d5f41..0000000 --- a/src/JT808.DotNetty.Client/JT808TcpClientFactory.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Client -{ - public interface IJT808TcpClientFactory : IDisposable - { - JT808TcpClient Create(JT808DeviceConfig 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(JT808DeviceConfig 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.DotNetty.Client/Metadata/JT808AtomicCounter.cs b/src/JT808.DotNetty.Client/Metadata/JT808AtomicCounter.cs deleted file mode 100644 index 1ffe64d..0000000 --- a/src/JT808.DotNetty.Client/Metadata/JT808AtomicCounter.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Client.Metadata -{ - /// - /// - /// - /// - internal class JT808AtomicCounter - { - long counter = 0; - - public JT808AtomicCounter(long initialCount = 0) - { - this.counter = initialCount; - } - - public void Reset() - { - Interlocked.Exchange(ref counter, 0); - } - - public long Increment() - { - return Interlocked.Increment(ref counter); - } - - public long Add(long len) - { - return Interlocked.Add(ref counter,len); - } - - public long Decrement() - { - return Interlocked.Decrement(ref counter); - } - - public long Count - { - get - { - return Interlocked.Read(ref counter); - } - } - } -} diff --git a/src/JT808.DotNetty.Client/Metadata/JT808ClientRequest.cs b/src/JT808.DotNetty.Client/Metadata/JT808ClientRequest.cs deleted file mode 100644 index c11e3fb..0000000 --- a/src/JT808.DotNetty.Client/Metadata/JT808ClientRequest.cs +++ /dev/null @@ -1,34 +0,0 @@ -using JT808.Protocol; -using JT808.Protocol.Enums; -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace JT808.DotNetty.Client.Metadata -{ - public class JT808ClientRequest - { - public JT808Package Package { get; } - - public byte[] HexData { get; } - - public JT808Version Version { get; } - - /// - /// 根据实际情况适当调整包的大小 - /// - public int MinBufferSize { get;} - - public JT808ClientRequest(JT808Package package, JT808Version version= JT808Version.JTT2013, int minBufferSize=1024) - { - Package = package; - MinBufferSize = minBufferSize; - Version = version; - } - - public JT808ClientRequest(byte[] hexData) - { - HexData = hexData; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Client/Metadata/JT808Report.cs b/src/JT808.DotNetty.Client/Metadata/JT808Report.cs deleted file mode 100644 index 78e695e..0000000 --- a/src/JT808.DotNetty.Client/Metadata/JT808Report.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Client.Metadata -{ - public class JT808Report - { - public long SendTotalCount { get; set; } - public long ReceiveTotalCount { get; set; } - public DateTime CurrentDate { get; set; } - public int Connections { get; set; } - public int OnlineConnections { get; set; } - public int OfflineConnections { get; set; } - } -} diff --git a/src/JT808.DotNetty.Client/Services/JT808ReceiveAtomicCounterService.cs b/src/JT808.DotNetty.Client/Services/JT808ReceiveAtomicCounterService.cs deleted file mode 100644 index d7cec1d..0000000 --- a/src/JT808.DotNetty.Client/Services/JT808ReceiveAtomicCounterService.cs +++ /dev/null @@ -1,35 +0,0 @@ -using JT808.DotNetty.Client.Metadata; - -namespace JT808.DotNetty.Client.Services -{ - /// - /// 接收计数包服务 - /// - public class JT808ReceiveAtomicCounterService - { - private readonly JT808AtomicCounter MsgSuccessCounter; - - public JT808ReceiveAtomicCounterService() - { - MsgSuccessCounter=new JT808AtomicCounter(); - } - - public void Reset() - { - MsgSuccessCounter.Reset(); - } - - public long MsgSuccessIncrement() - { - return MsgSuccessCounter.Increment(); - } - - public long MsgSuccessCount - { - get - { - return MsgSuccessCounter.Count; - } - } - } -} diff --git a/src/JT808.DotNetty.Client/Services/JT808ReportHostedService.cs b/src/JT808.DotNetty.Client/Services/JT808ReportHostedService.cs deleted file mode 100644 index 17e0220..0000000 --- a/src/JT808.DotNetty.Client/Services/JT808ReportHostedService.cs +++ /dev/null @@ -1,67 +0,0 @@ -using JT808.DotNetty.Client.Metadata; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Client.Services -{ - public class JT808ReportHostedService : BackgroundService - { - private readonly IOptionsMonitor jT808ReportOptions; - private readonly JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService; - private readonly JT808SendAtomicCounterService jT808SendAtomicCounterService; - private readonly IJT808TcpClientFactory jT808TcpClientFactory; - private readonly ILogger logger; - - public JT808ReportHostedService( - ILoggerFactory loggerFactory, - IOptionsMonitor jT808ReportOptionsAccessor, - JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService, - JT808SendAtomicCounterService jT808SendAtomicCounterService, - IJT808TcpClientFactory jT808TcpClientFactory) - { - logger = loggerFactory.CreateLogger("JT808ReportHostedService"); - jT808ReportOptions = jT808ReportOptionsAccessor; - jT808ReportOptions.CurrentValue.FileExistsAndCreate(); - this.jT808ReceiveAtomicCounterService = jT808ReceiveAtomicCounterService; - this.jT808SendAtomicCounterService = jT808SendAtomicCounterService; - this.jT808TcpClientFactory = jT808TcpClientFactory; - jT808ReportOptions.OnChange((options) => { options.FileExistsAndCreate(); }); - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (!stoppingToken.IsCancellationRequested) - { - var clients = jT808TcpClientFactory.GetAll(); - JT808Report report = new JT808Report() - { - SendTotalCount = jT808SendAtomicCounterService.MsgSuccessCount, - ReceiveTotalCount = jT808ReceiveAtomicCounterService.MsgSuccessCount, - CurrentDate = DateTime.Now, - Connections = clients.Count, - OnlineConnections = clients.Where(w => w.IsOpen).Count(), - OfflineConnections = clients.Where(w => !w.IsOpen).Count(), - }; - string json = JsonConvert.SerializeObject(report); - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug(json); - } - using (var sw=new StreamWriter(jT808ReportOptions.CurrentValue.FileFullPath,true)) - { - sw.WriteLine(json); - } - await Task.Delay(TimeSpan.FromSeconds(jT808ReportOptions.CurrentValue.Interval), stoppingToken); - } - } - } -} diff --git a/src/JT808.DotNetty.Client/Services/JT808SendAtomicCounterService.cs b/src/JT808.DotNetty.Client/Services/JT808SendAtomicCounterService.cs deleted file mode 100644 index 7642bc0..0000000 --- a/src/JT808.DotNetty.Client/Services/JT808SendAtomicCounterService.cs +++ /dev/null @@ -1,35 +0,0 @@ -using JT808.DotNetty.Client.Metadata; - -namespace JT808.DotNetty.Client.Services -{ - /// - /// 发送计数包服务 - /// - public class JT808SendAtomicCounterService - { - private readonly JT808AtomicCounter MsgSuccessCounter; - - public JT808SendAtomicCounterService() - { - MsgSuccessCounter=new JT808AtomicCounter(); - } - - public void Reset() - { - MsgSuccessCounter.Reset(); - } - - public long MsgSuccessIncrement() - { - return MsgSuccessCounter.Increment(); - } - - public long MsgSuccessCount - { - get - { - return MsgSuccessCounter.Count; - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs deleted file mode 100644 index e1d8612..0000000 --- a/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs +++ /dev/null @@ -1,32 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using System.Collections.Generic; -using JT808.Protocol; -using DotNetty.Transport.Channels; - -namespace JT808.DotNetty.Core.Codecs -{ - public class JT808TcpDecoder : ByteToMessageDecoder - { - protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) - { - //过滤掉不是808标准包 - //不包括头尾标识 - //(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1 - if (input.Capacity < 12) - { - byte[] buffer = new byte[input.Capacity]; - input.ReadBytes(buffer, 0, input.Capacity); - return; - } - else - { - byte[] buffer = new byte[input.Capacity + 2]; - input.ReadBytes(buffer, 1, input.Capacity); - buffer[0] = JT808Package.BeginFlag; - buffer[input.Capacity + 1] = JT808Package.EndFlag; - output.Add(buffer); - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Codecs/JT808TcpEncoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808TcpEncoder.cs deleted file mode 100644 index 634b3be..0000000 --- a/src/JT808.DotNetty.Core/Codecs/JT808TcpEncoder.cs +++ /dev/null @@ -1,52 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using JT808.Protocol; -using DotNetty.Transport.Channels; -using JT808.DotNetty.Core.Interfaces; -using Microsoft.Extensions.Logging; -using JT808.Protocol.Interfaces; - -namespace JT808.DotNetty.Core.Codecs -{ - /// - /// tcp统一下发出口 - /// - public class JT808TcpEncoder : MessageToByteEncoder - { - private readonly ILogger logger; - - private readonly JT808Serializer JT808Serializer; - - public JT808TcpEncoder( - IJT808Config jT808Config, - ILoggerFactory loggerFactory) - { - logger = loggerFactory.CreateLogger(); - this.JT808Serializer = jT808Config.GetSerializer(); - } - - protected override void Encode(IChannelHandlerContext context, IJT808Reply message, IByteBuffer output) - { - if (message.Package != null) - { - try - { - var sendData = JT808Serializer.Serialize(message.Package, minBufferSize: message.MinBufferSize); - output.WriteBytes(Unpooled.WrappedBuffer(sendData)); - } - catch (JT808.Protocol.Exceptions.JT808Exception ex) - { - logger.LogError(ex, context.Channel.Id.AsShortText()); - } - catch (System.Exception ex) - { - logger.LogError(ex, context.Channel.Id.AsShortText()); - } - } - else if (message.HexData != null) - { - output.WriteBytes(Unpooled.WrappedBuffer(message.HexData)); - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs deleted file mode 100644 index a0b9c8c..0000000 --- a/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs +++ /dev/null @@ -1,33 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using DotNetty.Transport.Channels; -using System.Collections.Generic; -using DotNetty.Transport.Channels.Sockets; -using JT808.DotNetty.Core.Metadata; - -namespace JT808.DotNetty.Core.Codecs -{ - public class JT808UdpDecoder : MessageToMessageDecoder - { - protected override void Decode(IChannelHandlerContext context, DatagramPacket message, List output) - { - if (!message.Content.IsReadable()) return; - IByteBuffer byteBuffer = message.Content; - //过滤掉非808标准包 - //不包括头尾标识 - //(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1 - if (byteBuffer.ReadableBytes < 12) - { - byte[] buffer = new byte[byteBuffer.ReadableBytes]; - byteBuffer.ReadBytes(buffer, 0, byteBuffer.ReadableBytes); - return; - } - else - { - byte[] buffer = new byte[byteBuffer.ReadableBytes]; - byteBuffer.ReadBytes(buffer); - output.Add(new JT808UdpPackage(buffer, message.Sender)); - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Configurations/JT808Configuration.cs b/src/JT808.DotNetty.Core/Configurations/JT808Configuration.cs deleted file mode 100644 index 636952f..0000000 --- a/src/JT808.DotNetty.Core/Configurations/JT808Configuration.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Configurations -{ - public class JT808Configuration - { - public int TcpPort { get; set; } = 808; - - public int UdpPort { get; set; } = 808; - - public int QuietPeriodSeconds { get; set; } = 1; - - public TimeSpan QuietPeriodTimeSpan => TimeSpan.FromSeconds(QuietPeriodSeconds); - - public int ShutdownTimeoutSeconds { get; set; } = 3; - - public TimeSpan ShutdownTimeoutTimeSpan => TimeSpan.FromSeconds(ShutdownTimeoutSeconds); - - public int SoBacklog { get; set; } = 8192; - - public int EventLoopCount { get; set; } = Environment.ProcessorCount; - - public int ReaderIdleTimeSeconds { get; set; } = 3600; - - public int WriterIdleTimeSeconds { get; set; } = 3600; - - public int AllIdleTimeSeconds { get; set; } = 3600; - - /// - /// WebApi服务 - /// 默认828端口 - /// - public int WebApiPort { get; set; } = 828; - - /// - /// WebApi 默认token 123456 - /// - public string WebApiToken { get; set; } = "123456"; - - /// - /// 转发远程地址 (可选项)知道转发的地址有利于提升性能 - /// 按照808的消息,有些请求必须要应答,但是转发可以不需要有应答可以节省部分资源包括: - // 1.消息的序列化 - // 2.消息的下发 - // 都有一定的性能损耗,那么不需要判断写超时 IdleState.WriterIdle - // 就跟神兽貔貅一样。。。 - /// - public List ForwardingRemoteIPAddress { get; set; } - } -} diff --git a/src/JT808.DotNetty.Core/Converters/ByteArrayHexTextJsonConverter.cs b/src/JT808.DotNetty.Core/Converters/ByteArrayHexTextJsonConverter.cs deleted file mode 100644 index 744c711..0000000 --- a/src/JT808.DotNetty.Core/Converters/ByteArrayHexTextJsonConverter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Core.JsonConvert -{ - /// - /// - /// ref:https://github.com/dotnet/corefx/blob/release/3.0/src/System.Text.Json/tests/Serialization/CustomConverterTests.Array.cs - /// - public class ByteArrayHexTextJsonConverter : JsonConverter - { - public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - //string hexJson = reader.get(); - var hexJson = reader.GetString(); - var list = new List(); - foreach (string str in hexJson.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries)) - { - list.Add(Convert.ToByte(str, 16)); - } - return list.ToArray(); - } - - public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options) - { - var hexString = string.Join(" ", (value).Select(p => p.ToString("X2"))); - writer.WriteStringValue(hexString); - } - } -} diff --git a/src/JT808.DotNetty.Core/Converters/JsonByteArrayHexConverter.cs b/src/JT808.DotNetty.Core/Converters/JsonByteArrayHexConverter.cs deleted file mode 100644 index 14875fb..0000000 --- a/src/JT808.DotNetty.Core/Converters/JsonByteArrayHexConverter.cs +++ /dev/null @@ -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.DotNetty.Core.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); - } - } -} diff --git a/src/JT808.DotNetty.Core/Converters/JsonIPAddressConverter.cs b/src/JT808.DotNetty.Core/Converters/JsonIPAddressConverter.cs deleted file mode 100644 index 955ed04..0000000 --- a/src/JT808.DotNetty.Core/Converters/JsonIPAddressConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; - -namespace JT808.DotNetty.Core.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); - } - } -} diff --git a/src/JT808.DotNetty.Core/Converters/JsonIPEndPointConverter.cs b/src/JT808.DotNetty.Core/Converters/JsonIPEndPointConverter.cs deleted file mode 100644 index 8bed28f..0000000 --- a/src/JT808.DotNetty.Core/Converters/JsonIPEndPointConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Net; - -namespace JT808.DotNetty.Core.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(serializer); - int port = (int)jo["Port"]; - return new IPEndPoint(address, port); - } - } -} diff --git a/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs b/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs deleted file mode 100644 index a03d240..0000000 --- a/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.Json; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.Core.Metadata; - -namespace JT808.DotNetty.Core.Handlers -{ - /// - /// 基于webapi http模式抽象消息处理业务 - /// 自定义消息处理业务 - /// 注意: - /// 1.ConfigureServices: - /// services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHttpHandlerBase),typeof(JT808MsgIdCustomHttpHandlerImpl),ServiceLifetime.Singleton)); - /// 2.解析具体的消息体,具体消息调用具体的JT808Serializer.Deserialize - /// - public abstract class JT808MsgIdHttpHandlerBase - { - /// - /// 初始化消息处理业务 - /// - protected JT808MsgIdHttpHandlerBase() - { - HandlerDict = new Dictionary>(); - } - - protected void CreateRoute(string url, Func func) - { - if (!HandlerDict.ContainsKey(url)) - { - HandlerDict.Add(url, func); - } - else - { - // 替换 - HandlerDict[url] = func; - } - } - - public Dictionary> HandlerDict { get; } - - protected JT808HttpResponse CreateJT808HttpResponse(dynamic dynamicObject) - { - byte[] data = JsonSerializer.SerializeToUtf8Bytes(dynamicObject); - return new JT808HttpResponse() - { - Data = data - }; - } - - public JT808HttpResponse DefaultHttpResponse() - { - byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808DefaultResultDto()); - return new JT808HttpResponse(json); - } - - public JT808HttpResponse EmptyHttpResponse() - { - byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() - { - Code = JT808ResultCode.Empty, - Message = "内容为空", - Data = "Content Empty" - }); - return new JT808HttpResponse(json); - } - - public JT808HttpResponse NotFoundHttpResponse() - { - byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() - { - Code = JT808ResultCode.NotFound, - Message = "没有该服务", - Data = "没有该服务" - }); - return new JT808HttpResponse(json); - } - - public JT808HttpResponse AuthFailHttpResponse() - { - byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() - { - Code = JT808ResultCode.AuthFail, - Message = "token认证失败", - Data = "token认证失败" - }); - return new JT808HttpResponse(json); - } - - public JT808HttpResponse ErrorHttpResponse(Exception ex) - { - byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto() - { - Code = JT808ResultCode.Error, - Message = ex.StackTrace, - Data = ex.Message - }); - return new JT808HttpResponse(json); - } - } -} diff --git a/src/JT808.DotNetty.Core/Impls/JT808DatagramPacketImpl.cs b/src/JT808.DotNetty.Core/Impls/JT808DatagramPacketImpl.cs deleted file mode 100644 index ef494bd..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808DatagramPacketImpl.cs +++ /dev/null @@ -1,21 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Transport.Channels.Sockets; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Services; -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; - -namespace JT808.DotNetty.Core.Impls -{ - class JT808DatagramPacketImpl : IJT808DatagramPacket - { - public DatagramPacket Create(byte[] message, EndPoint recipient) - { - return new DatagramPacket(Unpooled.WrappedBuffer(message), recipient); - } - } -} diff --git a/src/JT808.DotNetty.Core/Impls/JT808DefaultChannelId.cs b/src/JT808.DotNetty.Core/Impls/JT808DefaultChannelId.cs deleted file mode 100644 index 07670b9..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808DefaultChannelId.cs +++ /dev/null @@ -1,42 +0,0 @@ -using DotNetty.Transport.Channels; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Impls -{ - /// - /// 仅测试用 - /// - internal class JT808DefaultChannelId : IChannelId - { - public JT808DefaultChannelId() - { - Id= Guid.NewGuid().ToString("N"); - } - public JT808DefaultChannelId(string id) - { - Id = id; - } - private string Id { get;} - - public string AsLongText() - { - return Id; - } - - public string AsShortText() - { - return Id; - } - - public int CompareTo(IChannelId other) - { - if(other.AsShortText()== Id) - { - return 1; - } - return 0; - } - } -} diff --git a/src/JT808.DotNetty.Core/Impls/JT808MsgProducerDefaultImpl.cs b/src/JT808.DotNetty.Core/Impls/JT808MsgProducerDefaultImpl.cs deleted file mode 100644 index 38dfa7c..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808MsgProducerDefaultImpl.cs +++ /dev/null @@ -1,29 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Services; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Core.Impls -{ - internal class JT808MsgProducerDefaultImpl : IJT808MsgProducer - { - private readonly JT808MsgService JT808MsgService; - public string TopicName => JT808NettyConstants.MsgTopic; - public JT808MsgProducerDefaultImpl(JT808MsgService jT808MsgService) - { - JT808MsgService = jT808MsgService; - } - public void Dispose() - { - - } - - public Task ProduceAsync(string terminalNo, byte[] data) - { - JT808MsgService.MsgQueue.Add((terminalNo, data)); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.Core/Impls/JT808MsgReplyConsumerDefaultImpl.cs b/src/JT808.DotNetty.Core/Impls/JT808MsgReplyConsumerDefaultImpl.cs deleted file mode 100644 index 887a6d6..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808MsgReplyConsumerDefaultImpl.cs +++ /dev/null @@ -1,280 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Services; -using JT808.Protocol; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using JT808.Protocol.MessageBody; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Core.Impls -{ - internal class JT808MsgReplyConsumerDefaultImpl : IJT808MsgReplyConsumer - { - private readonly JT808MsgService JT808MsgService; - - private readonly JT808Serializer JT808Serializer; - - private Dictionary HandlerDict; - - private delegate byte[] MsgIdMethodDelegate(JT808HeaderPackage package); - public JT808MsgReplyConsumerDefaultImpl( - IJT808Config jT808Config, - JT808MsgService jT808MsgService) - { - JT808MsgService = jT808MsgService; - this.JT808Serializer = jT808Config.GetSerializer(); - HandlerDict = new Dictionary { - {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 CancellationTokenSource Cts =>new CancellationTokenSource(); - - public string TopicName => JT808NettyConstants.MsgReplyTopic; - - public void Dispose() - { - Cts.Dispose(); - } - - public void OnMessage(Action<(string TerminalNo, byte[] Data)> callback) - { - Task.Run(() => - { - foreach(var item in JT808MsgService.MsgQueue.GetConsumingEnumerable()) - { - try - { - var package = JT808Serializer.HeaderDeserialize(item.Data); - if (HandlerDict.TryGetValue(package.Header.MsgId, out var func)) - { - var buffer = func(package); - if (buffer != null) - { - callback((item.TerminalNo, buffer)); - } - } - } - catch - { - - } - } - }, Cts.Token); - } - - public void Subscribe() - { - - } - - public void Unsubscribe() - { - Cts.Cancel(); - } - - /// - /// 终端通用应答 - /// 平台无需回复 - /// 实现自己的业务 - /// - /// - /// - public byte[] Msg0x0001(JT808HeaderPackage request) - { - return null; - } - /// - /// 终端心跳 - /// - /// - /// - public byte[] Msg0x0002(JT808HeaderPackage request) - { - if(request.Version== JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端注销 - /// - /// - /// - public byte[] Msg0x0003(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端注册 - /// - /// - /// - public byte[] Msg0x0100(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.终端注册应答.Create_终端注册应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8100() - { - Code = "J" + request.Header.TerminalPhoneNo, - JT808TerminalRegisterResult = JT808TerminalRegisterResult.成功, - AckMsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.终端注册应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8100() - { - Code = "J" + request.Header.TerminalPhoneNo, - JT808TerminalRegisterResult = JT808TerminalRegisterResult.成功, - AckMsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端鉴权 - /// - /// - /// - public byte[] Msg0x0102(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 位置信息汇报 - /// - /// - /// - public byte[] Msg0x0200(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 定位数据批量上传 - /// - /// - /// - public byte[] Msg0x0704(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 数据上行透传 - /// - /// - /// - public byte[] Msg0x0900(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Impls/JT808NettyBuilderDefault.cs b/src/JT808.DotNetty.Core/Impls/JT808NettyBuilderDefault.cs deleted file mode 100644 index b268ef2..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808NettyBuilderDefault.cs +++ /dev/null @@ -1,26 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Interfaces; -using JT808.Protocol; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Impls -{ - public class JT808NettyBuilderDefault : IJT808NettyBuilder - { - public IJT808Builder JT808Builder { get; } - - public JT808NettyBuilderDefault(IJT808Builder builder) - { - JT808Builder = builder; - } - - public IJT808Builder Builder() - { - return JT808Builder; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Impls/JT808SessionProducerDefaultImpl.cs b/src/JT808.DotNetty.Core/Impls/JT808SessionProducerDefaultImpl.cs deleted file mode 100644 index b5d6d11..0000000 --- a/src/JT808.DotNetty.Core/Impls/JT808SessionProducerDefaultImpl.cs +++ /dev/null @@ -1,31 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Core -{ - internal class JT808SessionProducerDefaultImpl : IJT808SessionProducer - { - private readonly ILogger logger; - public JT808SessionProducerDefaultImpl(ILoggerFactory loggerFactory) - { - logger = loggerFactory.CreateLogger(); - } - - public string TopicName => JT808NettyConstants.SessionTopic; - - public void Dispose() - { - - } - - public Task ProduceAsync(string terminalNo, string notice) - { - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug($"{terminalNo}-{notice}"); - } - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808DatagramPacket.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808DatagramPacket.cs deleted file mode 100644 index 196117f..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808DatagramPacket.cs +++ /dev/null @@ -1,13 +0,0 @@ -using DotNetty.Transport.Channels.Sockets; -using System.Net; - -namespace JT808.DotNetty.Core.Interfaces -{ - /// - /// 基于udp的创建发送包 - /// - public interface IJT808DatagramPacket - { - DatagramPacket Create(byte[] message, EndPoint recipient); - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808Reply.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808Reply.cs deleted file mode 100644 index 99a2a74..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808Reply.cs +++ /dev/null @@ -1,17 +0,0 @@ -using JT808.Protocol; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Interfaces -{ - public interface IJT808Reply - { - JT808Package Package { get; set; } - byte[] HexData { get; set; } - /// - /// 根据实际情况适当调整包的大小 - /// - int MinBufferSize { get; set; } - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808Session.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808Session.cs deleted file mode 100644 index 22ad240..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808Session.cs +++ /dev/null @@ -1,20 +0,0 @@ -using DotNetty.Transport.Channels; -using JT808.DotNetty.Abstractions.Enums; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Interfaces -{ - public interface IJT808Session - { - /// - /// 终端手机号 - /// - string TerminalPhoneNo { get; set; } - IChannel Channel { get; set; } - DateTime LastActiveTime { get; set; } - DateTime StartTime { get; set; } - JT808TransportProtocolType TransportProtocolType { get; set; } - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808SessionService.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808SessionService.cs deleted file mode 100644 index 79cd501..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808SessionService.cs +++ /dev/null @@ -1,36 +0,0 @@ -using JT808.DotNetty.Abstractions.Dtos; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Interfaces -{ - /// - /// JT808会话服务 - /// - public interface IJT808SessionService - { - /// - /// 获取udp会话集合 - /// - /// - JT808ResultDto> GetUdpAll(); - /// - /// 获取tcp会话集合 - /// - /// - JT808ResultDto> GetTcpAll(); - /// - /// 通过设备终端号移除对应会话 - /// - /// - /// - JT808ResultDto RemoveByTerminalPhoneNo(string terminalPhoneNo); - /// - /// 通过设备终端号获取对应会话 - /// - /// - /// - JT808ResultDto QueryTcpSessionByTerminalPhoneNo(string terminalPhoneNo); - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808UnificationSendService.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808UnificationSendService.cs deleted file mode 100644 index a4935d5..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808UnificationSendService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using JT808.DotNetty.Abstractions.Dtos; - -namespace JT808.DotNetty.Core.Interfaces -{ - /// - /// JT808统一下发命令服务 - /// - public interface IJT808UnificationSendService - { - JT808ResultDto Send(string terminalPhoneNo, byte[] data); - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiAuthorization.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiAuthorization.cs deleted file mode 100644 index 24f33e0..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiAuthorization.cs +++ /dev/null @@ -1,13 +0,0 @@ -using DotNetty.Codecs.Http; -using System; -using System.Collections.Generic; -using System.Security.Principal; -using System.Text; - -namespace JT808.DotNetty.Core.Interfaces -{ - public interface IJT808WebApiAuthorization - { - bool Authorization(IFullHttpRequest request, out IPrincipal principal); - } -} diff --git a/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiNettyBuilder.cs b/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiNettyBuilder.cs deleted file mode 100644 index 5c9c343..0000000 --- a/src/JT808.DotNetty.Core/Interfaces/IJT808WebApiNettyBuilder.cs +++ /dev/null @@ -1,16 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Handlers; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Interfaces -{ - public interface IJT808WebApiNettyBuilder - { - IJT808NettyBuilder Instance { get; } - IJT808NettyBuilder Builder(); - IJT808WebApiNettyBuilder ReplaceMsgIdHandler() where T : JT808MsgIdHttpHandlerBase; - IJT808WebApiNettyBuilder ReplaceAuthorization() where T : IJT808WebApiAuthorization; - } -} diff --git a/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj b/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj deleted file mode 100644 index 450e81e..0000000 --- a/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Core - JT808.DotNetty.Core - 基于DotNetty实现的JT808DotNetty的核心库 - 基于DotNetty实现的JT808DotNetty的核心库 - - - - - - - - - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs b/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs deleted file mode 100644 index 98d57b7..0000000 --- a/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.Core.Impls; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Core.Session; -using JT808.DotNetty.Internal; -using JT808.Protocol; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; -using System; -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("JT808.DotNetty.Core.Test")] -[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] -[assembly: InternalsVisibleTo("JT808.DotNetty.Udp.Test")] -[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp")] -[assembly: InternalsVisibleTo("JT808.DotNetty.Udp")] -[assembly: InternalsVisibleTo("JT808.DotNetty.WebApi")] -namespace JT808.DotNetty.Core -{ - public static class JT808CoreDotnettyExtensions - { - public static IJT808NettyBuilder AddJT808NettyCore(this IJT808Builder jt808Builder, IConfiguration configuration) - { - IJT808NettyBuilder nettyBuilder = new JT808NettyBuilderDefault(jt808Builder); - nettyBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808Configuration")); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.AddHostedService(); - return nettyBuilder; - } - - public static IJT808NettyBuilder AddJT808NettyCore(this IJT808Builder jt808Builder, Action jt808Options) - { - IJT808NettyBuilder nettyBuilder = new JT808NettyBuilderDefault(jt808Builder); - nettyBuilder.JT808Builder.Services.Configure(jt808Options); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.TryAddSingleton(); - nettyBuilder.JT808Builder.Services.AddHostedService(); - return nettyBuilder; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Metadata/JT808AtomicCounter.cs b/src/JT808.DotNetty.Core/Metadata/JT808AtomicCounter.cs deleted file mode 100644 index 25b8cca..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808AtomicCounter.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace JT808.DotNetty.Core.Metadata -{ - /// - /// - /// - /// - internal class JT808AtomicCounter - { - long counter = 0; - - public JT808AtomicCounter(long initialCount = 0) - { - this.counter = initialCount; - } - - public void Reset() - { - Interlocked.Exchange(ref counter, 0); - } - - public long Increment() - { - return Interlocked.Increment(ref counter); - } - - public long Add(long len) - { - return Interlocked.Add(ref counter,len); - } - - public long Decrement() - { - return Interlocked.Decrement(ref counter); - } - - public long Count - { - get - { - return Interlocked.Read(ref counter); - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Metadata/JT808HttpRequest.cs b/src/JT808.DotNetty.Core/Metadata/JT808HttpRequest.cs deleted file mode 100644 index 274226b..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808HttpRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using JT808.Protocol; -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace JT808.DotNetty.Core.Metadata -{ - public class JT808HttpRequest - { - public string Json { get; set; } - - public JT808HttpRequest() - { - - } - - public JT808HttpRequest(string json) - { - Json = json; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Metadata/JT808HttpResponse.cs b/src/JT808.DotNetty.Core/Metadata/JT808HttpResponse.cs deleted file mode 100644 index 3bd3379..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808HttpResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -using JT808.Protocol; -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace JT808.DotNetty.Core.Metadata -{ - public class JT808HttpResponse - { - public byte[] Data { get; set; } - - public JT808HttpResponse() - { - - } - - public JT808HttpResponse(byte[] data) - { - this.Data = data; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Metadata/JT808TcpSession.cs b/src/JT808.DotNetty.Core/Metadata/JT808TcpSession.cs deleted file mode 100644 index 27c4338..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808TcpSession.cs +++ /dev/null @@ -1,32 +0,0 @@ -using DotNetty.Transport.Channels; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Interfaces; -using System; - -namespace JT808.DotNetty.Core.Metadata -{ - public class JT808TcpSession: IJT808Session - { - public JT808TcpSession(IChannel channel, string terminalPhoneNo) - { - Channel = channel; - TerminalPhoneNo = terminalPhoneNo; - StartTime = DateTime.Now; - LastActiveTime = DateTime.Now; - } - - public JT808TcpSession() { } - - /// - /// 终端手机号 - /// - public string TerminalPhoneNo { get; set; } - - public IChannel Channel { get; set; } - - public DateTime LastActiveTime { get; set; } - - public DateTime StartTime { get; set; } - public JT808TransportProtocolType TransportProtocolType { get; set; } = JT808TransportProtocolType.tcp; - } -} diff --git a/src/JT808.DotNetty.Core/Metadata/JT808UdpPackage.cs b/src/JT808.DotNetty.Core/Metadata/JT808UdpPackage.cs deleted file mode 100644 index 939f93f..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808UdpPackage.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; - -namespace JT808.DotNetty.Core.Metadata -{ - public class JT808UdpPackage - { - public JT808UdpPackage(byte[] buffer, EndPoint sender) - { - Buffer = buffer; - Sender = sender; - } - - public byte[] Buffer { get; } - - public EndPoint Sender { get; } - } -} diff --git a/src/JT808.DotNetty.Core/Metadata/JT808UdpSession.cs b/src/JT808.DotNetty.Core/Metadata/JT808UdpSession.cs deleted file mode 100644 index 909ac4c..0000000 --- a/src/JT808.DotNetty.Core/Metadata/JT808UdpSession.cs +++ /dev/null @@ -1,38 +0,0 @@ -using DotNetty.Transport.Channels; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Interfaces; -using System; -using System.Net; - -namespace JT808.DotNetty.Core.Metadata -{ - public class JT808UdpSession: IJT808Session - { - public JT808UdpSession(IChannel channel, - EndPoint sender, - string terminalPhoneNo) - { - Channel = channel; - TerminalPhoneNo = terminalPhoneNo; - StartTime = DateTime.Now; - LastActiveTime = DateTime.Now; - Sender = sender; - } - - public EndPoint Sender { get; set; } - - public JT808UdpSession() { } - - /// - /// 终端手机号 - /// - public string TerminalPhoneNo { get; set; } - - public IChannel Channel { get; set; } - - public DateTime LastActiveTime { get; set; } - - public DateTime StartTime { get; set; } - public JT808TransportProtocolType TransportProtocolType { get; set; } = JT808TransportProtocolType.udp; - } -} diff --git a/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.Core/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Core/Services/JT808AtomicCounterService.cs b/src/JT808.DotNetty.Core/Services/JT808AtomicCounterService.cs deleted file mode 100644 index 85cf0d5..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808AtomicCounterService.cs +++ /dev/null @@ -1,52 +0,0 @@ -using JT808.DotNetty.Core.Metadata; - -namespace JT808.DotNetty.Core.Services -{ - /// - /// 计数包服务 - /// - public class JT808AtomicCounterService - { - private readonly JT808AtomicCounter MsgSuccessCounter; - - private readonly JT808AtomicCounter MsgFailCounter; - - public JT808AtomicCounterService() - { - MsgSuccessCounter=new JT808AtomicCounter(); - MsgFailCounter = new JT808AtomicCounter(); - } - - public void Reset() - { - MsgSuccessCounter.Reset(); - MsgFailCounter.Reset(); - } - - public long MsgSuccessIncrement() - { - return MsgSuccessCounter.Increment(); - } - - public long MsgSuccessCount - { - get - { - return MsgSuccessCounter.Count; - } - } - - public long MsgFailIncrement() - { - return MsgFailCounter.Increment(); - } - - public long MsgFailCount - { - get - { - return MsgFailCounter.Count; - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Services/JT808AtomicCounterServiceFactory.cs b/src/JT808.DotNetty.Core/Services/JT808AtomicCounterServiceFactory.cs deleted file mode 100644 index 916befb..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808AtomicCounterServiceFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -using JT808.DotNetty.Abstractions.Enums; -using System; -using System.Collections.Concurrent; - -namespace JT808.DotNetty.Core.Services -{ - public class JT808AtomicCounterServiceFactory - { - private readonly ConcurrentDictionary cache; - - public JT808AtomicCounterServiceFactory() - { - cache = new ConcurrentDictionary(); - } - - public JT808AtomicCounterService Create(JT808TransportProtocolType type) - { - if(cache.TryGetValue(type,out var service)) - { - return service; - } - else - { - var serviceNew = new JT808AtomicCounterService(); - cache.TryAdd(type, serviceNew); - return serviceNew; - } - } - } -} diff --git a/src/JT808.DotNetty.Core/Services/JT808MsgReplyHostedService.cs b/src/JT808.DotNetty.Core/Services/JT808MsgReplyHostedService.cs deleted file mode 100644 index 633e574..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808MsgReplyHostedService.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Session; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Core.Services -{ - internal class JT808MsgReplyHostedService : IHostedService - { - private readonly JT808SessionManager JT808SessionManager; - - private readonly IJT808MsgReplyConsumer JT808MsgReplyConsumer; - - public JT808MsgReplyHostedService( - IJT808MsgReplyConsumer jT808MsgReplyConsumer, - JT808SessionManager jT808SessionManager) - { - JT808MsgReplyConsumer = jT808MsgReplyConsumer; - JT808SessionManager = jT808SessionManager; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - JT808MsgReplyConsumer.OnMessage(item => - { - JT808SessionManager.Send(item.TerminalNo, item.Data); - }); - JT808MsgReplyConsumer.Subscribe(); - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - JT808MsgReplyConsumer.Unsubscribe(); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.Core/Services/JT808MsgService.cs b/src/JT808.DotNetty.Core/Services/JT808MsgService.cs deleted file mode 100644 index 2c271aa..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808MsgService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Services -{ - internal class JT808MsgService - { - public System.Collections.Concurrent.BlockingCollection<(string TerminalNo, byte[] Data)> MsgQueue { get; set; } = new System.Collections.Concurrent.BlockingCollection<(string TerminalNo, byte[] Data)>(); - } -} diff --git a/src/JT808.DotNetty.Core/Services/JT808SessionService.cs b/src/JT808.DotNetty.Core/Services/JT808SessionService.cs deleted file mode 100644 index f8cb7ba..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808SessionService.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Text.Json; -using System.Collections.Generic; -using System.Linq; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Session; - -namespace JT808.DotNetty.Core.Services -{ - internal class JT808SessionService : IJT808SessionService - { - private readonly JT808SessionManager jT808SessionManager; - - public JT808SessionService( - JT808SessionManager jT808SessionManager) - { - this.jT808SessionManager = jT808SessionManager; - } - - public JT808ResultDto> GetTcpAll() - { - JT808ResultDto> resultDto = new JT808ResultDto>(); - try - { - resultDto.Data = jT808SessionManager.GetAll().Select(s => new JT808TcpSessionInfoDto - { - LastActiveTime = s.LastActiveTime, - StartTime = s.StartTime, - TerminalPhoneNo = s.TerminalPhoneNo, - RemoteAddressIP = s.Channel.RemoteAddress.ToString(), - }).ToList(); - resultDto.Code = JT808ResultCode.Ok; - } - catch (Exception ex) - { - resultDto.Data = null; - resultDto.Code = JT808ResultCode.Error; - resultDto.Message = ex.Message; - } - return resultDto; - } - - public JT808ResultDto> GetUdpAll() - { - JT808ResultDto> resultDto = new JT808ResultDto>(); - try - { - resultDto.Data = jT808SessionManager.GetUdpAll().Select(s => new JT808UdpSessionInfoDto - { - LastActiveTime = s.LastActiveTime, - StartTime = s.StartTime, - TerminalPhoneNo = s.TerminalPhoneNo, - RemoteAddressIP = s.Sender.ToString() - }).ToList(); - resultDto.Code = JT808ResultCode.Ok; - } - catch (Exception ex) - { - resultDto.Data = null; - resultDto.Code = JT808ResultCode.Error; - resultDto.Message = ex.Message; - } - return resultDto; - } - - public JT808ResultDto RemoveByTerminalPhoneNo(string terminalPhoneNo) - { - JT808ResultDto resultDto = new JT808ResultDto(); - try - { - var session = jT808SessionManager.RemoveSession(terminalPhoneNo); - if (session != null) - { - if(session.Channel.Open) - { - session.Channel.CloseAsync(); - } - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = true; - } - else - { - resultDto.Code = JT808ResultCode.Empty; - resultDto.Data = false; - resultDto.Message = "Session Empty"; - } - } - catch (AggregateException ex) - { - resultDto.Data = false; - resultDto.Code = 500; - resultDto.Message = ex.Message; - } - catch (Exception ex) - { - resultDto.Data = false; - resultDto.Code = JT808ResultCode.Error; - resultDto.Message = ex.Message; - } - return resultDto; - } - - public JT808ResultDto QueryTcpSessionByTerminalPhoneNo(string terminalPhoneNo) - { - JT808ResultDto resultDto = new JT808ResultDto(); - try - { - resultDto.Data = jT808SessionManager.GetAll().Where(w=>w.TerminalPhoneNo== terminalPhoneNo).Select(s => new JT808TcpSessionInfoDto - { - LastActiveTime = s.LastActiveTime, - StartTime = s.StartTime, - TerminalPhoneNo = s.TerminalPhoneNo, - RemoteAddressIP = s.Channel.RemoteAddress.ToString(), - }).FirstOrDefault(); - resultDto.Code = JT808ResultCode.Ok; - } - catch (Exception ex) - { - resultDto.Data = null; - resultDto.Code = JT808ResultCode.Error; - resultDto.Message = ex.Message; - } - return resultDto; - } - } -} diff --git a/src/JT808.DotNetty.Core/Services/JT808UnificationSendService.cs b/src/JT808.DotNetty.Core/Services/JT808UnificationSendService.cs deleted file mode 100644 index bb051da..0000000 --- a/src/JT808.DotNetty.Core/Services/JT808UnificationSendService.cs +++ /dev/null @@ -1,47 +0,0 @@ -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Session; -using System; -using System.Text.Json; - -namespace JT808.DotNetty.Internal -{ - internal class JT808UnificationSendService : IJT808UnificationSendService - { - private readonly JT808SessionManager jT808SessionManager; - - public JT808UnificationSendService( - JT808SessionManager jT808SessionManager) - { - this.jT808SessionManager = jT808SessionManager; - } - - public JT808ResultDto Send(string terminalPhoneNo, byte[] data) - { - JT808ResultDto resultDto = new JT808ResultDto(); - try - { - if(jT808SessionManager.TrySend(terminalPhoneNo, data, out var message)) - { - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = true; - resultDto.Message = message; - } - else - { - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = false; - resultDto.Message = message; - } - } - catch (Exception ex) - { - resultDto.Data = false; - resultDto.Code = JT808ResultCode.Error; - resultDto.Message = ex.Message; - } - return resultDto; - } - } -} diff --git a/src/JT808.DotNetty.Core/Session/JT808SessionManager.cs b/src/JT808.DotNetty.Core/Session/JT808SessionManager.cs deleted file mode 100644 index 8127dd1..0000000 --- a/src/JT808.DotNetty.Core/Session/JT808SessionManager.cs +++ /dev/null @@ -1,304 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Transport.Channels; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Metadata; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; - -namespace JT808.DotNetty.Core.Session -{ - public class JT808SessionManager - { - private readonly ILogger logger; - - private readonly IJT808DatagramPacket jT808DatagramPacket; - public IJT808SessionProducer JT808SessionProducer { get; } - - public ConcurrentDictionary Sessions { get; } - - public JT808SessionManager( - IJT808SessionProducer jT808SessionProducer, - ILoggerFactory loggerFactory - ) - { - Sessions = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - JT808SessionProducer = jT808SessionProducer; - logger = loggerFactory.CreateLogger(); - } - - public JT808SessionManager( - IJT808SessionProducer jT808SessionProducer, - ILoggerFactory loggerFactory, - IJT808DatagramPacket jT808DatagramPacket) - { - Sessions = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - JT808SessionProducer = jT808SessionProducer; - logger = loggerFactory.CreateLogger(); - this.jT808DatagramPacket = jT808DatagramPacket; - } - - public int SessionCount - { - get - { - return Sessions.Count; - } - } - public IJT808Session GetSessionByTerminalPhoneNo(string terminalPhoneNo) - { - if (string.IsNullOrEmpty(terminalPhoneNo)) - return default; - if (Sessions.TryGetValue(terminalPhoneNo, out IJT808Session targetSession)) - { - return targetSession; - } - else - { - return default; - } - } - public JT808TcpSession GetTcpSessionByTerminalPhoneNo(string terminalPhoneNo) - { - return (JT808TcpSession)GetSessionByTerminalPhoneNo(terminalPhoneNo); - } - public JT808UdpSession GetUdpSessionByTerminalPhoneNo(string terminalPhoneNo) - { - return (JT808UdpSession)GetSessionByTerminalPhoneNo(terminalPhoneNo); - } - public void Heartbeat(string terminalPhoneNo) - { - if (string.IsNullOrEmpty(terminalPhoneNo)) return; - if (Sessions.TryGetValue(terminalPhoneNo, out IJT808Session oldjT808Session)) - { - oldjT808Session.LastActiveTime = DateTime.Now; - Sessions.TryUpdate(terminalPhoneNo, oldjT808Session, oldjT808Session); - } - } - public bool TrySend(string terminalPhoneNo, byte[] data, out string message) - { - bool isSuccessed; - var session = GetSessionByTerminalPhoneNo(terminalPhoneNo); - if (session != null) - { - //判断转发数据是下发不了消息的 - if (Sessions.Select(s => s.Value).Count(c => c.Channel.Id == session.Channel.Id) > 1) - { - isSuccessed = false; - message = "not support transmit data send."; - } - else - { - if(session.TransportProtocolType== JT808TransportProtocolType.tcp) - { - session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); - isSuccessed = true; - message = "ok"; - } - else if (session.TransportProtocolType == JT808TransportProtocolType.udp) - { - isSuccessed = true; - message = "ok"; - session.Channel.WriteAndFlushAsync(jT808DatagramPacket.Create(data, ((JT808UdpSession)session).Sender)); - } - else - { - isSuccessed = false; - message = "unknow type"; - } - } - } - else - { - isSuccessed = false; - message = "offline"; - } - return isSuccessed; - } - internal void Send(string terminalPhoneNo, byte[] data) - { - var session = GetSessionByTerminalPhoneNo(terminalPhoneNo); - if (session != null) - { - if (session.TransportProtocolType == JT808TransportProtocolType.tcp) - { - session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); - } - else if (session.TransportProtocolType == JT808TransportProtocolType.udp) - { - session.Channel.WriteAndFlushAsync(jT808DatagramPacket.Create(data, ((JT808UdpSession)session).Sender)); - } - } - } - public bool TrySend(string terminalPhoneNo, IJT808Reply reply, out string message) - { - bool isSuccessed; - var session = GetSessionByTerminalPhoneNo(terminalPhoneNo); - if (session != null) - { - //判断转发数据是下发不了消息的 - if (Sessions.Select(s => s.Value).Count(c => c.Channel.Id == session.Channel.Id) > 1) - { - isSuccessed = false; - message = "not support transmit data send."; - } - else - { - if (session.TransportProtocolType == JT808TransportProtocolType.tcp) - { - isSuccessed = true; - message = "ok"; - session.Channel.WriteAndFlushAsync(reply); - } - else if (session.TransportProtocolType == JT808TransportProtocolType.udp) - { - isSuccessed = true; - message = "ok"; - session.Channel.WriteAndFlushAsync(jT808DatagramPacket.Create(reply.HexData, ((JT808UdpSession)session).Sender)); - } - else - { - isSuccessed = false; - message = "unknow type"; - } - } - } - else - { - isSuccessed = false; - message = "offline"; - } - return isSuccessed; - } - public void TryAdd(string terminalPhoneNo, IChannel channel) - { - // 解决了设备号跟通道绑定到一起,不需要用到通道本身的SessionId - // 不管设备下发更改了设备终端号,只要是没有在内存中就当是新的 - // 存在的问题: - // 1.原先老的如何销毁 - // 2.这时候用的通道是相同的,设备终端是不同的 - // 当设备主动或者服务器断开以后,可以释放,这点内存忽略不计,况且更改设备号不是很频繁。 - - //修复第一次通过转发过来的数据,再次通过直连后通道没有改变导致下发不成功,所以每次进行通道的更新操作。 - if (Sessions.TryGetValue(terminalPhoneNo, out IJT808Session oldJT808Session)) - { - oldJT808Session.LastActiveTime = DateTime.Now; - oldJT808Session.Channel = channel; - Sessions.TryUpdate(terminalPhoneNo, oldJT808Session, oldJT808Session); - } - else - { - JT808TcpSession jT808TcpSession = new JT808TcpSession(channel, terminalPhoneNo); - if (Sessions.TryAdd(terminalPhoneNo, jT808TcpSession)) - { - //使用场景: - //部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, - //这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 - //有设备关联上来可以进行通知 例如:使用Redis发布订阅 - JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,jT808TcpSession.TerminalPhoneNo); - } - } - } - public void TryAdd(IChannel channel, EndPoint sender, string terminalPhoneNo) - { - //1.先判断是否在缓存里面 - if (Sessions.TryGetValue(terminalPhoneNo, out IJT808Session jT808UdpSession)) - { - if(jT808UdpSession is JT808UdpSession convertSession) - { - convertSession.LastActiveTime = DateTime.Now; - convertSession.Sender = sender; - convertSession.Channel = channel; - Sessions.TryUpdate(terminalPhoneNo, convertSession, convertSession); - } - } - else - { - //添加缓存 - //使用场景: - //部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, - //这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 - //有设备关联上来可以进行通知 例如:使用Redis发布订阅 - Sessions.TryAdd(terminalPhoneNo, new JT808UdpSession(channel, sender, terminalPhoneNo)); - } - //移动是个大的内网,不跟随下发,根本就发不出来 - //移动很多卡,存储的那个socket地址端口,有效期非常短 - //不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了 - //所以此处采用跟随设备消息下发指令 - JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,terminalPhoneNo); - } - public IJT808Session RemoveSession(string terminalPhoneNo) - { - //设备离线可以进行通知 - //使用Redis 发布订阅 - if (string.IsNullOrEmpty(terminalPhoneNo)) return default; - if (!Sessions.TryGetValue(terminalPhoneNo, out IJT808Session jT808Session)) - { - return default; - } - // 处理转发过来的是数据 这时候通道对设备是1对多关系,需要清理垃圾数据 - //1.用当前会话的通道Id找出通过转发过来的其他设备的终端号 - var terminalPhoneNos = Sessions.Where(w => w.Value.Channel.Id == jT808Session.Channel.Id).Select(s => s.Key).ToList(); - //2.存在则一个个移除 - if (terminalPhoneNos.Count > 1) - { - //3.移除包括当前的设备号 - foreach (var key in terminalPhoneNos) - { - Sessions.TryRemove(key, out IJT808Session jT808SessionRemove); - } - string nos = string.Join(",", terminalPhoneNos); - logger.LogInformation($">>>{terminalPhoneNo}-{nos} 1-n Session Remove."); - JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); - return jT808Session; - } - else - { - if (Sessions.TryRemove(terminalPhoneNo, out IJT808Session jT808SessionRemove)) - { - logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); - JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, terminalPhoneNo); - return jT808SessionRemove; - } - else - { - return default; - } - } - } - public void RemoveSessionByChannel(IChannel channel) - { - //设备离线可以进行通知 - //使用Redis 发布订阅 - var terminalPhoneNos = Sessions.Where(w => w.Value.Channel.Id == channel.Id).Select(s => s.Key).ToList(); - if (terminalPhoneNos.Count > 0) - { - foreach (var key in terminalPhoneNos) - { - Sessions.TryRemove(key, out IJT808Session jT808SessionRemove); - } - string nos = string.Join(",", terminalPhoneNos); - logger.LogInformation($">>>{nos} Channel Remove."); - JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); - } - } - public IEnumerable GetAll() - { - return Sessions.Select(s => s.Value).ToList(); - } - public IEnumerable GetTcpAll() - { - return Sessions.Where(w => w.Value.TransportProtocolType == JT808TransportProtocolType.tcp).Select(s => (JT808TcpSession)s.Value).ToList(); - } - public IEnumerable GetUdpAll() - { - return Sessions.Where(w => w.Value.TransportProtocolType == JT808TransportProtocolType.udp).Select(s => (JT808UdpSession)s.Value).ToList(); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808ConsumerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808ConsumerConfig.cs deleted file mode 100644 index 5ff137a..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808ConsumerConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808ConsumerConfig: ConsumerConfig, IOptions - { - public string TopicName { get; set; } - - public JT808ConsumerConfig Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808MsgConsumerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808MsgConsumerConfig.cs deleted file mode 100644 index c37439f..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808MsgConsumerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808MsgConsumerConfig : JT808ConsumerConfig, IOptions - { - JT808MsgConsumerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808MsgProducerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808MsgProducerConfig.cs deleted file mode 100644 index 659789c..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808MsgProducerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808MsgProducerConfig : JT808ProducerConfig, IOptions - { - JT808MsgProducerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyConsumerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyConsumerConfig.cs deleted file mode 100644 index d7db165..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyConsumerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808MsgReplyConsumerConfig : JT808ConsumerConfig, IOptions - { - JT808MsgReplyConsumerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyProducerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyProducerConfig.cs deleted file mode 100644 index 5b13af2..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808MsgReplyProducerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808MsgReplyProducerConfig : JT808ProducerConfig, IOptions - { - JT808MsgReplyProducerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808ProducerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808ProducerConfig.cs deleted file mode 100644 index 1a3c9ad..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808ProducerConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808ProducerConfig : ProducerConfig,IOptions - { - public string TopicName { get; set; } - - public JT808ProducerConfig Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808SessionConsumerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808SessionConsumerConfig.cs deleted file mode 100644 index 2aceeb4..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808SessionConsumerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808SessionConsumerConfig : JT808ConsumerConfig, IOptions - { - JT808SessionConsumerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/Configs/JT808SessionProducerConfig.cs b/src/JT808.DotNetty.Kafka/Configs/JT808SessionProducerConfig.cs deleted file mode 100644 index 37c0a06..0000000 --- a/src/JT808.DotNetty.Kafka/Configs/JT808SessionProducerConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Confluent.Kafka; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - public class JT808SessionProducerConfig : JT808ProducerConfig, IOptions - { - JT808SessionProducerConfig IOptions.Value => this; - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808.DotNetty.Kafka.csproj b/src/JT808.DotNetty.Kafka/JT808.DotNetty.Kafka.csproj deleted file mode 100644 index 73712d4..0000000 --- a/src/JT808.DotNetty.Kafka/JT808.DotNetty.Kafka.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Kafka - JT808.DotNetty.Kafka - 基于Kafka的JT808消息发布与订阅 - 基于Kafka的JT808消息发布与订阅 - - - - - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.Kafka/JT808ClientBuilderDefault.cs b/src/JT808.DotNetty.Kafka/JT808ClientBuilderDefault.cs deleted file mode 100644 index 245125c..0000000 --- a/src/JT808.DotNetty.Kafka/JT808ClientBuilderDefault.cs +++ /dev/null @@ -1,25 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.Protocol; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka -{ - internal class JT808ClientBuilderDefault : IJT808ClientBuilder - { - public IJT808Builder JT808Builder { get; } - - public JT808ClientBuilderDefault(IJT808Builder builder) - { - JT808Builder = builder; - } - - public IJT808Builder Builder() - { - return JT808Builder; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Kafka/JT808ClientKafkaExtensions.cs b/src/JT808.DotNetty.Kafka/JT808ClientKafkaExtensions.cs deleted file mode 100644 index d53c421..0000000 --- a/src/JT808.DotNetty.Kafka/JT808ClientKafkaExtensions.cs +++ /dev/null @@ -1,64 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.Protocol; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; - -namespace JT808.DotNetty.Kafka -{ - public static class JT808ClientKafkaExtensions - { - public static IJT808ClientBuilder AddJT808ClientKafka(this IJT808Builder builder) - { - return new JT808ClientBuilderDefault(builder); - } - /// - /// - /// - /// - /// GetSection("JT808MsgConsumerConfig") - /// - public static IJT808ClientBuilder AddMsgConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808MsgConsumerConfig")); - jT808ClientBuilder.JT808Builder.Services.TryAddSingleton(); - return jT808ClientBuilder; - } - /// - /// - /// - /// - /// GetSection("JT808MsgReplyProducerConfig") - /// - public static IJT808ClientBuilder AddMsgReplyProducer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808MsgReplyProducerConfig")); - jT808ClientBuilder.JT808Builder.Services.TryAddSingleton(); - return jT808ClientBuilder; - } - /// - /// - /// - /// - /// GetSection("JT808MsgReplyConsumerConfig") - /// - public static IJT808ClientBuilder AddMsgReplyConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808MsgReplyConsumerConfig")); - jT808ClientBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(JT808MsgReplyConsumer), ServiceLifetime.Singleton)); - return jT808ClientBuilder; - } - /// - /// - /// - /// - /// GetSection("JT808SessionConsumerConfig") - /// - public static IJT808ClientBuilder AddSessionConsumer(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808SessionConsumerConfig")); - jT808ClientBuilder.JT808Builder.Services.TryAddSingleton(); - return jT808ClientBuilder; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Kafka/JT808MsgConsumer.cs b/src/JT808.DotNetty.Kafka/JT808MsgConsumer.cs deleted file mode 100644 index e144cb4..0000000 --- a/src/JT808.DotNetty.Kafka/JT808MsgConsumer.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -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.DotNetty.Kafka -{ - public sealed class JT808MsgConsumer : IJT808MsgConsumer - { - private bool disposed = false; - public CancellationTokenSource Cts { get; private set; } = new CancellationTokenSource(); - - private readonly IConsumer consumer; - - private readonly ILogger logger; - - public string TopicName { get; } - - public JT808MsgConsumer( - IOptions consumerConfigAccessor, - ILoggerFactory loggerFactory) - { - consumer = new ConsumerBuilder(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) - { - if (disposed) return; - try - { - //如果不指定分区,根据kafka的机制会从多个分区中拉取数据 - //如果指定分区,根据kafka的机制会从相应的分区中拉取数据 - var data = consumer.Consume(Cts.Token); - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}"); - } - callback((data.Message.Key, data.Message.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() - { - if (disposed) return; - consumer.Unsubscribe(); - Cts.Cancel(); - } - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - consumer.Close(); - consumer.Dispose(); - Cts.Dispose(); - } - disposed = true; - } - ~JT808MsgConsumer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808MsgProducer.cs b/src/JT808.DotNetty.Kafka/JT808MsgProducer.cs deleted file mode 100644 index 14a9d78..0000000 --- a/src/JT808.DotNetty.Kafka/JT808MsgProducer.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Kafka -{ - public sealed class JT808MsgProducer : IJT808MsgProducer - { - private bool disposed = false; - public string TopicName { get; } - - private readonly IProducer producer; - public JT808MsgProducer( - IOptions producerConfigAccessor) - { - producer = new ProducerBuilder(producerConfigAccessor.Value).Build(); - TopicName = producerConfigAccessor.Value.TopicName; - } - - public async Task ProduceAsync(string terminalNo, byte[] data) - { - if (disposed) return; - await producer.ProduceAsync(TopicName, new Message - { - Key = terminalNo, - Value = data - }); - } - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - producer.Dispose(); - } - disposed = true; - } - ~JT808MsgProducer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808MsgReplyConsumer.cs b/src/JT808.DotNetty.Kafka/JT808MsgReplyConsumer.cs deleted file mode 100644 index 8fdefa3..0000000 --- a/src/JT808.DotNetty.Kafka/JT808MsgReplyConsumer.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -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.DotNetty.Kafka -{ - public sealed class JT808MsgReplyConsumer : IJT808MsgReplyConsumer - { - private bool disposed = false; - public CancellationTokenSource Cts { get; private set; } = new CancellationTokenSource(); - - private readonly IConsumer consumer; - - private readonly ILogger logger; - - public string TopicName { get; } - - public JT808MsgReplyConsumer( - IOptions consumerConfigAccessor, - ILoggerFactory loggerFactory) - { - consumer = new ConsumerBuilder(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) - { - if (disposed) return; - try - { - //如果不指定分区,根据kafka的机制会从多个分区中拉取数据 - //如果指定分区,根据kafka的机制会从相应的分区中拉取数据 - var data = consumer.Consume(Cts.Token); - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}"); - } - callback((data.Message.Key, data.Message.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() - { - if (disposed) return; - consumer.Unsubscribe(); - Cts.Cancel(); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - consumer.Close(); - consumer.Dispose(); - Cts.Dispose(); - } - disposed = true; - } - ~JT808MsgReplyConsumer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808MsgReplyProducer.cs b/src/JT808.DotNetty.Kafka/JT808MsgReplyProducer.cs deleted file mode 100644 index bf938bc..0000000 --- a/src/JT808.DotNetty.Kafka/JT808MsgReplyProducer.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Kafka -{ - public sealed class JT808MsgReplyProducer : IJT808MsgReplyProducer - { - private bool disposed = false; - public string TopicName { get;} - - private IProducer producer; - public JT808MsgReplyProducer( - IOptions producerConfigAccessor) - { - producer = new ProducerBuilder(producerConfigAccessor.Value).Build(); - TopicName = producerConfigAccessor.Value.TopicName; - } - - public async Task ProduceAsync(string terminalNo, byte[] data) - { - if (disposed) return; - await producer.ProduceAsync(TopicName, new Message - { - Key = terminalNo, - Value = data - }); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - producer.Dispose(); - } - disposed = true; - } - ~JT808MsgReplyProducer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808ServerKafkaExtensions.cs b/src/JT808.DotNetty.Kafka/JT808ServerKafkaExtensions.cs deleted file mode 100644 index 0c96d43..0000000 --- a/src/JT808.DotNetty.Kafka/JT808ServerKafkaExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; - -namespace JT808.DotNetty.Kafka -{ - public static class JT808ServerKafkaExtensions - { - /// - /// - /// - /// - /// GetSection("JT808MsgProducerConfig") - /// - public static IJT808NettyBuilder AddJT808ServerKafkaMsgProducer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) - { - jT808NettyBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808MsgProducerConfig")); - jT808NettyBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgProducer), typeof(JT808MsgProducer), ServiceLifetime.Singleton)); - return jT808NettyBuilder; - } - /// - /// - /// - /// - /// GetSection("JT808MsgReplyConsumerConfig") - /// - public static IJT808NettyBuilder AddJT808ServerKafkaMsgReplyConsumer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) - { - jT808NettyBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808MsgReplyConsumerConfig")); - jT808NettyBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(JT808MsgReplyConsumer), ServiceLifetime.Singleton)); - return jT808NettyBuilder; - } - /// - /// - /// - /// - /// GetSection("JT808SessionProducerConfig") - /// - public static IJT808NettyBuilder AddJT808ServerKafkaSessionProducer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) - { - jT808NettyBuilder.JT808Builder.Services.Configure(configuration.GetSection("JT808SessionProducerConfig")); - jT808NettyBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808SessionProducer), typeof(JT808SessionProducer), ServiceLifetime.Singleton)); - return jT808NettyBuilder; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Kafka/JT808SessionConsumer.cs b/src/JT808.DotNetty.Kafka/JT808SessionConsumer.cs deleted file mode 100644 index 04fb585..0000000 --- a/src/JT808.DotNetty.Kafka/JT808SessionConsumer.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -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.DotNetty.Kafka -{ - public sealed class JT808SessionConsumer : IJT808SessionConsumer - { - private bool disposed = false; - public CancellationTokenSource Cts { get; private set; } = new CancellationTokenSource(); - - private readonly IConsumer consumer; - - private readonly ILogger logger; - - public string TopicName { get; } - - public JT808SessionConsumer( - IOptions consumerConfigAccessor, - ILoggerFactory loggerFactory) - { - consumer = new ConsumerBuilder(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) - { - if (disposed) return; - try - { - //如果不指定分区,根据kafka的机制会从多个分区中拉取数据 - //如果指定分区,根据kafka的机制会从相应的分区中拉取数据 - var data = consumer.Consume(Cts.Token); - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}"); - } - callback((data.Message.Key, data.Message.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() - { - if (disposed) return; - consumer.Unsubscribe(); - Cts.Cancel(); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - consumer.Close(); - consumer.Dispose(); - Cts.Dispose(); - } - disposed = true; - } - ~JT808SessionConsumer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.Kafka/JT808SessionProducer.cs b/src/JT808.DotNetty.Kafka/JT808SessionProducer.cs deleted file mode 100644 index 1eba8f8..0000000 --- a/src/JT808.DotNetty.Kafka/JT808SessionProducer.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Confluent.Kafka; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Kafka -{ - public sealed class JT808SessionProducer : IJT808SessionProducer - { - private bool disposed = false; - public string TopicName { get; } - - private readonly IProducer producer; - public JT808SessionProducer( - IOptions producerConfigAccessor) - { - producer = new ProducerBuilder(producerConfigAccessor.Value).Build(); - TopicName = producerConfigAccessor.Value.TopicName; - } - - public async Task ProduceAsync(string notice,string terminalNo) - { - if (disposed) return; - await producer.ProduceAsync(TopicName, new Message - { - Key = notice, - Value = terminalNo - }); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - if (disposing) - { - producer.Dispose(); - } - disposed = true; - } - ~JT808SessionProducer() - { - Dispose(false); - } - public void Dispose() - { - //必须为true - Dispose(true); - //通知垃圾回收机制不再调用终结器(析构器) - GC.SuppressFinalize(this); - } - } -} diff --git a/src/JT808.DotNetty.RabbitMQ/JT808.DotNetty.RabbitMQ.csproj b/src/JT808.DotNetty.RabbitMQ/JT808.DotNetty.RabbitMQ.csproj deleted file mode 100644 index 0f3fc58..0000000 --- a/src/JT808.DotNetty.RabbitMQ/JT808.DotNetty.RabbitMQ.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - - JT808.DotNetty.RabbitMQ - JT808.DotNetty.RabbitMQ - 基于RabbitMQ的JT808消息发布与订阅 - 基于RabbitMQ的JT808消息发布与订阅 - - - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.RabbitMQ/JT808MsgProducer.cs b/src/JT808.DotNetty.RabbitMQ/JT808MsgProducer.cs deleted file mode 100644 index 4f0b149..0000000 --- a/src/JT808.DotNetty.RabbitMQ/JT808MsgProducer.cs +++ /dev/null @@ -1,35 +0,0 @@ -using EasyNetQ; -using EasyNetQ.Topology; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.DotNetty.RabbitMQ -{ - public class JT808MsgProducer : IJT808MsgProducer - { - public string TopicName { get; } - - private readonly IBus bus; - public JT808MsgProducer(IOptions producerConfigAccessor) - { - bus = RabbitHutch.CreateBus(producerConfigAccessor.Value.ConnectionString); - TopicName = producerConfigAccessor.Value.TopicName; - } - - public void Dispose() - { - bus.Dispose(); - } - - public Task ProduceAsync(string terminalNo, byte[] data) - { - var exchange = bus.Advanced.ExchangeDeclare(TopicName, ExchangeType.Fanout); - bus.Advanced.Publish(exchange, "", false, new Message(data)); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.RabbitMQ/JT808ProducerConfig.cs b/src/JT808.DotNetty.RabbitMQ/JT808ProducerConfig.cs deleted file mode 100644 index cf43fa1..0000000 --- a/src/JT808.DotNetty.RabbitMQ/JT808ProducerConfig.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.RabbitMQ -{ - public class JT808ProducerConfig : IOptions - { - public string TopicName { get; set; } - public string ConnectionString { get; set; } - public JT808ProducerConfig Value => this; - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808.DotNetty.MsgIdHandler.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808.DotNetty.MsgIdHandler.Test.csproj deleted file mode 100644 index 4a7ccfe..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808.DotNetty.MsgIdHandler.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs deleted file mode 100644 index de53c04..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/JT808DotNettyMsgIdHandlerDefaultImpl.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -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.DotNetty.MsgIdHandler.Test -{ - public class JT808DotNettyMsgIdHandlerDefaultImpl : IJT808DotNettyMsgIdHandler - { - public readonly ILogger logger; - public JT808DotNettyMsgIdHandlerDefaultImpl(ILoggerFactory loggerFactory, - IServiceProvider serviceProvider) { - logger = loggerFactory.CreateLogger(); - 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()}"); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Program.cs deleted file mode 100644 index 26587d8..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Program.cs +++ /dev/null @@ -1,38 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgConsumer(hostContext.Configuration) - .AddJT808MsgIdHandler(); - }); - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Properties/launchSettings.json deleted file mode 100644 index 034806e..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.MsgIdHandler.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/appsettings.json deleted file mode 100644 index 40bd102..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgIdHandler.Test/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808.DotNetty.MsgLogging.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808.DotNetty.MsgLogging.Test.csproj deleted file mode 100644 index 67f35cf..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808.DotNetty.MsgLogging.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808MsgLoggingImpl.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808MsgLoggingImpl.cs deleted file mode 100644 index 6c88628..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/JT808MsgLoggingImpl.cs +++ /dev/null @@ -1,49 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -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.DotNetty.MsgLogging.Test -{ - public class JT808MsgLoggingImpl : IJT808MsgLogging - { - public readonly ILogger logger; - public JT808MsgLoggingImpl(ILoggerFactory loggerFactory) { - logger = loggerFactory.CreateLogger(); - 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()}"); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Program.cs deleted file mode 100644 index c594bee..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Program.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgConsumer(hostContext.Configuration) - .AddMsgReplyConsumer(hostContext.Configuration) - .AddJT808MsgLogging(); - }) - ; - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Properties/launchSettings.json deleted file mode 100644 index faa2a57..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.MsgLogging.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/appsettings.json deleted file mode 100644 index 373ec70..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.MsgLogging.Test/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyConsumerConfig": { - "TopicName": "JT808MsgReply", - "GroupId": "msgreply-group", - "BootstrapServers": "127.0.0.1:9093" - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808.DotNetty.ReplyMessage.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808.DotNetty.ReplyMessage.Test.csproj deleted file mode 100644 index 5e4a007..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808.DotNetty.ReplyMessage.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs deleted file mode 100644 index 0898fd4..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/JT808DotNettyReplyMessageServiceInherited.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -using JT808.Protocol; -using JT808.Protocol.Extensions; -using Microsoft.Extensions.Logging; - -namespace JT808.DotNetty.ReplyMessage.Test -{ - public class JT808DotNettyReplyMessageServiceInherited : JT808DotNettyReplyMessageService - { - public readonly ILogger logger; - - public JT808DotNettyReplyMessageServiceInherited(IJT808Config jT808Config, - IJT808MsgReplyProducer jT808MsgReplyProducer, - ILoggerFactory loggerFactory) - : base(jT808Config, jT808MsgReplyProducer) - { - logger = loggerFactory.CreateLogger(); - 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); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Program.cs deleted file mode 100644 index 5b7510f..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Program.cs +++ /dev/null @@ -1,41 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgConsumer(hostContext.Configuration) - .AddMsgReplyProducer(hostContext.Configuration) - .AddInprocJT808ReplyMessage(); - }) - ; - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Properties/launchSettings.json deleted file mode 100644 index f800717..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.ReplyMessage.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/appsettings.json deleted file mode 100644 index 40bd102..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.ReplyMessage.Test/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808.DotNetty.SessionNotice.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808.DotNetty.SessionNotice.Test.csproj deleted file mode 100644 index d638a8a..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808.DotNetty.SessionNotice.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs deleted file mode 100644 index 949afcc..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/JT808DotNettySessionNoticeServiceInherited.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -using Microsoft.Extensions.Logging; - -namespace JT808.DotNetty.SessionNotice.Test -{ - public class JT808DotNettySessionNoticeServiceInherited : JT808DotNettySessionNoticeService - { - 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); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Program.cs deleted file mode 100644 index 7aa840e..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Program.cs +++ /dev/null @@ -1,40 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddSessionConsumer(hostContext.Configuration) - .AddInprocJT808SessionNotice(); - }) - ; - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Properties/launchSettings.json deleted file mode 100644 index 20bfb21..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.SessionNotice.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/appsettings.json deleted file mode 100644 index d5f2a06..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.SessionNotice.Test/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808SessionConsumerConfig": { - "TopicName": "JT808Session", - "GroupId": "session-group", - "BootstrapServers": "127.0.0.1:9094" - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808.DotNetty.Traffic.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808.DotNetty.Traffic.Test.csproj deleted file mode 100644 index a7798de..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808.DotNetty.Traffic.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808DotNettyTrafficServiceTest.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808DotNettyTrafficServiceTest.cs deleted file mode 100644 index e33f9e8..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/JT808DotNettyTrafficServiceTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -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.DotNetty.Traffic.Test -{ - public class JT808DotNettyTrafficServiceTest - { - private readonly CSRedis.CSRedisClient redisClien; - public readonly ILogger logger; - public JT808DotNettyTrafficServiceTest(ILoggerFactory loggerFactory) { - redisClien = new CSRedis.CSRedisClient("127.0.0.1:6379,password=smallchi"); - RedisHelper.Initialization(redisClien); - logger = loggerFactory.CreateLogger(); - 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}"); - } - }); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Program.cs deleted file mode 100644 index b86a523..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Program.cs +++ /dev/null @@ -1,43 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddSingleton(); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgConsumer(hostContext.Configuration) - .AddInprocJT808Traffic(); - - services.BuildServiceProvider().GetRequiredService(); - }) - ; - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Properties/launchSettings.json deleted file mode 100644 index a98570a..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.Traffic.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/appsettings.json deleted file mode 100644 index 40bd102..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Traffic.Test/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808.DotNetty.Transmit.Test.csproj b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808.DotNetty.Transmit.Test.csproj deleted file mode 100644 index f0bd7e1..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808.DotNetty.Transmit.Test.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808DotNettyTransmitServiceTest.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808DotNettyTransmitServiceTest.cs deleted file mode 100644 index bee4288..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/JT808DotNettyTransmitServiceTest.cs +++ /dev/null @@ -1,34 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -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.DotNetty.Transmit.Test -{ - public class JT808DotNettyTransmitServiceTest - { - public readonly ILogger logger; - public JT808DotNettyTransmitServiceTest(ILoggerFactory loggerFactory) { - logger = loggerFactory.CreateLogger(); - 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(); - } - } - }); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Program.cs b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Program.cs deleted file mode 100644 index 7f55500..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Program.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.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.DotNetty.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(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddSingleton(); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgConsumer(hostContext.Configuration) - .AddInprocJT808Transmit(hostContext.Configuration); - services.BuildServiceProvider().GetRequiredService(); - }) - ; - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Properties/launchSettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Properties/launchSettings.json deleted file mode 100644 index a7aecc2..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/Properties/launchSettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": { - "JT808.DotNetty.Transmit.Test": { - "commandName": "Project", - "commandLineArgs": "ASPNETCORE_ENVIRONMENT=Development", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/appsettings.json b/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/appsettings.json deleted file mode 100644 index 40bd102..0000000 --- a/src/JT808.DotNetty.Services.Tests/JT808.DotNetty.Transmit.Test/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/IJT808DotNettyMsgIdHandler.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/IJT808DotNettyMsgIdHandler.cs deleted file mode 100644 index 1285d88..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/IJT808DotNettyMsgIdHandler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.MsgIdHandler -{ - /// - /// JT808消息Id处理程序 - /// - public interface IJT808DotNettyMsgIdHandler - { - void Processor((string TerminalNo, byte[] Data) parameter); - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808.DotNetty.MsgIdHandler.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808.DotNetty.MsgIdHandler.csproj deleted file mode 100644 index d93e217..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808.DotNetty.MsgIdHandler.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.MsgIdHandler - JT808.DotNetty.MsgIdHandler - 基于JT808消息业务处理程序服务 - 基于JT808消息业务处理程序服务 - LICENSE - - - - - - - - - diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerExtensions.cs deleted file mode 100644 index 74fb417..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.MsgIdHandler -{ - public static class JT808DotNettyMsgIdHandlerExtensions - { - public static IJT808ClientBuilder AddJT808MsgIdHandler(this IJT808ClientBuilder jT808ClientBuilder) - where TJT808DotNettyMsgIdHandler: IJT808DotNettyMsgIdHandler - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(typeof(IJT808DotNettyMsgIdHandler),typeof(TJT808DotNettyMsgIdHandler)); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerHostedService.cs deleted file mode 100644 index b2209e5..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgIdHandler/JT808DotNettyMsgIdHandlerHostedService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.MsgIdHandler -{ - public class JT808DotNettyMsgIdHandlerHostedService : IHostedService - { - private readonly IJT808MsgConsumer jT808MsgConsumer; - - private readonly IJT808DotNettyMsgIdHandler jT808DotNettyMsgIdHandler; - public JT808DotNettyMsgIdHandlerHostedService( - IJT808DotNettyMsgIdHandler jT808DotNettyMsgIdHandler, - IJT808MsgConsumer jT808MsgConsumer) - { - this.jT808DotNettyMsgIdHandler = jT808DotNettyMsgIdHandler; - this.jT808MsgConsumer = jT808MsgConsumer; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - jT808MsgConsumer.Subscribe(); - jT808MsgConsumer.OnMessage(jT808DotNettyMsgIdHandler.Processor); - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - jT808MsgConsumer.Unsubscribe(); - return Task.CompletedTask; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808.DotNetty.MsgLogging.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808.DotNetty.MsgLogging.csproj deleted file mode 100644 index 21b1e3f..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808.DotNetty.MsgLogging.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.MsgLogging - JT808.DotNetty.MsgLogging - 基于JT808消息上下行日志服务 - 基于JT808消息上下行日志服务 - LICENSE - - - - - - - - - diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgDownLoggingHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgDownLoggingHostedService.cs deleted file mode 100644 index f7b9dd0..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgDownLoggingHostedService.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.MsgLogging -{ - public class JT808DotNettyMsgDownLoggingHostedService : IHostedService - { - private readonly IJT808MsgReplyConsumer jT808MsgReplyConsumer; - private readonly IJT808MsgLogging jT808MsgLogging; - public JT808DotNettyMsgDownLoggingHostedService( - 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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgLoggingExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgLoggingExtensions.cs deleted file mode 100644 index d5d7f7f..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgLoggingExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.MsgLogging -{ - public static class JT808DotNettyMsgLoggingExtensions - { - public static IJT808ClientBuilder AddJT808MsgLogging(this IJT808ClientBuilder jT808ClientBuilder) - where TJT808MsgLogging: IJT808MsgLogging - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(typeof(IJT808MsgLogging),typeof(TJT808MsgLogging)); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgUpLoggingHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgUpLoggingHostedService.cs deleted file mode 100644 index 2dea945..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808DotNettyMsgUpLoggingHostedService.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.MsgLogging -{ - public class JT808DotNettyMsgUpLoggingHostedService : IHostedService - { - private readonly IJT808MsgConsumer jT808MsgConsumer; - private readonly IJT808MsgLogging jT808MsgLogging; - public JT808DotNettyMsgUpLoggingHostedService( - 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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808MsgLoggingType.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808MsgLoggingType.cs deleted file mode 100644 index ae911cf..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/JT808MsgLoggingType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.MsgLogging -{ - public enum JT808MsgLoggingType - { - /// - /// 数据上行 - /// - up, - /// - /// 数据下行 - /// - down - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808.DotNetty.ReplyMessage.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808.DotNetty.ReplyMessage.csproj deleted file mode 100644 index f80a488..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808.DotNetty.ReplyMessage.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.ReplyMessage - JT808.DotNetty.ReplyMessage - 基于JT808消息业务处理程序服务 - 基于JT808消息业务处理程序服务 - LICENSE - - - - - - - - diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageExtensions.cs deleted file mode 100644 index 156d64a..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.ReplyMessage -{ - public static class JT808DotNettyReplyMessageExtensions - { - /// - /// 独享消息应答服务(不同的消费者实例) - /// - /// - /// - public static IJT808ClientBuilder AddInprocJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - /// - /// 独享消息应答服务(不同的消费者实例) - /// - /// 自定义消息回复服务 - /// - /// - public static IJT808ClientBuilder AddInprocJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder) - where TReplyMessageService : JT808DotNettyReplyMessageService - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - /// - /// 共享消息应答服务(消费者单实例) - /// - /// 自定义消息回复服务 - /// - /// - public static IJT808ClientBuilder AddShareJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder) - where TReplyMessageService : JT808DotNettyReplyMessageService - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - /// - /// 共享消息应答服务(消费者单实例) - /// - /// - /// - public static IJT808ClientBuilder AddShareJT808ReplyMessage(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageHostedService.cs deleted file mode 100644 index 36acede..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageHostedService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.ReplyMessage -{ - public class JT808DotNettyReplyMessageHostedService : IHostedService - { - private readonly IJT808MsgConsumer jT808MsgConsumer; - private readonly JT808DotNettyReplyMessageService jT808DotNettyReplyMessageService; - - public JT808DotNettyReplyMessageHostedService( - JT808DotNettyReplyMessageService 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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageService.cs deleted file mode 100644 index 4a0bad4..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.ReplyMessage/JT808DotNettyReplyMessageService.cs +++ /dev/null @@ -1,250 +0,0 @@ -using JT808.DotNetty.Abstractions; -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.DotNetty.ReplyMessage -{ - public class JT808DotNettyReplyMessageService - { - protected Dictionary HandlerDict { get; } - - protected delegate byte[] MsgIdMethodDelegate(JT808HeaderPackage package); - protected JT808Serializer JT808Serializer { get; } - protected IJT808MsgReplyProducer JT808MsgReplyProducer { get; } - public JT808DotNettyReplyMessageService( - IJT808Config jT808Config, - IJT808MsgReplyProducer jT808MsgReplyProducer) - { - this.JT808Serializer = jT808Config.GetSerializer(); - this.JT808MsgReplyProducer = jT808MsgReplyProducer; - HandlerDict = new Dictionary { - {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 - { - } - } - - /// - /// 终端通用应答 - /// 平台无需回复 - /// 实现自己的业务 - /// - /// - /// - public virtual byte[] Msg0x0001(JT808HeaderPackage request) - { - return null; - } - /// - /// 终端心跳 - /// - /// - /// - public virtual byte[] Msg0x0002(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端注销 - /// - /// - /// - public virtual byte[] Msg0x0003(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端注册 - /// - /// - /// - public virtual byte[] Msg0x0100(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.终端注册应答.Create_终端注册应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8100() - { - Code = "J" + request.Header.TerminalPhoneNo, - JT808TerminalRegisterResult = JT808TerminalRegisterResult.成功, - AckMsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.终端注册应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8100() - { - Code = "J" + request.Header.TerminalPhoneNo, - JT808TerminalRegisterResult = JT808TerminalRegisterResult.成功, - AckMsgNum = request.Header.MsgNum - })); - } - } - /// - /// 终端鉴权 - /// - /// - /// - public virtual byte[] Msg0x0102(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 位置信息汇报 - /// - /// - /// - public virtual byte[] Msg0x0200(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 定位数据批量上传 - /// - /// - /// - public virtual byte[] Msg0x0704(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - /// - /// 数据上行透传 - /// - /// - /// - public virtual byte[] Msg0x0900(JT808HeaderPackage request) - { - if (request.Version == JT808Version.JTT2019) - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create_平台通用应答_2019(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - else - { - return JT808Serializer.Serialize(JT808MsgId.平台通用应答.Create(request.Header.TerminalPhoneNo, new JT808_0x8001() - { - AckMsgId = request.Header.MsgId, - JT808PlatformResult = JT808PlatformResult.成功, - MsgNum = request.Header.MsgNum - })); - } - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808.DotNetty.SessionNotice.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808.DotNetty.SessionNotice.csproj deleted file mode 100644 index 74063cb..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808.DotNetty.SessionNotice.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.SessionNotice - JT808.DotNetty.SessionNotice - 基于JT808会话通知服务 - 基于JT808会话通知服务 - LICENSE - - - - - - - - - diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeExtensions.cs deleted file mode 100644 index df7bce8..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeExtensions.cs +++ /dev/null @@ -1,61 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.SessionNotice -{ - public static class JT808DotNettySessionNoticeExtensions - { - /// - /// 独享消息会话通知服务(不同的消费者实例) - /// - /// - /// - public static IJT808ClientBuilder AddInprocJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - - /// - /// 独享消息会话通知服务(不同的消费者实例) - /// - /// 自定义会话通知服务 - /// - /// - public static IJT808ClientBuilder AddInprocJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder) - where TSessionNoticeService : JT808DotNettySessionNoticeService - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - - /// - /// 共享消息会话通知服务(消费者单实例) - /// - /// 自定义会话通知服务 - /// - /// - public static IJT808ClientBuilder AddShareJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder) - where TSessionNoticeService : JT808DotNettySessionNoticeService - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - - /// - /// 共享消息会话通知服务(消费者单实例) - /// - /// - /// - public static IJT808ClientBuilder AddShareJT808SessionNotice(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeHostedService.cs deleted file mode 100644 index a610ade..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeHostedService.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using JT808.Protocol; -using JT808.Protocol.Interfaces; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.SessionNotice -{ - public class JT808DotNettySessionNoticeHostedService : IHostedService - { - private readonly JT808DotNettySessionNoticeService jT808DotNettySessionNoticeService; - private readonly IJT808SessionConsumer jT808SessionConsumer; - public JT808DotNettySessionNoticeHostedService( - IJT808SessionConsumer jT808SessionConsumer, - JT808DotNettySessionNoticeService 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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeService.cs deleted file mode 100644 index a4f164b..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.SessionNotice/JT808DotNettySessionNoticeService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.SessionNotice -{ - public class JT808DotNettySessionNoticeService - { - protected ILogger logger { get; } - public JT808DotNettySessionNoticeService(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}"); - } - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808.DotNetty.Traffic.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808.DotNetty.Traffic.csproj deleted file mode 100644 index e50003a..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808.DotNetty.Traffic.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Traffic - JT808.DotNetty.Traffic - 基于JT808设备流量统计服务 - 基于JT808设备流量统计服务 - LICENSE - - - - - - - - - - - diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficService.cs deleted file mode 100644 index 1dde491..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficService.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.Extensions.Configuration; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Traffic -{ - public class JT808DotNettyTrafficService:IDisposable - { - private readonly CSRedis.CSRedisClient redisClien; - public JT808DotNettyTrafficService(IConfiguration configuration) - { - redisClien = new CSRedis.CSRedisClient(configuration.GetConnectionString("TrafficRedisHost")); - TrafficRedisClient.Initialization(redisClien); - } - - public void Dispose() - { - redisClien.Dispose(); - } - - /// - /// 按设备每天统计sim卡流量 - /// - /// - /// - public void Processor(string terminalNo,int len) - { - TrafficRedisClient.HIncrBy(terminalNo, DateTime.Now.ToString("yyyyMMdd"), len); - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceExtensions.cs deleted file mode 100644 index fdeac49..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceExtensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Traffic -{ - public static class JT808DotNettyTrafficServiceExtensions - { - /// - /// 独享消息流量统计服务(不同的消费者实例) - /// - /// - /// - public static IJT808ClientBuilder AddInprocJT808Traffic(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - /// - /// 共享消息流量统计服务(消费者单实例) - /// - /// - /// - /// - public static IJT808ClientBuilder AddShareJT808Traffic(this IJT808ClientBuilder jT808ClientBuilder) - { - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceHostedService.cs deleted file mode 100644 index 9de189f..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/JT808DotNettyTrafficServiceHostedService.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; -using JT808.Protocol.Extensions; - -namespace JT808.DotNetty.Traffic -{ - public class JT808DotNettyTrafficServiceHostedService : IHostedService - { - private readonly IJT808MsgConsumer jT808MsgConsumer; - private readonly JT808DotNettyTrafficService jT808DotNettyTrafficService; - - public JT808DotNettyTrafficServiceHostedService( - JT808DotNettyTrafficService 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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/TrafficRedisClient.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/TrafficRedisClient.cs deleted file mode 100644 index 675dd10..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Traffic/TrafficRedisClient.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Traffic -{ - class TrafficRedisClient: RedisHelper - { } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/DataTransferOptions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/DataTransferOptions.cs deleted file mode 100644 index 4aff0a4..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/DataTransferOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Transmit.Configs -{ - public class DataTransferOptions - { - public string Host { get; set; } - - public List TerminalNos { get; set; } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/RemoteServerOptions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/RemoteServerOptions.cs deleted file mode 100644 index 69c108f..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Configs/RemoteServerOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Transmit.Configs -{ - public class RemoteServerOptions - { - public List DataTransfer { get; set; } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Handlers/ClientConnectionHandler.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Handlers/ClientConnectionHandler.cs deleted file mode 100644 index da9926a..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/Handlers/ClientConnectionHandler.cs +++ /dev/null @@ -1,76 +0,0 @@ -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.DotNetty.Transmit.Handlers -{ - public class ClientConnectionHandler : ChannelHandlerAdapter - { - private readonly Bootstrap bootstrap; - public Dictionary channeldic; - private readonly ILogger logger; - public ClientConnectionHandler(Bootstrap bootstrap, - Dictionary channeldic, - ILoggerFactory loggerFactory) - { - this.bootstrap = bootstrap; - this.channeldic = channeldic; - logger = loggerFactory.CreateLogger(); - } - public override void ChannelInactive(IChannelHandlerContext context) - { - Policy.HandleResult(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).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(); - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808.DotNetty.Transmit.csproj b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808.DotNetty.Transmit.csproj deleted file mode 100644 index 73ba674..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808.DotNetty.Transmit.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Transmit - JT808.DotNetty.Transmit - 基于DotNetty实现的JT808数据转发服务 - 基于DotNetty实现的JT808数据转发服务 - LICENSE - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitExtensions.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitExtensions.cs deleted file mode 100644 index a5084b3..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Text; -using JT808.Protocol; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Transmit; -using Microsoft.Extensions.Configuration; -using JT808.DotNetty.Transmit.Configs; - -namespace JT808.DotNetty.Transmit -{ - public static class JT808DotNettyTransmitExtensions - { - /// - /// 独享转发服务(不同的消费者实例) - /// - /// - /// - /// - public static IJT808ClientBuilder AddInprocJT808Transmit(this IJT808ClientBuilder jT808ClientBuilder,IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("RemoteServerOptions")); - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - jT808ClientBuilder.JT808Builder.Services.AddHostedService(); - return jT808ClientBuilder; - } - /// - /// 共享转发服务(消费者单实例) - /// - /// - /// - /// - public static IJT808ClientBuilder AddShareJT808Transmit(this IJT808ClientBuilder jT808ClientBuilder, IConfiguration configuration) - { - jT808ClientBuilder.JT808Builder.Services.Configure(configuration.GetSection("RemoteServerOptions")); - jT808ClientBuilder.JT808Builder.Services.AddSingleton(); - return jT808ClientBuilder; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitHostedService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitHostedService.cs deleted file mode 100644 index 5b0f299..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitHostedService.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Hosting; -using System.Threading; - -namespace JT808.DotNetty.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; - } - } -} diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitService.cs b/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitService.cs deleted file mode 100644 index e9f6ce1..0000000 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.Transmit/JT808DotNettyTransmitService.cs +++ /dev/null @@ -1,236 +0,0 @@ -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 JT808.DotNetty.Transmit.Configs; -using System.Linq; -using JT808.DotNetty.Transmit.Handlers; - -namespace JT808.DotNetty.Transmit -{ - public class JT808DotNettyTransmitService - { - private readonly ILogger logger; - private readonly ILoggerFactory loggerFactory; - private IOptionsMonitor optionsMonitor; - public Dictionary channeldic = new Dictionary(); - public JT808DotNettyTransmitService(ILoggerFactory loggerFactory, - IOptionsMonitor 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() - .Option(ChannelOption.TcpNodelay, true) - .Handler(new ActionChannelInitializer(channel => - { - IChannelPipeline pipeline = channel.Pipeline; - pipeline.AddLast(new ClientConnectionHandler(bootstrap, channeldic, loggerFactory)); - })); - optionsMonitor.OnChange(options => - { - List lastRemoteServers = new List(); - 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); - }); - } - /// - /// 初始化远程服务器 - /// - /// - /// - /// - private async Task InitRemoteServsers(Bootstrap bootstrap) - { - List remoteServers = new List(); - 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; - } - /// - /// 动态删除远程服务器 - /// - /// - private void DelRemoteServsers(List lastRemoteServers) - { - var delChannels = channeldic.Keys.Except(lastRemoteServers).ToList(); - foreach (var item in delChannels) - { - channeldic[item].CloseAsync(); - channeldic.Remove(item); - } - } - /// - /// 动态添加远程服务器 - /// - /// - /// - private void AddRemoteServsers(Bootstrap bootstrap, List 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}"); - } - } - } - } -} diff --git a/src/JT808.DotNetty.Tcp/Handlers/JT808TcpConnectionHandler.cs b/src/JT808.DotNetty.Tcp/Handlers/JT808TcpConnectionHandler.cs deleted file mode 100644 index be98063..0000000 --- a/src/JT808.DotNetty.Tcp/Handlers/JT808TcpConnectionHandler.cs +++ /dev/null @@ -1,103 +0,0 @@ -using DotNetty.Handlers.Timeout; -using DotNetty.Transport.Channels; -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Session; -using Microsoft.Extensions.Logging; -using System; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Tcp.Handlers -{ - /// - /// JT808服务通道处理程序 - /// - internal class JT808TcpConnectionHandler : ChannelHandlerAdapter - { - private readonly ILogger logger; - - private readonly JT808SessionManager jT808SessionManager; - - public JT808TcpConnectionHandler( - JT808SessionManager jT808SessionManager, - ILoggerFactory loggerFactory) - { - this.jT808SessionManager = jT808SessionManager; - logger = loggerFactory.CreateLogger(); - } - - /// - /// 通道激活 - /// - /// - public override void ChannelActive(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($"<<<{ channelId } Successful client connection to server."); - base.ChannelActive(context); - } - - /// - /// 设备主动断开 - /// - /// - public override void ChannelInactive(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($">>>{ channelId } The client disconnects from the server."); - base.ChannelInactive(context); - base.CloseAsync(context); - } - - /// - /// 服务器主动断开 - /// - /// - /// - public override Task CloseAsync(IChannelHandlerContext context) - { - string channelId = context.Channel.Id.AsShortText(); - if (logger.IsEnabled(LogLevel.Debug)) - logger.LogDebug($"<<<{ channelId } The server disconnects from the client."); - jT808SessionManager.RemoveSessionByChannel(context.Channel); - return base.CloseAsync(context); - } - - public override void ChannelReadComplete(IChannelHandlerContext context)=> context.Flush(); - - /// - /// 超时策略 - /// - /// - /// - public override void UserEventTriggered(IChannelHandlerContext context, object evt) - { - IdleStateEvent idleStateEvent = evt as IdleStateEvent; - if (idleStateEvent != null) - { - if(idleStateEvent.State== IdleState.ReaderIdle) - { - string channelId = context.Channel.Id.AsShortText(); - logger.LogInformation($"{idleStateEvent.State.ToString()}>>>{channelId}"); - // 由于808是设备发心跳,如果很久没有上报数据,那么就由服务器主动关闭连接。 - context.CloseAsync(); - } - // 按照808的消息,有些请求必须要应答,但是转发可以不需要有应答可以节省部分资源包括: - // 1.消息的序列化 - // 2.消息的下发 - // 都有一定的性能损耗,那么不需要判断写超时 IdleState.WriterIdle - // 就跟神兽貔貅一样。。。 - } - base.UserEventTriggered(context, evt); - } - - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) - { - string channelId = context.Channel.Id.AsShortText(); - logger.LogError(exception,$"{channelId} {exception.Message}" ); - context.CloseAsync(); - } - } -} - diff --git a/src/JT808.DotNetty.Tcp/Handlers/JT808TcpServerHandler.cs b/src/JT808.DotNetty.Tcp/Handlers/JT808TcpServerHandler.cs deleted file mode 100644 index db2aba4..0000000 --- a/src/JT808.DotNetty.Tcp/Handlers/JT808TcpServerHandler.cs +++ /dev/null @@ -1,77 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Transport.Channels; -using JT808.Protocol; -using System; -using Microsoft.Extensions.Logging; -using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Abstractions.Enums; -using JT808.Protocol.Exceptions; -using JT808.DotNetty.Core.Session; -using JT808.DotNetty.Abstractions; - -namespace JT808.DotNetty.Tcp.Handlers -{ - /// - /// JT808服务端处理程序 - /// - internal class JT808TcpServerHandler : SimpleChannelInboundHandler - { - private readonly JT808SessionManager jT808SessionManager; - - private readonly JT808AtomicCounterService jT808AtomicCounterService; - - private readonly ILogger logger; - - private readonly JT808Serializer JT808Serializer; - - private readonly IJT808MsgProducer JT808MsgProducer; - - public JT808TcpServerHandler( - IJT808MsgProducer jT808MsgProducer, - IJT808Config jT808Config, - ILoggerFactory loggerFactory, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory, - JT808SessionManager jT808SessionManager) - { - this.jT808SessionManager = jT808SessionManager; - this.JT808MsgProducer = jT808MsgProducer; - this.jT808AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); - this.JT808Serializer = jT808Config.GetSerializer(); - logger = loggerFactory.CreateLogger(); - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, byte[] msg) - { - try - { - //解析到头部,然后根据具体的消息Id通过队列去进行消费 - //要是一定要解析到数据体可以在JT808MsgIdHandlerBase类中根据具体的消息, - //解析具体的消息体,具体调用JT808Serializer.Deserialize - JT808HeaderPackage jT808HeaderPackage = JT808Serializer.HeaderDeserialize(msg); - if (logger.IsEnabled(LogLevel.Trace)) - { - logger.LogTrace($"accept package success count=>{jT808AtomicCounterService.MsgSuccessCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg)}"); - } - jT808AtomicCounterService.MsgSuccessIncrement(); - jT808SessionManager.TryAdd(jT808HeaderPackage.Header.TerminalPhoneNo,ctx.Channel); - JT808MsgProducer.ProduceAsync(jT808HeaderPackage.Header.TerminalPhoneNo, msg); - } - catch (JT808Exception ex) - { - jT808AtomicCounterService.MsgFailIncrement(); - if (logger.IsEnabled(LogLevel.Error)) - { - logger.LogError(ex,$"accept package fail count=>{jT808AtomicCounterService.MsgFailCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg)}"); - } - } - catch (Exception ex) - { - jT808AtomicCounterService.MsgFailIncrement(); - if (logger.IsEnabled(LogLevel.Error)) - { - logger.LogError(ex, $"accept package fail count=>{jT808AtomicCounterService.MsgFailCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg)}"); - } - } - } - } -} diff --git a/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj b/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj deleted file mode 100644 index 8c72b7c..0000000 --- a/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Tcp - JT808.DotNetty.Tcp - 基于DotNetty实现的JT808DotNetty的Tcp服务 - 基于DotNetty实现的JT808DotNetty的Tcp服务 - - - - - - - - diff --git a/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs b/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs deleted file mode 100644 index 083bd39..0000000 --- a/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Tcp.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System.Runtime.CompilerServices; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Abstractions; - -[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] - -namespace JT808.DotNetty.Tcp -{ - public static class JT808TcpDotnettyExtensions - { - public static IJT808NettyBuilder AddJT808TcpNettyHost(this IJT808NettyBuilder jT808NettyBuilder) - { - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.AddHostedService(); - return jT808NettyBuilder; - } - - internal static IServiceCollection AddJT808TcpNettyHostTest(this IServiceCollection serviceDescriptors) - { - serviceDescriptors.TryAddScoped(); - serviceDescriptors.TryAddScoped(); - serviceDescriptors.TryAddScoped(); - serviceDescriptors.TryAddScoped(); - serviceDescriptors.AddHostedService(); - return serviceDescriptors; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs b/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs deleted file mode 100644 index 464ce88..0000000 --- a/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs +++ /dev/null @@ -1,96 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using DotNetty.Handlers.Timeout; -using DotNetty.Transport.Bootstrapping; -using DotNetty.Transport.Channels; -using DotNetty.Transport.Libuv; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.Tcp.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Net; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Tcp -{ - /// - /// JT808 Tcp网关服务 - /// - internal class JT808TcpServerHost : IHostedService - { - private readonly IServiceProvider serviceProvider; - private readonly JT808Configuration configuration; - private readonly ILogger logger; - private DispatcherEventLoopGroup bossGroup; - private WorkerEventLoopGroup workerGroup; - private IChannel bootstrapChannel; - private IByteBufferAllocator serverBufferAllocator; - - public JT808TcpServerHost( - IServiceProvider provider, - ILoggerFactory loggerFactory, - IOptions jT808ConfigurationAccessor) - { - serviceProvider = provider; - configuration = jT808ConfigurationAccessor.Value; - logger=loggerFactory.CreateLogger(); - } - - public Task StartAsync(CancellationToken cancellationToken) - { - bossGroup = new DispatcherEventLoopGroup(); - workerGroup = new WorkerEventLoopGroup(bossGroup, configuration.EventLoopCount); - serverBufferAllocator = new PooledByteBufferAllocator(); - //serverBufferAllocator = new UnpooledByteBufferAllocator(); - ServerBootstrap bootstrap = new ServerBootstrap(); - bootstrap.Group(bossGroup, workerGroup); - bootstrap.Channel(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) - || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - bootstrap - .Option(ChannelOption.SoReuseport, true) - .ChildOption(ChannelOption.SoReuseaddr, true); - } - bootstrap - .Option(ChannelOption.SoBacklog, configuration.SoBacklog) - .ChildOption(ChannelOption.Allocator, serverBufferAllocator) - .ChildHandler(new ActionChannelInitializer(channel => - { - IChannelPipeline pipeline = channel.Pipeline; - using (var scope = serviceProvider.CreateScope()) - { - 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("jt808TcpDecode", scope.ServiceProvider.GetRequiredService()); - channel.Pipeline.AddLast("jt808TcpEncode", scope.ServiceProvider.GetRequiredService()); - channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler( - configuration.ReaderIdleTimeSeconds, - configuration.WriterIdleTimeSeconds, - configuration.AllIdleTimeSeconds)); - channel.Pipeline.AddLast("jt808TcpConnection", scope.ServiceProvider.GetRequiredService()); - channel.Pipeline.AddLast("jt808TcpService", scope.ServiceProvider.GetRequiredService()); - } - })); - logger.LogInformation($"JT808 TCP Server start at {IPAddress.Any}:{configuration.TcpPort}."); - return bootstrap.BindAsync(configuration.TcpPort) - .ContinueWith(i => bootstrapChannel = i.Result); - } - - public async Task StopAsync(CancellationToken cancellationToken) - { - await bootstrapChannel.CloseAsync(); - var quietPeriod = configuration.QuietPeriodTimeSpan; - var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan; - await workerGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); - await bossGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); - } - } -} diff --git a/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.Tcp/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj deleted file mode 100644 index ace133c..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net5.0 - - false - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs deleted file mode 100644 index 003331b..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs +++ /dev/null @@ -1,74 +0,0 @@ -using DotNetty.Transport.Channels.Embedded; -using JT808.DotNetty.Core.Impls; -using System.Threading; -using Xunit; - -namespace JT808.DotNetty.Core.Test -{ - public class JT808SessionManagerTest: SeedTcpSession - { - [Fact] - public void AddTest() - { - var no = "test150"; - var channel = new EmbeddedChannel(new JT808DefaultChannelId()); - jT80TcpSessionManager.TryAdd(no,channel); - jT80TcpSessionManager.Heartbeat(no); - Assert.NotNull(jT80TcpSessionManager.GetTcpSessionByTerminalPhoneNo(no)); - } - - [Fact] - public void RemoveTest() - { - var no = "test151"; - var channel = new EmbeddedChannel(new JT808DefaultChannelId()); - jT80TcpSessionManager.TryAdd(no, channel); - var sessionInfo = jT80TcpSessionManager.RemoveSession(no); - Assert.Equal(no, sessionInfo.TerminalPhoneNo); - } - - [Fact] - public void OneChannelToManyDeviceTest1() - { - //转发过来的数据 1:n 一个通道对应多个设备 - var no = "test1"; - var no1 = "test2"; - var no2 = "test3"; - var no3 = "test4"; - var no4 = "test5"; - var channel = new EmbeddedChannel(new JT808DefaultChannelId()); - jT80TcpSessionManager.TryAdd(no,channel); - jT80TcpSessionManager.TryAdd(no1,channel); - jT80TcpSessionManager.TryAdd(no2,channel); - jT80TcpSessionManager.TryAdd(no3,channel); - jT80TcpSessionManager.TryAdd(no4,channel); - var removeSession = jT80TcpSessionManager.RemoveSession(no); - Assert.Equal(no, removeSession.TerminalPhoneNo); - Assert.Equal(channel, removeSession.Channel); - Assert.Equal(1,channel.Id.CompareTo(removeSession.Channel.Id)); - } - - - [Fact] - public void OneChannelToManyDeviceTest2() - { - //转发过来的数据 1:n 一个通道对应多个设备 - var no = "test61"; - var no1 = "test62"; - var no2 = "test63"; - var no3 = "test64"; - var no4 = "test65"; - var channel1 = new EmbeddedChannel(new JT808DefaultChannelId()); - var channel2 = new EmbeddedChannel(new JT808DefaultChannelId()); - jT80TcpSessionManager.TryAdd(no,channel1); - jT80TcpSessionManager.TryAdd(no1,channel1); - jT80TcpSessionManager.TryAdd(no2,channel1); - jT80TcpSessionManager.TryAdd(no3,channel2); - jT80TcpSessionManager.TryAdd(no4,channel2); - jT80TcpSessionManager.RemoveSessionByChannel(channel1); - Assert.Null(jT80TcpSessionManager.GetTcpSessionByTerminalPhoneNo(no)); - Assert.Null(jT80TcpSessionManager.GetTcpSessionByTerminalPhoneNo(no1)); - Assert.Null(jT80TcpSessionManager.GetTcpSessionByTerminalPhoneNo(no2)); - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs deleted file mode 100644 index c4f5c56..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs +++ /dev/null @@ -1,27 +0,0 @@ -using DotNetty.Transport.Channels.Embedded; -using JT808.DotNetty.Core.Impls; -using JT808.DotNetty.Core.Session; -using JT808.DotNetty.Internal; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Core.Test -{ - public class SeedTcpSession - { - public JT808SessionManager jT80TcpSessionManager = new JT808SessionManager( - new JT808SessionProducerDefaultImpl(new LoggerFactory()), - new LoggerFactory()); - - public SeedTcpSession() - { - for (var i = 0; i < 10; i++) - { - var channel = new EmbeddedChannel(new JT808DefaultChannelId()); - jT80TcpSessionManager.TryAdd(i.ToString(),channel); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/NLog.xsd b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/NLog.xsd deleted file mode 100644 index 2f57d09..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/NLog.xsd +++ /dev/null @@ -1,3106 +0,0 @@ - - - - - - - - - - - - - - - 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.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.unix.config b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.unix.config deleted file mode 100644 index f35bd45..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.unix.config +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.win.config b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.win.config deleted file mode 100644 index 14d4a10..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Configs/nlog.win.config +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj deleted file mode 100644 index 24ac72d..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - Exe - net5.0 - true - latest - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - Always - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.ini b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.ini deleted file mode 100644 index 75ec140..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.ini +++ /dev/null @@ -1,6 +0,0 @@ -[program:JT808.DotNetty.Hosting] -command=dotnet JT808.DotNetty.Hosting.dll -directory=/data/dotnetty_test -user=root -stdout_logfile=/data/supervisordlog/JT808.DotNetty.Hosting.log -redirect_stderr=true \ No newline at end of file diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Program.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Program.cs deleted file mode 100644 index c80d7d7..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/Program.cs +++ /dev/null @@ -1,80 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Tcp; -using JT808.DotNetty.Udp; -using JT808.DotNetty.WebApi; -using JT808.DotNetty.WebApiClientTool; -using JT808.Protocol; -using JT808.Protocol.Interfaces; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using NLog.Extensions.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading.Tasks; -using JT808.DotNetty.Kafka; - -namespace JT808.DotNetty.Hosting -{ - class Program - { - static async Task Main(string[] args) - { - //7E020000220138123456780085000000010000000101EA2A3F08717931000C015400201901032000020104000000E6F87E - 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(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); - logging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => - { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808NettyCore(hostContext.Configuration) - .AddJT808TcpNettyHost() - .AddJT808UdpNettyHost() - .AddJT808WebApiNettyHost() - //扩展webapi JT808MsgIdHttpHandlerBase - //.ReplaceMsgIdHandler() - .Builder() - //添加kafka插件 - .AddJT808ServerKafkaMsgProducer(hostContext.Configuration) - .AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) - .AddJT808ServerKafkaSessionProducer(hostContext.Configuration) - .Builder(); - //使用微软自带的webapi客户端 - //services.AddHttpClient("jt808webapi", c => - //{ - // c.BaseAddress = new Uri("http://localhost:828/"); - // c.DefaultRequestHeaders.Add("token", "123456); - //}) - //.AddTypedClient(); - //var client = services.BuildServiceProvider().GetRequiredService(); - //var result = client.GetTcpAtomicCounter(); - }); - - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/appsettings.json b/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/appsettings.json deleted file mode 100644 index 62c868b..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Hosting/appsettings.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "Logging": { - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808Configuration": { - "TcpPort": 808, - "UdpPort": 808, - "WebApiPort": 828 - }, - "JT808MsgProducerConfig": { - "TopicName": "JT808Msg", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyProducerConfig": { - "TopicName": "JT808MsgReply", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyConsumerConfig": { - "TopicName": "JT808MsgReply", - "GroupId": "msgreply-group", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808SessionProducerConfig": { - "TopicName": "JT808Session", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808SessionConsumerConfig": { - "TopicName": "JT808Session", - "GroupId": "session-group", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808.DotNetty.Kafka.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808.DotNetty.Kafka.Test.csproj deleted file mode 100644 index 6feac47..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808.DotNetty.Kafka.Test.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net5.0 - - false - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - Always - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808BaseTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808BaseTest.cs deleted file mode 100644 index c71537e..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808BaseTest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808BaseTest - { - public const string BootstrapServers = "172.16.19.120:9092"; - - //public const string BootstrapServers = "192.168.3.11:9092"; - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808Config.json b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808Config.json deleted file mode 100644 index 523adb0..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808Config.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "JT808MsgProducerConfig": { - "TopicName": "JT808Msg", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808Msg", - "GroupId": "msg-group", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyProducerConfig": { - "TopicName": "JT808MsgReply", - "BootstrapServers": "127.0.0.1:9093" - }, - "JT808MsgReplyConsumerConfig": { - "TopicName": "JT808MsgReply", - "GroupId": "msgreply-group", - "BootstrapServers": "127.0.0.1:9093" - }, - "JT808SessionProducerConfig": { - "TopicName": "JT808Session", - "BootstrapServers": "127.0.0.1:9094" - }, - "JT808SessionConsumerConfig": { - "TopicName": "JT808Session", - "GroupId": "session-group", - "BootstrapServers": "127.0.0.1:9094" - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808ConfigTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808ConfigTest.cs deleted file mode 100644 index b76a092..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808ConfigTest.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System; -using System.Collections.Generic; -using System.Text; -using Xunit; -using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Options; -using System.IO; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808ConfigTest - { - [Fact] - public void Test1() - { - var configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.SetBasePath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory)); - configurationBuilder.AddJsonFile("JT808Config.json"); - IConfigurationRoot configurationRoot = configurationBuilder.Build(); - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808MsgProducerConfig")); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808MsgConsumerConfig")); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808MsgReplyProducerConfig")); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808MsgReplyConsumerConfig")); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808SessionProducerConfig")); - serviceDescriptors.Configure(configurationRoot.GetSection("JT808SessionConsumerConfig")); - var serviceProvider = serviceDescriptors.BuildServiceProvider(); - var jT808MsgProducerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808Msg", jT808MsgProducerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9092", jT808MsgProducerConfigAccessor.Value.BootstrapServers); - var jT808MsgConsumerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808Msg", jT808MsgConsumerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9092", jT808MsgConsumerConfigAccessor.Value.BootstrapServers); - Assert.Equal("msg-group", jT808MsgConsumerConfigAccessor.Value.GroupId); - var jT808MsgReplyProducerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808MsgReply", jT808MsgReplyProducerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9093", jT808MsgReplyProducerConfigAccessor.Value.BootstrapServers); - var jT808MsgReplyConsumerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808MsgReply", jT808MsgReplyConsumerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9093", jT808MsgReplyConsumerConfigAccessor.Value.BootstrapServers); - Assert.Equal("msgreply-group", jT808MsgReplyConsumerConfigAccessor.Value.GroupId); - var jT808SessionProducerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808Session", jT808SessionProducerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9094", jT808SessionProducerConfigAccessor.Value.BootstrapServers); - var jT808SessionConsumerConfigAccessor = serviceProvider.GetRequiredService>(); - Assert.Equal("JT808Session", jT808SessionConsumerConfigAccessor.Value.TopicName); - Assert.Equal("127.0.0.1:9094", jT808SessionConsumerConfigAccessor.Value.BootstrapServers); - Assert.Equal("session-group", jT808SessionConsumerConfigAccessor.Value.GroupId); - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgConsumerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgConsumerTest.cs deleted file mode 100644 index b2256a5..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgConsumerTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Threading; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808MsgConsumerTest: JT808BaseTest - { - public JT808MsgConsumerConfig JT808ConsumerConfig = new JT808MsgConsumerConfig - { - GroupId= "JT808Msg.test", - TopicName = "JT808Msg", - BootstrapServers = BootstrapServers - }; - [Fact] - public void Test1() - { - using (IJT808MsgConsumer JT808MsgConsumer = new JT808MsgConsumer(JT808ConsumerConfig, new LoggerFactory())) - { - JT808MsgConsumer.Subscribe(); - JT808MsgConsumer.OnMessage(item => - { - Debug.WriteLine($"{item.TerminalNo}-{item.Data.Length}"); - }); - Thread.Sleep(30000); - JT808MsgConsumer.Unsubscribe(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgProducerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgProducerTest.cs deleted file mode 100644 index 37d0e12..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgProducerTest.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Confluent.Kafka; -using Confluent.Kafka.Admin; -using JT808.DotNetty.Abstractions; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808MsgProducerTest: JT808BaseTest - { - - public JT808MsgProducerConfig JT808ProducerConfig = new JT808MsgProducerConfig - { - TopicName = "JT808Msg", - BootstrapServers = BootstrapServers - }; - - public JT808MsgProducerTest() - { - using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = BootstrapServers }).Build()) - { - try - { - adminClient.DeleteTopicsAsync(new List() { JT808ProducerConfig.TopicName }).Wait(); - } - catch (AggregateException e) - { - //Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - catch (CreateTopicsException e) - { - Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - } - } - - [Fact] - public void Test1() - { - using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(JT808ProducerConfig)) - { - jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); - } - } - - [Fact] - public void Test2() - { - using (IJT808MsgProducer jT808MsgProducer = new JT808MsgProducer(JT808ProducerConfig)) - { - jT808MsgProducer.ProduceAsync("123457", new byte[] { 0x7E, 0, 0x7E }).Wait(); - jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyConsumerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyConsumerTest.cs deleted file mode 100644 index f896957..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyConsumerTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Threading; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808MsgReplyConsumerTest: JT808BaseTest - { - - public JT808MsgReplyConsumerConfig JT808ConsumerConfig = new JT808MsgReplyConsumerConfig - { - GroupId= "jt808.MsgReply.test", - TopicName = "JT808MsgReply", - BootstrapServers = BootstrapServers - }; - [Fact] - public void Test1() - { - using (IJT808MsgReplyConsumer JT808MsgConsumer = new JT808MsgReplyConsumer(JT808ConsumerConfig, new LoggerFactory())) - { - JT808MsgConsumer.Subscribe(); - JT808MsgConsumer.OnMessage(item => - { - Debug.WriteLine($"{item.TerminalNo}-{item.Data.Length}"); - }); - Thread.Sleep(30000); - JT808MsgConsumer.Unsubscribe(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyProducerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyProducerTest.cs deleted file mode 100644 index a6ae040..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808MsgReplyProducerTest.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Confluent.Kafka; -using Confluent.Kafka.Admin; -using JT808.DotNetty.Abstractions; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808MsgReplyProducerTest: JT808BaseTest - { - - public JT808MsgReplyProducerConfig JT808ProducerConfig = new JT808MsgReplyProducerConfig - { - TopicName = "JT808MsgReply", - BootstrapServers = BootstrapServers - }; - - public JT808MsgReplyProducerTest() - { - using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = BootstrapServers }).Build()) - { - try - { - adminClient.DeleteTopicsAsync(new List() { JT808ProducerConfig.TopicName }).Wait(); - } - catch(AggregateException e) - { - //Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - catch (CreateTopicsException e) - { - Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - } - } - - [Fact] - public void Test1() - { - using (IJT808MsgReplyProducer jT808MsgProducer = new JT808MsgReplyProducer(JT808ProducerConfig)) - { - jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); - } - } - - [Fact] - public void Test2() - { - using (IJT808MsgReplyProducer jT808MsgProducer = new JT808MsgReplyProducer(JT808ProducerConfig)) - { - jT808MsgProducer.ProduceAsync("123457", new byte[] { 0x7E, 0, 0x7E }).Wait(); - jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionConsumerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionConsumerTest.cs deleted file mode 100644 index 4b98857..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionConsumerTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -using JT808.DotNetty.Abstractions; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Threading; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808SessionConsumerTest : JT808BaseTest - { - - public JT808SessionConsumerConfig JT808ConsumerConfig = new JT808SessionConsumerConfig - { - GroupId= "JT808Session.test", - TopicName = "JT808Session", - BootstrapServers = BootstrapServers - }; - [Fact] - public void Test1() - { - using (IJT808SessionConsumer JT808MsgConsumer = new JT808SessionConsumer(JT808ConsumerConfig, new LoggerFactory())) - { - JT808MsgConsumer.Subscribe(); - JT808MsgConsumer.OnMessage(item => - { - Debug.WriteLine($"{item.TerminalNo}-{item.Notice}"); - }); - Thread.Sleep(30000); - JT808MsgConsumer.Unsubscribe(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionProducerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionProducerTest.cs deleted file mode 100644 index 2c9bea9..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Kafka.Test/JT808SessionProducerTest.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Confluent.Kafka; -using Confluent.Kafka.Admin; -using JT808.DotNetty.Abstractions; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using Xunit; - -namespace JT808.DotNetty.Kafka.Test -{ - public class JT808SessionProducerTest: JT808BaseTest - { - public JT808SessionProducerConfig JT808ProducerConfig = new JT808SessionProducerConfig - { - TopicName = "JT808Session", - BootstrapServers = BootstrapServers - }; - - public JT808SessionProducerTest() - { - using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = BootstrapServers }).Build()) - { - try - { - adminClient.DeleteTopicsAsync(new List() { JT808ProducerConfig.TopicName }).Wait(); - } - catch (AggregateException e) - { - //Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - catch (CreateTopicsException e) - { - Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); - } - } - } - - [Fact] - public void Test1() - { - using (IJT808SessionProducer jT808MsgProducer = new JT808SessionProducer(JT808ProducerConfig)) - { - jT808MsgProducer.ProduceAsync("online","123456").Wait(); - jT808MsgProducer.ProduceAsync("offline", "123457").Wait(); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/JT808.DotNetty.RabbitMQ.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/JT808.DotNetty.RabbitMQ.Test.csproj deleted file mode 100644 index acf960f..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/JT808.DotNetty.RabbitMQ.Test.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - netcoreapp3.1 - - false - - - - - - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/UnitTest1.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/UnitTest1.cs deleted file mode 100644 index fc2ac69..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.RabbitMQ.Test/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace JT808.DotNetty.RabbitMQ.Test -{ - [TestClass] - public class UnitTest1 - { - //https://www.rabbitmq.com/getstarted.html - [TestMethod] - public void TestMethod1() - { - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj deleted file mode 100644 index d14569c..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net5.0 - - false - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs deleted file mode 100644 index 6b6c19a..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs +++ /dev/null @@ -1,88 +0,0 @@ -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Interfaces; -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.DotNetty.Core.Session; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.Protocol.MessageBody; -using Xunit; -using System.Linq; -using JT808.DotNetty.Core.Codecs; -using DotNetty.Buffers; - -namespace JT808.DotNetty.Tcp.Test -{ - public class JT808SessionServiceTest:TestBase - { - List TNos = new List { - "123456789001", - "123456789002", - "123456789003", - "123456789004", - "123456789005" - }; - - public JT808SessionServiceTest() - { - SeedSession(TNos.ToArray()); - } - - [Fact] - public void GetTcpAllTest() - { - IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); - var result = jT808SessionServiceDefaultImpl.GetTcpAll(); - var tons = result.Data.Select(s => s.TerminalPhoneNo).ToList(); - foreach (var item in TNos) - { - Assert.Contains(item, tons); - } - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void RemoveByTerminalPhoneNoTest() - { - string tno = "123456789006"; - IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); - SeedSession(tno); - var result1 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo(tno); - Assert.Equal(JT808ResultCode.Ok, result1.Code); - Assert.True(result1.Data); - var result2 = jT808SessionServiceDefaultImpl.GetTcpAll(); - Assert.Equal(JT808ResultCode.Ok, result2.Code); - Assert.DoesNotContain(tno, result2.Data.Select(s => s.TerminalPhoneNo)); - } - - [Fact] - public void SendTest() - { - //"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" - var jT808UnificationSendService = ServiceProvider.GetService(); - 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 jt808Result = jT808UnificationSendService.Send(no, data); - Assert.Equal(JT808ResultCode.Ok, jt808Result.Code); - Assert.True(jt808Result.Data); - if (Channels.TryGetValue(no, out var channel)) - { - var package = channel.ReadOutbound(); - byte[] recevie = new byte[package.Capacity]; - package.ReadBytes(recevie); - Assert.Equal(data, recevie); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs deleted file mode 100644 index 8cb5ef1..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs +++ /dev/null @@ -1,69 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs; -using DotNetty.Transport.Channels.Embedded; -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Core.Impls; -using JT808.DotNetty.Core.Metadata; -using JT808.DotNetty.Tcp.Handlers; -using JT808.Protocol; -using JT808.Protocol.Extensions; -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.Text; - -namespace JT808.DotNetty.Tcp.Test -{ - public class TestBase - { - public IServiceProvider ServiceProvider; - public JT808Serializer JT808Serializer; - public TestBase() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - serviceDescriptors.AddJT808Configure() - .AddJT808NettyCore(options => { }) - .Builder(); - serviceDescriptors.AddJT808TcpNettyHostTest(); - ServiceProvider = serviceDescriptors.BuildServiceProvider(); - JT808Serializer = ServiceProvider.GetRequiredService().GetSerializer(); - } - - public EmbeddedChannel CreateEmbeddedChannel() - { - using (var soppe = ServiceProvider.CreateScope()) - { - var handler1 = soppe.ServiceProvider.GetRequiredService(); - var handler2 = soppe.ServiceProvider.GetRequiredService(); - var handler3 = soppe.ServiceProvider.GetRequiredService(); - var ch = new EmbeddedChannel(new JT808DefaultChannelId(), - new DelimiterBasedFrameDecoder(int.MaxValue,Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }),Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag })), - handler1, - handler2, - handler3); - return ch; - } - } - - public Dictionary Channels = new Dictionary(); - - public void SeedSession(params string[] terminalPhoneNos) - { - foreach (var item in terminalPhoneNos) - { - JT808Package jT808Package = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create(item); - var tmp1=JT808Serializer.Serialize(jT808Package); - var ch = CreateEmbeddedChannel(); - ch.WriteInbound(Unpooled.CopiedBuffer(tmp1)); - Channels.Add(item, ch); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj deleted file mode 100644 index cc92586..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net5.0 - false - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs deleted file mode 100644 index 3b564fa..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs +++ /dev/null @@ -1,95 +0,0 @@ -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Interfaces; -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.DotNetty.Core.Session; -using JT808.DotNetty.Abstractions.Dtos; -using Xunit; -using DotNetty.Transport.Channels.Embedded; -using Microsoft.Extensions.Logging; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Udp.Handlers; -using JT808.Protocol.MessageBody; -using System.Linq; -using DotNetty.Transport.Channels.Sockets; -using DotNetty.Buffers; - -namespace JT808.DotNetty.Udp.Test -{ - public class JT808SessionServiceTest:TestBase - { - List TNos = new List { - "123456789001", - "123456789002", - "123456789003", - "123456789004", - "123456789005" - }; - public JT808SessionServiceTest() - { - // 心跳会话包 - JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); - var ch1 = CreateEmbeddedChannel(); - ch1.WriteInbound(JT808Serializer.Serialize(jT808Package1)); - SeedSession(TNos.ToArray()); - } - - [Fact] - public void GetUdpAllTest() - { - IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); - var result = jT808SessionServiceDefaultImpl.GetUdpAll(); - var tons = result.Data.Select(s => s.TerminalPhoneNo).ToList(); - foreach (var item in TNos) - { - Assert.Contains(item, tons); - } - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void RemoveByTerminalPhoneNoTest() - { - string tno = "123456789006"; - IJT808SessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); - SeedSession(tno); - var result1 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo(tno); - Assert.Equal(JT808ResultCode.Ok, result1.Code); - Assert.True(result1.Data); - var result2 = jT808SessionServiceDefaultImpl.GetUdpAll(); - Assert.Equal(JT808ResultCode.Ok, result2.Code); - Assert.DoesNotContain(tno, result2.Data.Select(s=>s.TerminalPhoneNo)); - } - - [Fact] - public void SendTest() - { - //"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" - var jT808UnificationSendService = ServiceProvider.GetService(); - 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 jt808Result = jT808UnificationSendService.Send(no, data); - Assert.Equal(JT808ResultCode.Ok, jt808Result.Code); - Assert.True(jt808Result.Data); - if(Channels.TryGetValue(no,out var channel)) - { - var package = channel.ReadOutbound(); - byte[] recevie = new byte[package.Content.Capacity]; - package.Content.ReadBytes(recevie); - Assert.Equal(data, recevie); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs deleted file mode 100644 index f38e18f..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs +++ /dev/null @@ -1,67 +0,0 @@ -using JT808.DotNetty.Core; -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 DotNetty.Transport.Channels.Embedded; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Udp.Handlers; -using JT808.Protocol.Extensions; -using DotNetty.Transport.Channels.Sockets; -using DotNetty.Buffers; -using System.Net; -using JT808.DotNetty.Core.Impls; - -namespace JT808.DotNetty.Udp.Test -{ - public class TestBase - { - public IServiceProvider ServiceProvider; - public JT808Serializer JT808Serializer; - public TestBase() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - serviceDescriptors.AddJT808Configure() - .AddJT808NettyCore(options => { }) - .Builder(); - serviceDescriptors.AddJT808UdpNettyHostTest(); - ServiceProvider = serviceDescriptors.BuildServiceProvider(); - JT808Serializer = ServiceProvider.GetRequiredService().GetSerializer(); - } - - public EmbeddedChannel CreateEmbeddedChannel() - { - using (var soppe = ServiceProvider.CreateScope()) - { - var handler1 = soppe.ServiceProvider.GetRequiredService(); - var handler2 = soppe.ServiceProvider.GetRequiredService(); - var ch = new EmbeddedChannel(new JT808DefaultChannelId(),handler1, handler2); - return ch; - } - } - - public Dictionary Channels = new Dictionary(); - - public void SeedSession(params string[] terminalPhoneNos) - { - foreach(var item in terminalPhoneNos) - { - JT808Package jT808Package = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create(item); - var ch = CreateEmbeddedChannel(); - DatagramPacket datagramPacket = new DatagramPacket( - Unpooled.CopiedBuffer(JT808Serializer.Serialize(jT808Package)) - , new IPEndPoint(IPAddress.Any, 0) - , new IPEndPoint(IPAddress.Any, 0)); - ch.WriteInbound(datagramPacket); - Channels.Add(item, ch); - } - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Authorization/JT808AuthorizationDefaultTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Authorization/JT808AuthorizationDefaultTest.cs deleted file mode 100644 index 6c36d04..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Authorization/JT808AuthorizationDefaultTest.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using DotNetty.Codecs.Http; -using DotNetty.Common.Utilities; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.WebApi.Authorization; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Xunit; - -namespace JT808.DotNetty.WebApi.Test.Authorization -{ - public class JT808AuthorizationDefaultTest - { - [Fact] - public void AuthorizationQuertStringTest() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.Configure((options)=> { }); - var options=serviceDescriptors.BuildServiceProvider().GetRequiredService>(); - JT808AuthorizationDefault jT808AuthorizationDefault = new JT808AuthorizationDefault(options); - var m = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/demo?token=123456"); - Assert.True(jT808AuthorizationDefault.Authorization(m, out var principal)); - } - - [Fact] - public void AuthorizationQuertStringFailTest() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.Configure((options) => { }); - var options = serviceDescriptors.BuildServiceProvider().GetRequiredService>(); - JT808AuthorizationDefault jT808AuthorizationDefault = new JT808AuthorizationDefault(options); - var m = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/demo?token=12345"); - Assert.False(jT808AuthorizationDefault.Authorization(m, out var principal)); - } - - [Fact] - public void AuthorizationHeaderTest() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.Configure((options) => { }); - var options = serviceDescriptors.BuildServiceProvider().GetRequiredService>(); - JT808AuthorizationDefault jT808AuthorizationDefault = new JT808AuthorizationDefault(options); - var m = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/"); - m.Headers.Add((AsciiString)"token", "123456"); - Assert.True(jT808AuthorizationDefault.Authorization(m, out var principal)); - } - - [Fact] - public void AuthorizationHeaderFailTest() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.Configure((options) => { }); - var options = serviceDescriptors.BuildServiceProvider().GetRequiredService>(); - JT808AuthorizationDefault jT808AuthorizationDefault = new JT808AuthorizationDefault(options); - var m = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/"); - m.Headers.Add((AsciiString)"token", "12345"); - Assert.False(jT808AuthorizationDefault.Authorization(m, out var principal)); - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Handlers/JT808WebAPIServerHandlerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Handlers/JT808WebAPIServerHandlerTest.cs deleted file mode 100644 index 47bfe2e..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/Handlers/JT808WebAPIServerHandlerTest.cs +++ /dev/null @@ -1,211 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs.Http; -using DotNetty.Common.Utilities; -using DotNetty.Transport.Channels.Embedded; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Core.Session; -using JT808.DotNetty.WebApi.Authorization; -using JT808.DotNetty.WebApi.Handlers; -using JT808.Protocol; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; -using System.Text.Json; -using Xunit; -using HttpVersion = DotNetty.Codecs.Http.HttpVersion; - -namespace JT808.DotNetty.WebApi.Test.Handlers -{ - public class JT808WebAPIServerHandlerTest - { - [Fact] - public void SessionTcpGetAllTest() - { - var ch = WebExt.CreateEmbeddedChannel(serviceProvider => { - var sessionMgr = serviceProvider.GetRequiredService(); - sessionMgr.TryAdd("12345678",new EmbeddedChannel()); - }); - ch.WriteInbound(WebExt.CreateGetRequest(JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll)); - var result = ch.As>(); - Assert.Single(result.Data); - Assert.Equal("12345678", result.Data[0].TerminalPhoneNo); - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void GetUdpSessionAllTest() - { - var ch = WebExt.CreateEmbeddedChannel(serviceProvider => { - var sessionMgr=serviceProvider.GetRequiredService(); - sessionMgr.TryAdd(new EmbeddedChannel(),new IPEndPoint(IPAddress.Parse("127.0.0.1"), 888),"123456789"); - }); - ch.WriteInbound(WebExt.CreateGetRequest(JT808NettyConstants.JT808WebApiRouteTable.SessionUdpGetAll)); - var result = ch.As>(); - Assert.Single(result.Data); - Assert.Equal("123456789",result.Data[0].TerminalPhoneNo); - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void RemoveSessionByTerminalPhoneNoTest() - { - var ch = WebExt.CreateEmbeddedChannel(); - ch.WriteInbound(WebExt.CreatePostRequest(JT808NettyConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo,Encoding.UTF8.GetBytes("12345678"))); - var result = ch.As(); - Assert.False(result.Data); - Assert.Equal(JT808ResultCode.Empty, result.Code); - Assert.Equal("Session Empty", result.Message); - } - - [Fact] - public void UnificationSendTest() - { - var ch = WebExt.CreateEmbeddedChannel(); - JT808UnificationSendRequestDto jT808UnificationSendRequestDto = new JT808UnificationSendRequestDto - { - TerminalPhoneNo = "123456789", - Data = new byte[] { 1, 2, 3, 4 } - }; - byte[] content = JsonSerializer.SerializeToUtf8Bytes(jT808UnificationSendRequestDto); - ch.WriteInbound(WebExt.CreatePostRequest(JT808NettyConstants.JT808WebApiRouteTable.UnificationSend, content)); - var result = ch.As(); - Assert.False(result.Data); - Assert.Equal(JT808ResultCode.Ok, result.Code); - Assert.Equal("offline", result.Message); - } - - [Fact] - public void GetTcpAtomicCounterTest() - { - var ch = WebExt.CreateEmbeddedChannel(serviceProvider=> - { - var counterFactory = serviceProvider.GetRequiredService(); - var counter = counterFactory.Create(JT808TransportProtocolType.tcp); - counter.MsgSuccessIncrement(); - counter.MsgSuccessIncrement(); - counter.MsgFailIncrement(); - }); - - ch.WriteInbound(WebExt.CreateGetRequest(JT808NettyConstants.JT808WebApiRouteTable.GetTcpAtomicCounter)); - var result = ch.As(); - Assert.Equal(2,result.Data.MsgSuccessCount); - Assert.Equal(1,result.Data.MsgFailCount); - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void GetUdpAtomicCounterTest() - { - var ch = WebExt.CreateEmbeddedChannel(serviceProvider => - { - var counterFactory = serviceProvider.GetRequiredService(); - var counter = counterFactory.Create(JT808TransportProtocolType.udp); - counter.MsgSuccessIncrement(); - counter.MsgSuccessIncrement(); - counter.MsgSuccessIncrement(); - counter.MsgFailIncrement(); - }); - - ch.WriteInbound(WebExt.CreateGetRequest(JT808NettyConstants.JT808WebApiRouteTable.GetUdpAtomicCounter)); - var result = ch.As(); - Assert.Equal(3, result.Data.MsgSuccessCount); - Assert.Equal(1, result.Data.MsgFailCount); - Assert.Equal(JT808ResultCode.Ok, result.Code); - } - - [Fact] - public void UriTest1() - { - string uri = JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll +"? token=123456"; - var uriSpan = uri.AsSpan(); - var index = uriSpan.IndexOf('?'); - var result = uriSpan.Slice(0, index).ToString(); - Assert.Equal(JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll, result); - } - - [Fact] - public void UriTest2() - { - var index = JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll.IndexOf('?'); - Assert.Equal(-1, index); - } - } - - public static class WebExt - { - public static EmbeddedChannel CreateEmbeddedChannel() - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - serviceDescriptors.AddJT808Configure() - .AddJT808NettyCore(options => { }) - .Builder(); - serviceDescriptors.AddJT808WebApiNettyHostTest(); - var handler = serviceDescriptors.BuildServiceProvider().GetRequiredService(); - var ch = new EmbeddedChannel( - new HttpRequestDecoder(4096, 8192, 8192, false), - new HttpObjectAggregator(int.MaxValue), - handler); - return ch; - } - - public static EmbeddedChannel CreateEmbeddedChannel(Action action) - { - IServiceCollection serviceDescriptors = new ServiceCollection(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - serviceDescriptors.AddJT808Configure() - .AddJT808NettyCore(options => { }) - .Builder(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddSingleton(); - serviceDescriptors.AddScoped(); - var serviceProvider = serviceDescriptors.BuildServiceProvider(); - var handler = serviceProvider.GetRequiredService(); - var ch = new EmbeddedChannel( - new HttpRequestDecoder(4096, 8192, 8192, false), - new HttpObjectAggregator(int.MaxValue), - handler); - action(serviceProvider); - return ch; - } - - public static JT808ResultDto As(this EmbeddedChannel embeddedChannel) - { - if(embeddedChannel == null) return default; - DefaultFullHttpResponse response = embeddedChannel.ReadOutbound(); - if (response.Headers.TryGetInt(HttpHeaderNames.ContentLength, out int length)) - { - byte[] tmp = new byte[length]; - response.Content.ReadBytes(tmp); - response.Release(); - return JsonSerializer.Deserialize>(tmp); - } - response.Release(); - return default; - } - public static DefaultFullHttpRequest CreateGetRequest(string uri) - { - var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, uri); - request.Headers.Add((AsciiString)"token", "123456"); - return request; - } - public static DefaultFullHttpRequest CreatePostRequest(string uri,byte[]content) - { - var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, uri); - request.Headers.Add((AsciiString)"token", "123456"); - request.Content.WriteBytes(content); - return request; - } - } -} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj deleted file mode 100644 index 81fa98a..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netcoreapp3.1 - - false - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808HttpClientTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808HttpClientTest.cs deleted file mode 100644 index b3d8c03..0000000 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808HttpClientTest.cs +++ /dev/null @@ -1,159 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.WebApiClientTool; -using RichardSzalay.MockHttp; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using Xunit; - -namespace JT808.DotNetty.WebApi.Test -{ - public class JT808HttpClientTest - { - public static HttpClient CreateHttpClient(string uri,string requestjson,string responseJson) - { - string baseUrl = "http://localhost"; - var mockHttp = new MockHttpMessageHandler(); - var request = mockHttp.When($"{baseUrl}{uri}") - .Respond("application/json", responseJson); - if (!string.IsNullOrEmpty(requestjson)) - { - request.WithContent(requestjson); - } - var client = mockHttp.ToHttpClient(); - - client.BaseAddress = new Uri(baseUrl); - return client; - } - - [Fact] - public void GetTcpSessionAllTest() - { - JT808ResultDto> jT808ResultDto = new JT808ResultDto>(); - jT808ResultDto.Data = new List(); - jT808ResultDto.Code = 200; - jT808ResultDto.Data.Add(new JT808TcpSessionInfoDto { - LastActiveTime=DateTime.Parse("2019-10-29 23:23:23"), - StartTime=DateTime.Parse("2019-10-29 23:23:23"), - RemoteAddressIP="127.0.0.1:555", - TerminalPhoneNo="123456789" - }); - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll,"", JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.GetTcpSessionAll(); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data[0].TerminalPhoneNo, result.Data[0].TerminalPhoneNo); - Assert.Equal(jT808ResultDto.Data[0].StartTime, result.Data[0].StartTime); - Assert.Equal(jT808ResultDto.Data[0].LastActiveTime, result.Data[0].LastActiveTime); - Assert.Equal(jT808ResultDto.Data[0].RemoteAddressIP, result.Data[0].RemoteAddressIP); - } - - [Fact] - public void GetTcpSessionAllLargeTest() - { - JT808ResultDto> jT808ResultDto = new JT808ResultDto>(); - jT808ResultDto.Data = new List(); - jT808ResultDto.Code = 200; - for(var i = 0; i < 50000; i++) - { - jT808ResultDto.Data.Add(new JT808TcpSessionInfoDto - { - LastActiveTime = DateTime.Parse("2019-10-29 23:23:23"), - StartTime = DateTime.Parse("2019-10-29 23:23:23"), - RemoteAddressIP = "127.0.0.1:555", - TerminalPhoneNo = (i+1).ToString() - }); - } - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll, "", JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.GetTcpSessionAll(); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(50000, result.Data.Count); - } - - [Fact] - public void RemoveSessionByTerminalPhoneNoTest() - { - JT808ResultDto jT808ResultDto = new JT808ResultDto(); - jT808ResultDto.Data = true; - jT808ResultDto.Code = 200; - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo, "123456789", JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.RemoveByTerminalPhoneNo("123456789"); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data, result.Data); - } - - [Fact] - public void UnificationSendTest() - { - JT808ResultDto jT808ResultDto = new JT808ResultDto(); - jT808ResultDto.Data = true; - jT808ResultDto.Code = 200; - JT808UnificationSendRequestDto jT808UnificationSendRequestDto = new JT808UnificationSendRequestDto - { - TerminalPhoneNo = "123456789", - Data = new byte[] { 1, 2, 3, 4 } - }; - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.UnificationSend, JsonSerializer.Serialize(jT808UnificationSendRequestDto), JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.UnificationSend(jT808UnificationSendRequestDto); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data, result.Data); - } - - [Fact] - public void GetTcpAtomicCounterTest() - { - JT808ResultDto jT808ResultDto = new JT808ResultDto(); - jT808ResultDto.Data = new JT808AtomicCounterDto { - MsgFailCount=9, - MsgSuccessCount=10 - }; - jT808ResultDto.Code = 200; - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.GetTcpAtomicCounter, "",JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.GetTcpAtomicCounter(); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data.MsgFailCount, result.Data.MsgFailCount); - Assert.Equal(jT808ResultDto.Data.MsgSuccessCount, result.Data.MsgSuccessCount); - } - - [Fact] - public void GetUdpAtomicCounterTest() - { - JT808ResultDto jT808ResultDto = new JT808ResultDto(); - jT808ResultDto.Data = new JT808AtomicCounterDto - { - MsgFailCount = 19, - MsgSuccessCount = 110 - }; - jT808ResultDto.Code = 200; - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.GetUdpAtomicCounter, "", JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.GetUdpAtomicCounter(); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data.MsgFailCount, result.Data.MsgFailCount); - Assert.Equal(jT808ResultDto.Data.MsgSuccessCount, result.Data.MsgSuccessCount); - } - - [Fact] - public void GetUdpSessionAllTest() - { - JT808ResultDto> jT808ResultDto = new JT808ResultDto>(); - jT808ResultDto.Data = new List(); - jT808ResultDto.Data.Add(new JT808UdpSessionInfoDto - { - LastActiveTime = DateTime.Parse("2019-10-29 21:21:21"), - StartTime = DateTime.Parse("2019-10-29 21:21:21"), - RemoteAddressIP = "127.0.0.1:666", - TerminalPhoneNo = "123456789" - }); - jT808ResultDto.Code = 200; - JT808HttpClient jT808HttpClient = new JT808HttpClient(CreateHttpClient(JT808NettyConstants.JT808WebApiRouteTable.SessionUdpGetAll, "", JsonSerializer.Serialize(jT808ResultDto))); - var result = jT808HttpClient.GetUdpSessionAll(); - Assert.Equal(jT808ResultDto.Code, result.Code); - Assert.Equal(jT808ResultDto.Data[0].TerminalPhoneNo, result.Data[0].TerminalPhoneNo); - Assert.Equal(jT808ResultDto.Data[0].StartTime, result.Data[0].StartTime); - Assert.Equal(jT808ResultDto.Data[0].LastActiveTime, result.Data[0].LastActiveTime); - Assert.Equal(jT808ResultDto.Data[0].RemoteAddressIP, result.Data[0].RemoteAddressIP); - } - } -} diff --git a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs b/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs deleted file mode 100644 index b92932c..0000000 --- a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs +++ /dev/null @@ -1,79 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Transport.Channels; -using JT808.Protocol; -using System; -using Microsoft.Extensions.Logging; -using JT808.DotNetty.Core.Metadata; -using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Session; -using JT808.DotNetty.Abstractions; - -namespace JT808.DotNetty.Udp.Handlers -{ - /// - /// JT808 Udp服务端处理程序 - /// - internal class JT808UdpServerHandler : SimpleChannelInboundHandler - { - private readonly JT808AtomicCounterService jT808AtomicCounterService; - - private readonly ILogger logger; - - private readonly JT808SessionManager jT808UdpSessionManager; - - private readonly JT808Serializer JT808Serializer; - - private readonly IJT808MsgProducer JT808MsgProducer; - - public JT808UdpServerHandler( - IJT808MsgProducer jT808MsgProducer, - IJT808Config jT808Config, - ILoggerFactory loggerFactory, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory, - JT808SessionManager jT808UdpSessionManager) - { - this.JT808MsgProducer = jT808MsgProducer; - this.jT808AtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); - this.jT808UdpSessionManager = jT808UdpSessionManager; - logger = loggerFactory.CreateLogger(); - JT808Serializer = jT808Config.GetSerializer(); - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, JT808UdpPackage msg) - { - try - { - //解析到头部,然后根据具体的消息Id通过队列去进行消费 - //要是一定要解析到数据体可以在JT808MsgIdHandlerBase类中根据具体的消息, - //解析具体的消息体,具体调用JT808Serializer.Deserialize - JT808HeaderPackage jT808HeaderPackage = JT808Serializer.HeaderDeserialize(msg.Buffer); - if (logger.IsEnabled(LogLevel.Trace)) - { - logger.LogTrace($"accept package success count=>{jT808AtomicCounterService.MsgFailCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg.Buffer)}"); - } - jT808AtomicCounterService.MsgSuccessIncrement(); - jT808UdpSessionManager.TryAdd(ctx.Channel, msg.Sender, jT808HeaderPackage.Header.TerminalPhoneNo); - JT808MsgProducer.ProduceAsync(jT808HeaderPackage.Header.TerminalPhoneNo, msg.Buffer); - } - catch (JT808.Protocol.Exceptions.JT808Exception ex) - { - jT808AtomicCounterService.MsgFailIncrement(); - if (logger.IsEnabled(LogLevel.Error)) - { - logger.LogError(ex, $"accept package fail count=>{jT808AtomicCounterService.MsgFailCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg.Buffer)}"); - } - } - catch (Exception ex) - { - jT808AtomicCounterService.MsgFailIncrement(); - if (logger.IsEnabled(LogLevel.Error)) - { - logger.LogError(ex, $"accept package fail count=>{jT808AtomicCounterService.MsgFailCount.ToString()},accept msg=>{ByteBufferUtil.HexDump(msg.Buffer)}"); - } - } - } - - public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush(); - } -} diff --git a/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj b/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj deleted file mode 100644 index dcae4f0..0000000 --- a/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.Udp - JT808.DotNetty.Udp - 基于DotNetty实现的JT808DotNetty的Udp服务 - 基于DotNetty实现的JT808DotNetty的Udp服务 - - - - - - - - - diff --git a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs b/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs deleted file mode 100644 index 459f9d4..0000000 --- a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Core.Impls; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Udp.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("JT808.DotNetty.Udp.Test")] - -namespace JT808.DotNetty.Udp -{ - public static class JT808UdpDotnettyExtensions - { - public static IJT808NettyBuilder AddJT808UdpNettyHost(this IJT808NettyBuilder jT808NettyBuilder) - { - jT808NettyBuilder.JT808Builder.Services.TryAddSingleton(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.AddHostedService(); - return jT808NettyBuilder; - } - - internal static IServiceCollection AddJT808UdpNettyHostTest(this IServiceCollection serviceDescriptors) - { - serviceDescriptors.TryAddSingleton(); - serviceDescriptors.TryAddScoped(); - serviceDescriptors.TryAddScoped(); - return serviceDescriptors; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs b/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs deleted file mode 100644 index 5c3a7eb..0000000 --- a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs +++ /dev/null @@ -1,76 +0,0 @@ -using DotNetty.Transport.Bootstrapping; -using DotNetty.Transport.Channels; -using DotNetty.Transport.Channels.Sockets; -using JT808.DotNetty.Core.Codecs; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.Udp.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Net; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.Udp -{ - /// - /// JT808 Udp网关服务 - /// - internal class JT808UdpServerHost : IHostedService - { - private readonly IServiceProvider serviceProvider; - private readonly JT808Configuration configuration; - private readonly ILogger logger; - private MultithreadEventLoopGroup group; - private IChannel bootstrapChannel; - - public JT808UdpServerHost( - IServiceProvider provider, - ILoggerFactory loggerFactory, - IOptions jT808ConfigurationAccessor) - { - serviceProvider = provider; - configuration = jT808ConfigurationAccessor.Value; - logger=loggerFactory.CreateLogger(); - } - - public Task StartAsync(CancellationToken cancellationToken) - { - group = new MultithreadEventLoopGroup(); - 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.SoBroadcast, true) - .Handler(new ActionChannelInitializer(channel => - { - IChannelPipeline pipeline = channel.Pipeline; - using (var scope = serviceProvider.CreateScope()) - { - pipeline.AddLast("jt808UdpDecoder", scope.ServiceProvider.GetRequiredService()); - pipeline.AddLast("jt808UdpService", scope.ServiceProvider.GetRequiredService()); - } - })); - logger.LogInformation($"JT808 Udp Server start at {IPAddress.Any}:{configuration.UdpPort}."); - return bootstrap.BindAsync(configuration.UdpPort) - .ContinueWith(i => bootstrapChannel = i.Result); - } - - public async Task StopAsync(CancellationToken cancellationToken) - { - await bootstrapChannel.CloseAsync(); - var quietPeriod = configuration.QuietPeriodTimeSpan; - var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan; - await group.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); - } - } -} diff --git a/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.Udp/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.WebApi/Authorization/JT808AuthorizationDefault.cs b/src/JT808.DotNetty.WebApi/Authorization/JT808AuthorizationDefault.cs deleted file mode 100644 index cb319ee..0000000 --- a/src/JT808.DotNetty.WebApi/Authorization/JT808AuthorizationDefault.cs +++ /dev/null @@ -1,51 +0,0 @@ -using DotNetty.Codecs.Http; -using DotNetty.Common.Utilities; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.Core.Interfaces; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Security.Principal; -using System.Text; - -namespace JT808.DotNetty.WebApi.Authorization -{ - class JT808AuthorizationDefault : IJT808WebApiAuthorization - { - private IOptionsMonitor optionsMonitor; - public JT808AuthorizationDefault(IOptionsMonitor optionsMonitor) - { - this.optionsMonitor = optionsMonitor; - } - public bool Authorization(IFullHttpRequest request, out IPrincipal principal) - { - var uriSpan = request.Uri.AsSpan(); - var uriParamStr = uriSpan.Slice(uriSpan.IndexOf('?')+1).ToString().ToLower(); - var uriParams = uriParamStr.Split('&'); - var tokenParam = uriParams.FirstOrDefault(m => m.Contains("token")); - string tokenValue = string.Empty; - if (!string.IsNullOrEmpty(tokenParam)) - { - tokenValue = tokenParam.Split('=')[1]; - } - else - { - if (request.Headers.TryGetAsString((AsciiString)"token", out tokenValue)) - { - } - } - if (optionsMonitor.CurrentValue.WebApiToken == tokenValue) - { - principal = new ClaimsPrincipal(new GenericIdentity(tokenValue)); - return true; - } - else - { - principal = null; - return false; - } - } - } -} diff --git a/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs b/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs deleted file mode 100644 index 93a7426..0000000 --- a/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs +++ /dev/null @@ -1,162 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Dtos; -using JT808.DotNetty.Abstractions.Enums; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Metadata; -using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Internal; -using System.Text.Json; - -namespace JT808.DotNetty.WebApi.Handlers -{ - /// - /// 默认消息处理业务实现 - /// - public class JT808MsgIdDefaultWebApiHandler : JT808MsgIdHttpHandlerBase - { - private readonly JT808AtomicCounterService jT808TcpAtomicCounterService; - - private readonly JT808AtomicCounterService jT808UdpAtomicCounterService; - - private readonly IJT808SessionService jT808SessionService; - - private readonly IJT808UnificationSendService jT808UnificationSendService; - - public JT808MsgIdDefaultWebApiHandler( - IJT808UnificationSendService jT808UnificationSendService, - IJT808SessionService jT808SessionService, - JT808AtomicCounterServiceFactory jT808AtomicCounterServiceFactory - ) - { - this.jT808UnificationSendService = jT808UnificationSendService; - this.jT808SessionService = jT808SessionService; - this.jT808TcpAtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.tcp); - this.jT808UdpAtomicCounterService = jT808AtomicCounterServiceFactory.Create(JT808TransportProtocolType.udp); - InitTcpRoute(); - InitUdpRoute(); - InitCommontRoute(); - } - - /// - /// 会话服务集合 - /// - /// - /// - public JT808HttpResponse GetTcpSessionAll(JT808HttpRequest request) - { - var result = jT808SessionService.GetTcpAll(); - return CreateJT808HttpResponse(result); - } - - /// - /// 通过终端手机号查询对应会话 - /// - /// - /// - public JT808HttpResponse QueryTcpSessionByTerminalPhoneNo(JT808HttpRequest request) - { - if (string.IsNullOrEmpty(request.Json)) - { - return EmptyHttpResponse(); - } - return CreateJT808HttpResponse(jT808SessionService.GetTcpAll()); - } - - /// - /// 会话服务-通过设备终端号移除对应会话 - /// - /// - /// - public JT808HttpResponse RemoveSessionByTerminalPhoneNo(JT808HttpRequest request) - { - if (string.IsNullOrEmpty(request.Json)) - { - return EmptyHttpResponse(); - } - var result = jT808SessionService.RemoveByTerminalPhoneNo(request.Json); - return CreateJT808HttpResponse(result); - } - - /// - /// 会话服务集合 - /// - /// - /// - public JT808HttpResponse GetUdpSessionAll(JT808HttpRequest request) - { - var result = jT808SessionService.GetUdpAll(); - return CreateJT808HttpResponse(result); - } - - /// - /// 获取Tcp包计数器 - /// - /// - /// - public JT808HttpResponse GetTcpAtomicCounter(JT808HttpRequest request) - { - JT808AtomicCounterDto jT808AtomicCounterDto = new JT808AtomicCounterDto(); - jT808AtomicCounterDto.MsgFailCount = jT808TcpAtomicCounterService.MsgFailCount; - jT808AtomicCounterDto.MsgSuccessCount = jT808TcpAtomicCounterService.MsgSuccessCount; - return CreateJT808HttpResponse(new JT808ResultDto - { - Code = JT808ResultCode.Ok, - Data = jT808AtomicCounterDto - }); - } - - /// - /// 获取Udp包计数器 - /// - /// - /// - public JT808HttpResponse GetUdpAtomicCounter(JT808HttpRequest request) - { - JT808AtomicCounterDto jT808AtomicCounterDto = new JT808AtomicCounterDto(); - jT808AtomicCounterDto.MsgFailCount = jT808UdpAtomicCounterService.MsgFailCount; - jT808AtomicCounterDto.MsgSuccessCount = jT808UdpAtomicCounterService.MsgSuccessCount; - return CreateJT808HttpResponse(new JT808ResultDto - { - Code = JT808ResultCode.Ok, - Data = jT808AtomicCounterDto - }); - } - - /// - /// 统一下发信息 - /// - /// - /// - public JT808HttpResponse UnificationSend(JT808HttpRequest request) - { - if (string.IsNullOrEmpty(request.Json)) - { - return EmptyHttpResponse(); - } - - JT808UnificationSendRequestDto jT808UnificationSendRequestDto = JsonSerializer.Deserialize(request.Json); - var result = jT808UnificationSendService.Send(jT808UnificationSendRequestDto.TerminalPhoneNo, jT808UnificationSendRequestDto.Data); - return CreateJT808HttpResponse(result); - } - - protected virtual void InitCommontRoute() - { - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.UnificationSend, UnificationSend); - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo, RemoveSessionByTerminalPhoneNo); - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.QueryTcpSessionByTerminalPhoneNo, QueryTcpSessionByTerminalPhoneNo); - } - - protected virtual void InitTcpRoute() - { - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.GetTcpAtomicCounter, GetTcpAtomicCounter); - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll, GetTcpSessionAll); - } - - protected virtual void InitUdpRoute() - { - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.GetUdpAtomicCounter, GetUdpAtomicCounter); - CreateRoute(JT808NettyConstants.JT808WebApiRouteTable.SessionUdpGetAll, GetUdpSessionAll); - } - } -} diff --git a/src/JT808.DotNetty.WebApi/Handlers/JT808WebAPIServerHandler.cs b/src/JT808.DotNetty.WebApi/Handlers/JT808WebAPIServerHandler.cs deleted file mode 100644 index 46a25fc..0000000 --- a/src/JT808.DotNetty.WebApi/Handlers/JT808WebAPIServerHandler.cs +++ /dev/null @@ -1,98 +0,0 @@ -using DotNetty.Buffers; -using DotNetty.Codecs.Http; -using DotNetty.Common.Utilities; -using DotNetty.Transport.Channels; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.Core.Metadata; -using Microsoft.Extensions.Logging; -using System; -using System.Text; - -namespace JT808.DotNetty.WebApi.Handlers -{ - /// - /// jt808 webapi服务 - /// 请求量不大,只支持JSON格式并且只支持post发数据 - /// ref: dotnetty HttpServer - /// - internal class JT808WebAPIServerHandler : SimpleChannelInboundHandler - { - private static readonly AsciiString TypeJson = AsciiString.Cached("application/json"); - private static readonly AsciiString ServerName = AsciiString.Cached("JT808WebAPINetty"); - private static readonly AsciiString ContentTypeEntity = HttpHeaderNames.ContentType; - private static readonly AsciiString DateEntity = HttpHeaderNames.Date; - private static readonly AsciiString ContentLengthEntity = HttpHeaderNames.ContentLength; - private static readonly AsciiString ServerEntity = HttpHeaderNames.Server; - private readonly JT808MsgIdHttpHandlerBase jT808MsgIdHttpHandlerBase; - private readonly ILogger logger; - private readonly IJT808WebApiAuthorization jT808WebApiAuthorization; - public JT808WebAPIServerHandler( - IJT808WebApiAuthorization jT808WebApiAuthorization, - JT808MsgIdHttpHandlerBase jT808MsgIdHttpHandlerBase, - ILoggerFactory loggerFactory) - { - this.jT808WebApiAuthorization = jT808WebApiAuthorization; - this.jT808MsgIdHttpHandlerBase = jT808MsgIdHttpHandlerBase; - logger = loggerFactory.CreateLogger(); - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg) - { - if (logger.IsEnabled(LogLevel.Debug)) - { - logger.LogDebug($"Uri:{msg.Uri}"); - logger.LogDebug($"Content:{msg.Content.ToString(Encoding.UTF8)}"); - } - JT808HttpResponse jT808HttpResponse = null; - if (!jT808WebApiAuthorization.Authorization(msg, out var principal)) - { - jT808HttpResponse = jT808MsgIdHttpHandlerBase.AuthFailHttpResponse(); - } - else - { - var uriSpan = msg.Uri.AsSpan(); - var index = uriSpan.IndexOf('?'); - string uri = msg.Uri; - if (index > 0) - { - uri = uriSpan.Slice(0, index).ToString(); - } - if (jT808MsgIdHttpHandlerBase.HandlerDict.TryGetValue(uri, out var funcHandler)) - { - jT808HttpResponse = funcHandler(new JT808HttpRequest() { Json = msg.Content.ToString(Encoding.UTF8) }); - } - else - { - jT808HttpResponse = jT808MsgIdHttpHandlerBase.NotFoundHttpResponse(); - } - } - if (jT808HttpResponse != null) - { - WriteResponse(ctx, Unpooled.WrappedBuffer(jT808HttpResponse.Data), TypeJson, jT808HttpResponse.Data.Length); - } - } - - private void WriteResponse(IChannelHandlerContext ctx, IByteBuffer buf, ICharSequence contentType, int contentLength) - { - // Build the response object. - var response = new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK, buf, false); - HttpHeaders headers = response.Headers; - headers.Set(ContentTypeEntity, contentType); - headers.Set(ServerEntity, ServerName); - headers.Set(DateEntity, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); - headers.Set(ContentLengthEntity, contentLength); - // Close the non-keep-alive connection after the write operation is done. - ctx.WriteAndFlushAsync(response); - } - - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) - { - WriteResponse(context, Unpooled.WrappedBuffer(jT808MsgIdHttpHandlerBase.ErrorHttpResponse(exception).Data), TypeJson, jT808MsgIdHttpHandlerBase.ErrorHttpResponse(exception).Data.Length); - logger.LogError(exception, exception.Message); - context.CloseAsync(); - } - - public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush(); - } -} diff --git a/src/JT808.DotNetty.WebApi/JT808.DotNetty.WebApi.csproj b/src/JT808.DotNetty.WebApi/JT808.DotNetty.WebApi.csproj deleted file mode 100644 index 9bf5b95..0000000 --- a/src/JT808.DotNetty.WebApi/JT808.DotNetty.WebApi.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.WebApi - JT808.DotNetty.WebApi - 基于DotNetty实现的JT808DotNetty的WebApi服务 - 基于DotNetty实现的JT808DotNetty的WebApi服务 - - - - - - - - diff --git a/src/JT808.DotNetty.WebApi/JT808WebAPIServerHost.cs b/src/JT808.DotNetty.WebApi/JT808WebAPIServerHost.cs deleted file mode 100644 index 66cd93e..0000000 --- a/src/JT808.DotNetty.WebApi/JT808WebAPIServerHost.cs +++ /dev/null @@ -1,82 +0,0 @@ -using DotNetty.Codecs.Http; -using DotNetty.Transport.Bootstrapping; -using DotNetty.Transport.Channels; -using DotNetty.Transport.Libuv; -using JT808.DotNetty.Core.Configurations; -using JT808.DotNetty.WebApi.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Net; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.WebApi -{ - /// - /// JT808 集成一个webapi服务 - /// - internal class JT808WebAPIServerHost : IHostedService - { - private readonly IServiceProvider serviceProvider; - private readonly JT808Configuration configuration; - private readonly ILogger logger; - private DispatcherEventLoopGroup bossGroup; - private WorkerEventLoopGroup workerGroup; - private IChannel bootstrapChannel; - - public JT808WebAPIServerHost( - IServiceProvider provider, - ILoggerFactory loggerFactory, - IOptions jT808ConfigurationAccessor) - { - serviceProvider = provider; - configuration = jT808ConfigurationAccessor.Value; - logger = loggerFactory.CreateLogger(); - } - - public Task StartAsync(CancellationToken cancellationToken) - { - bossGroup = new DispatcherEventLoopGroup(); - workerGroup = new WorkerEventLoopGroup(bossGroup, 1); - ServerBootstrap bootstrap = new ServerBootstrap(); - bootstrap.Group(bossGroup, workerGroup); - bootstrap.Channel(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) - || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - bootstrap - .Option(ChannelOption.SoReuseport, true) - .ChildOption(ChannelOption.SoReuseaddr, true); - } - bootstrap - .Option(ChannelOption.SoBacklog, 8192) - .ChildHandler(new ActionChannelInitializer(channel => - { - IChannelPipeline pipeline = channel.Pipeline; - using (var scope = serviceProvider.CreateScope()) - { - pipeline.AddLast("http_encoder", new HttpResponseEncoder()); - pipeline.AddLast("http_decoder", new HttpRequestDecoder(4096, 8192, 8192, false)); - //将多个消息转换为单一的request或者response对象 =>IFullHttpRequest - pipeline.AddLast("http_aggregator", new HttpObjectAggregator(int.MaxValue)); - pipeline.AddLast("http_jt808webapihandler", scope.ServiceProvider.GetRequiredService()); - } - })); - logger.LogInformation($"JT808 WebAPI Server start at {IPAddress.Any}:{configuration.WebApiPort}."); - return bootstrap.BindAsync(configuration.WebApiPort).ContinueWith(i => bootstrapChannel = i.Result); - } - - public async Task StopAsync(CancellationToken cancellationToken) - { - await bootstrapChannel.CloseAsync(); - var quietPeriod = configuration.QuietPeriodTimeSpan; - var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan; - await workerGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); - await bossGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); - } - } -} diff --git a/src/JT808.DotNetty.WebApi/JT808WebApiBuilderDefault.cs b/src/JT808.DotNetty.WebApi/JT808WebApiBuilderDefault.cs deleted file mode 100644 index a91a83d..0000000 --- a/src/JT808.DotNetty.WebApi/JT808WebApiBuilderDefault.cs +++ /dev/null @@ -1,37 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System; -using System.Collections.Generic; -using System.Text; - -namespace JT808.DotNetty.WebApi -{ - public class JT808WebApiBuilderDefault : IJT808WebApiNettyBuilder - { - public JT808WebApiBuilderDefault(IJT808NettyBuilder jT808NettyBuilder) { - Instance = jT808NettyBuilder; - } - - public IJT808NettyBuilder Instance { get; } - - public IJT808NettyBuilder Builder() - { - return Instance; - } - - public IJT808WebApiNettyBuilder ReplaceAuthorization() where T : IJT808WebApiAuthorization - { - Instance.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808WebApiAuthorization), typeof(T), ServiceLifetime.Singleton)); - return this; - } - - public IJT808WebApiNettyBuilder ReplaceMsgIdHandler() where T : JT808MsgIdHttpHandlerBase - { - Instance.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHttpHandlerBase), typeof(T), ServiceLifetime.Singleton)); - return this; - } - } -} diff --git a/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs b/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs deleted file mode 100644 index 93096cc..0000000 --- a/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; -using JT808.DotNetty.WebApi.Authorization; -using JT808.DotNetty.WebApi.Handlers; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("JT808.DotNetty.WebApi.Test")] - -namespace JT808.DotNetty.WebApi -{ - public static class JT808WebApiDotnettyExtensions - { - public static IJT808WebApiNettyBuilder AddJT808WebApiNettyHost(this IJT808NettyBuilder jT808NettyBuilder) - { - jT808NettyBuilder.JT808Builder.Services.TryAddSingleton(); - jT808NettyBuilder.JT808Builder.Services.TryAddSingleton(); - jT808NettyBuilder.JT808Builder.Services.TryAddScoped(); - jT808NettyBuilder.JT808Builder.Services.AddHostedService(); - return new JT808WebApiBuilderDefault(jT808NettyBuilder); - } - - internal static IServiceCollection AddJT808WebApiNettyHostTest(this IServiceCollection serviceDescriptors) - { - serviceDescriptors.TryAddSingleton(); - serviceDescriptors.TryAddSingleton(); - serviceDescriptors.TryAddScoped(); - return serviceDescriptors; - } - } -} \ No newline at end of file diff --git a/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.WebApi/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.csproj b/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.csproj deleted file mode 100644 index dc82723..0000000 --- a/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - netstandard2.0;net5; - 9.0 - Copyright 2018. - SmallChi(Koike) - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - false - $(JT808DotNettyPackageVersion) - false - LICENSE - true - JT808.DotNetty.WebApiClientTool - JT808.DotNetty.WebApiClientTool - JT808DotNetty的WebApiClient客户端调用工具 - JT808DotNetty的WebApiClient客户端调用工具 - - - JT808.DotNetty.WebApiClientTool.xml - - - - - - - - - - - - - diff --git a/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.xml b/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.xml deleted file mode 100644 index 2c292e3..0000000 --- a/src/JT808.DotNetty.WebApiClientTool/JT808.DotNetty.WebApiClientTool.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - JT808.DotNetty.WebApiClientTool - - - - - 会话服务集合 - - - - - - 会话服务-通过设备终端号移除对应会话 - - - - - - - 统一下发信息 - - - - - - - 获取Tcp包计数器 - - - - - - 会话服务集合 - - - - - - 获取Udp包计数器 - - - - - diff --git a/src/JT808.DotNetty.WebApiClientTool/JT808HttpClient.cs b/src/JT808.DotNetty.WebApiClientTool/JT808HttpClient.cs deleted file mode 100644 index 804fc27..0000000 --- a/src/JT808.DotNetty.WebApiClientTool/JT808HttpClient.cs +++ /dev/null @@ -1,97 +0,0 @@ -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Abstractions.Dtos; -using System; -using System.Buffers.Text; -using System.Collections.Generic; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; - -namespace JT808.DotNetty.WebApiClientTool -{ - public class JT808HttpClient - { - public HttpClient HttpClient { get; } - public JT808HttpClient(HttpClient httpClient) - { - HttpClient = httpClient; - } - /// - /// 会话服务集合 - /// - /// - public JT808ResultDto> GetTcpSessionAll() - { - var request = new HttpRequestMessage(HttpMethod.Get, JT808NettyConstants.JT808WebApiRouteTable.SessionTcpGetAll); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - /// - /// 会话服务-通过设备终端号移除对应会话 - /// - /// - /// - public JT808ResultDto RemoveByTerminalPhoneNo(string terminalPhoneNo) - { - var request = new HttpRequestMessage(HttpMethod.Post, JT808NettyConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo); - request.Content = new StringContent(terminalPhoneNo); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - /// - /// 统一下发信息 - /// - /// - /// - public JT808ResultDto UnificationSend(JT808UnificationSendRequestDto jT808UnificationSendRequestDto) - { - var request = new HttpRequestMessage(HttpMethod.Post, JT808NettyConstants.JT808WebApiRouteTable.UnificationSend); - request.Content = new StringContent(JsonSerializer.Serialize(jT808UnificationSendRequestDto)); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - /// - /// 获取Tcp包计数器 - /// - /// - public JT808ResultDto GetTcpAtomicCounter() - { - var request = new HttpRequestMessage(HttpMethod.Get, JT808NettyConstants.JT808WebApiRouteTable.GetTcpAtomicCounter); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - /// - /// 会话服务集合 - /// - /// - public JT808ResultDto> GetUdpSessionAll() - { - var request = new HttpRequestMessage(HttpMethod.Get, JT808NettyConstants.JT808WebApiRouteTable.SessionUdpGetAll); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - /// - /// 获取Udp包计数器 - /// - /// - public JT808ResultDto GetUdpAtomicCounter() - { - var request = new HttpRequestMessage(HttpMethod.Get, JT808NettyConstants.JT808WebApiRouteTable.GetUdpAtomicCounter); - var response = HttpClient.SendAsync(request).Result; - response.EnsureSuccessStatusCode(); - var value = JsonSerializer.Deserialize>(response.Content.ReadAsByteArrayAsync().Result); - return value; - } - } -} diff --git a/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml b/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index e572661..0000000 --- a/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - FileSystem - Release - Any CPU - netstandard2.0 - ..\..\nupkgs - - \ No newline at end of file diff --git a/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml.user b/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 312c6e3..0000000 --- a/src/JT808.DotNetty.WebApiClientTool/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.sln b/src/JT808.DotNetty.sln deleted file mode 100644 index f8bdb21..0000000 --- a/src/JT808.DotNetty.sln +++ /dev/null @@ -1,205 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28922.388 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Udp", "JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj", "{C960084C-2CF4-4748-AD35-D2384285D6A3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Core", "JT808.DotNetty.Core\JT808.DotNetty.Core.csproj", "{67C5DC72-0004-48B3-BB5A-9CB7069B4F02}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Abstractions", "JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj", "{4DCF33C0-67C5-4179-AF1E-4E919F9F856D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3BD7FF02-8516-4A77-A385-9FDCDD792E22}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Tcp", "JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj", "{330CD783-5564-4083-ABFC-573CDC369F50}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.WebApi", "JT808.DotNetty.WebApi\JT808.DotNetty.WebApi.csproj", "{B783DE53-CE2A-4225-921F-04E5E57B28F3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Core.Test", "JT808.DotNetty.Tests\JT808.DotNetty.Core.Test\JT808.DotNetty.Core.Test.csproj", "{1C4CCE9B-761B-4581-B5DA-5B6D83572D56}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Tcp.Test", "JT808.DotNetty.Tests\JT808.DotNetty.Tcp.Test\JT808.DotNetty.Tcp.Test.csproj", "{AEF1E1E2-C861-4268-86F6-6F376FAF79A7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Udp.Test", "JT808.DotNetty.Tests\JT808.DotNetty.Udp.Test\JT808.DotNetty.Udp.Test.csproj", "{E503BFD8-D90A-4610-97C7-5B9A0497303B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Hosting", "JT808.DotNetty.Tests\JT808.DotNetty.Hosting\JT808.DotNetty.Hosting.csproj", "{A0F2F006-5AEB-454E-83C5-ABFB58DE17A9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.WebApiClientTool", "JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj", "{9D86C951-94F2-4CBD-B177-8AF31DDB05D8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Client", "JT808.DotNetty.Client\JT808.DotNetty.Client.csproj", "{87C08239-C57F-4FC5-9579-05D0723AA4A0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.CleintBenchmark", "JT808.DotNetty.CleintBenchmark\JT808.DotNetty.CleintBenchmark.csproj", "{C2B1A0F4-2C49-45DA-9F48-7A016FC6E9E1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Kafka", "JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj", "{576A8394-AA60-4DAE-864B-D4BBB67B8E75}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Kafka.Test", "JT808.DotNetty.Tests\JT808.DotNetty.Kafka.Test\JT808.DotNetty.Kafka.Test.csproj", "{50A94BD5-5CDF-4777-AE4C-80BA769AEDAB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{7F077BD5-8E4C-402A-9E24-DECAF251A420}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Transmit", "JT808.DotNetty.Services\JT808.DotNetty.Transmit\JT808.DotNetty.Transmit.csproj", "{0E2326F8-4C96-446B-9B91-285635870171}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.ReplyMessage.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.ReplyMessage.Test\JT808.DotNetty.ReplyMessage.Test.csproj", "{4C01B160-543B-4659-B99C-B9C774B3DEE9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Traffic.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.Traffic.Test\JT808.DotNetty.Traffic.Test.csproj", "{24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SessionNotice.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.SessionNotice.Test\JT808.DotNetty.SessionNotice.Test.csproj", "{81DE821F-0780-44B4-B02D-72998ECA6BD2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Transmit.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.Transmit.Test\JT808.DotNetty.Transmit.Test.csproj", "{EE5EF8D4-8B61-4706-81BB-412F643E8F51}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.MsgLogging.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.MsgLogging.Test\JT808.DotNetty.MsgLogging.Test.csproj", "{591D7974-9AF5-41E2-9B3C-B271EE682943}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.MsgIdHandler.Test", "JT808.DotNetty.Services.Tests\JT808.DotNetty.MsgIdHandler.Test\JT808.DotNetty.MsgIdHandler.Test.csproj", "{B5C872E6-4187-479A-B3BA-CCE76A225DE9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.MsgIdHandler", "JT808.DotNetty.Services\JT808.DotNetty.MsgIdHandler\JT808.DotNetty.MsgIdHandler.csproj", "{081E805B-CDB7-48AB-89D7-136D94A9A413}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.MsgLogging", "JT808.DotNetty.Services\JT808.DotNetty.MsgLogging\JT808.DotNetty.MsgLogging.csproj", "{8F84D633-DE73-4267-B05F-06740B9C1EA6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.ReplyMessage", "JT808.DotNetty.Services\JT808.DotNetty.ReplyMessage\JT808.DotNetty.ReplyMessage.csproj", "{DDB299EC-6817-495F-8CF0-FBB9408AF6A4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SessionNotice", "JT808.DotNetty.Services\JT808.DotNetty.SessionNotice\JT808.DotNetty.SessionNotice.csproj", "{A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Traffic", "JT808.DotNetty.Services\JT808.DotNetty.Traffic\JT808.DotNetty.Traffic.csproj", "{60B5BD57-1529-4D06-8FAD-0C6427AAF3CA}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.WebApi.Test", "JT808.DotNetty.Tests\JT808.DotNetty.WebApi.Test\JT808.DotNetty.WebApi.Test.csproj", "{864A21E9-39F1-4B6C-9F95-3347454A7198}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C960084C-2CF4-4748-AD35-D2384285D6A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C960084C-2CF4-4748-AD35-D2384285D6A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C960084C-2CF4-4748-AD35-D2384285D6A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C960084C-2CF4-4748-AD35-D2384285D6A3}.Release|Any CPU.Build.0 = Release|Any CPU - {67C5DC72-0004-48B3-BB5A-9CB7069B4F02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67C5DC72-0004-48B3-BB5A-9CB7069B4F02}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67C5DC72-0004-48B3-BB5A-9CB7069B4F02}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67C5DC72-0004-48B3-BB5A-9CB7069B4F02}.Release|Any CPU.Build.0 = Release|Any CPU - {4DCF33C0-67C5-4179-AF1E-4E919F9F856D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4DCF33C0-67C5-4179-AF1E-4E919F9F856D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4DCF33C0-67C5-4179-AF1E-4E919F9F856D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4DCF33C0-67C5-4179-AF1E-4E919F9F856D}.Release|Any CPU.Build.0 = Release|Any CPU - {330CD783-5564-4083-ABFC-573CDC369F50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {330CD783-5564-4083-ABFC-573CDC369F50}.Debug|Any CPU.Build.0 = Debug|Any CPU - {330CD783-5564-4083-ABFC-573CDC369F50}.Release|Any CPU.ActiveCfg = Release|Any CPU - {330CD783-5564-4083-ABFC-573CDC369F50}.Release|Any CPU.Build.0 = Release|Any CPU - {B783DE53-CE2A-4225-921F-04E5E57B28F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B783DE53-CE2A-4225-921F-04E5E57B28F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B783DE53-CE2A-4225-921F-04E5E57B28F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B783DE53-CE2A-4225-921F-04E5E57B28F3}.Release|Any CPU.Build.0 = Release|Any CPU - {1C4CCE9B-761B-4581-B5DA-5B6D83572D56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C4CCE9B-761B-4581-B5DA-5B6D83572D56}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C4CCE9B-761B-4581-B5DA-5B6D83572D56}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C4CCE9B-761B-4581-B5DA-5B6D83572D56}.Release|Any CPU.Build.0 = Release|Any CPU - {AEF1E1E2-C861-4268-86F6-6F376FAF79A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AEF1E1E2-C861-4268-86F6-6F376FAF79A7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AEF1E1E2-C861-4268-86F6-6F376FAF79A7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AEF1E1E2-C861-4268-86F6-6F376FAF79A7}.Release|Any CPU.Build.0 = Release|Any CPU - {E503BFD8-D90A-4610-97C7-5B9A0497303B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E503BFD8-D90A-4610-97C7-5B9A0497303B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E503BFD8-D90A-4610-97C7-5B9A0497303B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E503BFD8-D90A-4610-97C7-5B9A0497303B}.Release|Any CPU.Build.0 = Release|Any CPU - {A0F2F006-5AEB-454E-83C5-ABFB58DE17A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0F2F006-5AEB-454E-83C5-ABFB58DE17A9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0F2F006-5AEB-454E-83C5-ABFB58DE17A9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0F2F006-5AEB-454E-83C5-ABFB58DE17A9}.Release|Any CPU.Build.0 = Release|Any CPU - {9D86C951-94F2-4CBD-B177-8AF31DDB05D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D86C951-94F2-4CBD-B177-8AF31DDB05D8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D86C951-94F2-4CBD-B177-8AF31DDB05D8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D86C951-94F2-4CBD-B177-8AF31DDB05D8}.Release|Any CPU.Build.0 = Release|Any CPU - {87C08239-C57F-4FC5-9579-05D0723AA4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {87C08239-C57F-4FC5-9579-05D0723AA4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {87C08239-C57F-4FC5-9579-05D0723AA4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {87C08239-C57F-4FC5-9579-05D0723AA4A0}.Release|Any CPU.Build.0 = Release|Any CPU - {C2B1A0F4-2C49-45DA-9F48-7A016FC6E9E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C2B1A0F4-2C49-45DA-9F48-7A016FC6E9E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C2B1A0F4-2C49-45DA-9F48-7A016FC6E9E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C2B1A0F4-2C49-45DA-9F48-7A016FC6E9E1}.Release|Any CPU.Build.0 = Release|Any CPU - {576A8394-AA60-4DAE-864B-D4BBB67B8E75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {576A8394-AA60-4DAE-864B-D4BBB67B8E75}.Debug|Any CPU.Build.0 = Debug|Any CPU - {576A8394-AA60-4DAE-864B-D4BBB67B8E75}.Release|Any CPU.ActiveCfg = Release|Any CPU - {576A8394-AA60-4DAE-864B-D4BBB67B8E75}.Release|Any CPU.Build.0 = Release|Any CPU - {50A94BD5-5CDF-4777-AE4C-80BA769AEDAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50A94BD5-5CDF-4777-AE4C-80BA769AEDAB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50A94BD5-5CDF-4777-AE4C-80BA769AEDAB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50A94BD5-5CDF-4777-AE4C-80BA769AEDAB}.Release|Any CPU.Build.0 = Release|Any CPU - {0E2326F8-4C96-446B-9B91-285635870171}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0E2326F8-4C96-446B-9B91-285635870171}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0E2326F8-4C96-446B-9B91-285635870171}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0E2326F8-4C96-446B-9B91-285635870171}.Release|Any CPU.Build.0 = Release|Any CPU - {4C01B160-543B-4659-B99C-B9C774B3DEE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4C01B160-543B-4659-B99C-B9C774B3DEE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4C01B160-543B-4659-B99C-B9C774B3DEE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4C01B160-543B-4659-B99C-B9C774B3DEE9}.Release|Any CPU.Build.0 = Release|Any CPU - {24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB}.Release|Any CPU.Build.0 = Release|Any CPU - {81DE821F-0780-44B4-B02D-72998ECA6BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {81DE821F-0780-44B4-B02D-72998ECA6BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {81DE821F-0780-44B4-B02D-72998ECA6BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {81DE821F-0780-44B4-B02D-72998ECA6BD2}.Release|Any CPU.Build.0 = Release|Any CPU - {EE5EF8D4-8B61-4706-81BB-412F643E8F51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EE5EF8D4-8B61-4706-81BB-412F643E8F51}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EE5EF8D4-8B61-4706-81BB-412F643E8F51}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EE5EF8D4-8B61-4706-81BB-412F643E8F51}.Release|Any CPU.Build.0 = Release|Any CPU - {591D7974-9AF5-41E2-9B3C-B271EE682943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {591D7974-9AF5-41E2-9B3C-B271EE682943}.Debug|Any CPU.Build.0 = Debug|Any CPU - {591D7974-9AF5-41E2-9B3C-B271EE682943}.Release|Any CPU.ActiveCfg = Release|Any CPU - {591D7974-9AF5-41E2-9B3C-B271EE682943}.Release|Any CPU.Build.0 = Release|Any CPU - {B5C872E6-4187-479A-B3BA-CCE76A225DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B5C872E6-4187-479A-B3BA-CCE76A225DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B5C872E6-4187-479A-B3BA-CCE76A225DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B5C872E6-4187-479A-B3BA-CCE76A225DE9}.Release|Any CPU.Build.0 = Release|Any CPU - {081E805B-CDB7-48AB-89D7-136D94A9A413}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {081E805B-CDB7-48AB-89D7-136D94A9A413}.Debug|Any CPU.Build.0 = Debug|Any CPU - {081E805B-CDB7-48AB-89D7-136D94A9A413}.Release|Any CPU.ActiveCfg = Release|Any CPU - {081E805B-CDB7-48AB-89D7-136D94A9A413}.Release|Any CPU.Build.0 = Release|Any CPU - {8F84D633-DE73-4267-B05F-06740B9C1EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8F84D633-DE73-4267-B05F-06740B9C1EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8F84D633-DE73-4267-B05F-06740B9C1EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8F84D633-DE73-4267-B05F-06740B9C1EA6}.Release|Any CPU.Build.0 = Release|Any CPU - {DDB299EC-6817-495F-8CF0-FBB9408AF6A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDB299EC-6817-495F-8CF0-FBB9408AF6A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDB299EC-6817-495F-8CF0-FBB9408AF6A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DDB299EC-6817-495F-8CF0-FBB9408AF6A4}.Release|Any CPU.Build.0 = Release|Any CPU - {A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A}.Release|Any CPU.Build.0 = Release|Any CPU - {60B5BD57-1529-4D06-8FAD-0C6427AAF3CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60B5BD57-1529-4D06-8FAD-0C6427AAF3CA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60B5BD57-1529-4D06-8FAD-0C6427AAF3CA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60B5BD57-1529-4D06-8FAD-0C6427AAF3CA}.Release|Any CPU.Build.0 = Release|Any CPU - {864A21E9-39F1-4B6C-9F95-3347454A7198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {864A21E9-39F1-4B6C-9F95-3347454A7198}.Debug|Any CPU.Build.0 = Debug|Any CPU - {864A21E9-39F1-4B6C-9F95-3347454A7198}.Release|Any CPU.ActiveCfg = Release|Any CPU - {864A21E9-39F1-4B6C-9F95-3347454A7198}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1C4CCE9B-761B-4581-B5DA-5B6D83572D56} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {AEF1E1E2-C861-4268-86F6-6F376FAF79A7} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {E503BFD8-D90A-4610-97C7-5B9A0497303B} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {A0F2F006-5AEB-454E-83C5-ABFB58DE17A9} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {50A94BD5-5CDF-4777-AE4C-80BA769AEDAB} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {0E2326F8-4C96-446B-9B91-285635870171} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {4C01B160-543B-4659-B99C-B9C774B3DEE9} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {24E3A6DD-0BC4-4EDA-AC40-B07371BB5FDB} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {81DE821F-0780-44B4-B02D-72998ECA6BD2} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {EE5EF8D4-8B61-4706-81BB-412F643E8F51} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {591D7974-9AF5-41E2-9B3C-B271EE682943} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {B5C872E6-4187-479A-B3BA-CCE76A225DE9} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {081E805B-CDB7-48AB-89D7-136D94A9A413} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {8F84D633-DE73-4267-B05F-06740B9C1EA6} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {DDB299EC-6817-495F-8CF0-FBB9408AF6A4} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {A30A0671-FC46-4BEC-A6F9-DC2400CA7F3A} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {60B5BD57-1529-4D06-8FAD-0C6427AAF3CA} = {7F077BD5-8E4C-402A-9E24-DECAF251A420} - {864A21E9-39F1-4B6C-9F95-3347454A7198} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {FC0FFCEA-E1EF-4C97-A1C5-F89418B6834B} - EndGlobalSection -EndGlobal diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/DataTransferOptions.cs b/src/JT808.Gateway.Abstractions/Configurations/DataTransferOptions.cs similarity index 80% rename from src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/DataTransferOptions.cs rename to src/JT808.Gateway.Abstractions/Configurations/DataTransferOptions.cs index a591f66..3bf6a86 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/DataTransferOptions.cs +++ b/src/JT808.Gateway.Abstractions/Configurations/DataTransferOptions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.Transmit.Configs +namespace JT808.Gateway.Abstractions.Configurations { public class DataTransferOptions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/RemoteServerOptions.cs b/src/JT808.Gateway.Abstractions/Configurations/RemoteServerOptions.cs similarity index 78% rename from src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/RemoteServerOptions.cs rename to src/JT808.Gateway.Abstractions/Configurations/RemoteServerOptions.cs index 2d4541a..765425d 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/Configs/RemoteServerOptions.cs +++ b/src/JT808.Gateway.Abstractions/Configurations/RemoteServerOptions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.Transmit.Configs +namespace JT808.Gateway.Abstractions.Configurations { public class RemoteServerOptions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingType.cs b/src/JT808.Gateway.Abstractions/Enums/JT808MsgLoggingType.cs similarity index 87% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingType.cs rename to src/JT808.Gateway.Abstractions/Enums/JT808MsgLoggingType.cs index 9c2ad11..b4a8cb2 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingType.cs +++ b/src/JT808.Gateway.Abstractions/Enums/JT808MsgLoggingType.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.MsgLogging +namespace JT808.Gateway.Abstractions.Enums { public enum JT808MsgLoggingType { diff --git a/src/JT808.Gateway.Abstractions/IJT808ClientBuilder.cs b/src/JT808.Gateway.Abstractions/IJT808ClientBuilder.cs index 9574094..0b76634 100644 --- a/src/JT808.Gateway.Abstractions/IJT808ClientBuilder.cs +++ b/src/JT808.Gateway.Abstractions/IJT808ClientBuilder.cs @@ -1,4 +1,5 @@ using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -8,7 +9,7 @@ namespace JT808.Gateway.Abstractions { public interface IJT808ClientBuilder { - IJT808Builder JT808Builder { get; } - IJT808Builder Builder(); + IJT808DIBuilder JT808Builder { get; } + IJT808DIBuilder Builder(); } } diff --git a/src/JT808.Gateway.Abstractions/IJT808GatewayBuilder.cs b/src/JT808.Gateway.Abstractions/IJT808GatewayBuilder.cs index 72f6bbd..3c92991 100644 --- a/src/JT808.Gateway.Abstractions/IJT808GatewayBuilder.cs +++ b/src/JT808.Gateway.Abstractions/IJT808GatewayBuilder.cs @@ -1,4 +1,5 @@ using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -8,7 +9,7 @@ namespace JT808.Gateway.Abstractions { public interface IJT808GatewayBuilder { - IJT808Builder JT808Builder { get; } - IJT808Builder Builder(); + IJT808DIBuilder JT808Builder { get; } + IJT808DIBuilder Builder(); } } diff --git a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/IJT808MsgLogging.cs b/src/JT808.Gateway.Abstractions/IJT808MsgLogging.cs similarity index 77% rename from src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/IJT808MsgLogging.cs rename to src/JT808.Gateway.Abstractions/IJT808MsgLogging.cs index 948836e..5a96a35 100644 --- a/src/JT808.DotNetty.Services/JT808.DotNetty.MsgLogging/IJT808MsgLogging.cs +++ b/src/JT808.Gateway.Abstractions/IJT808MsgLogging.cs @@ -1,9 +1,10 @@ -using System; +using JT808.Gateway.Abstractions.Enums; +using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; -namespace JT808.DotNetty.MsgLogging +namespace JT808.Gateway.Abstractions { /// /// 808数据上下行日志接口 diff --git a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj index b69a484..ec2acfd 100644 --- a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj +++ b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.csproj @@ -16,9 +16,10 @@ - + + - + diff --git a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.xml b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.xml index 7c9da0a..832de62 100644 --- a/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.xml +++ b/src/JT808.Gateway.Abstractions/JT808.Gateway.Abstractions.xml @@ -115,6 +115,16 @@ 统一下发请求参数 + + + 数据上行 + + + + + 数据下行 + + 传输协议类型 @@ -162,6 +172,11 @@ 808 hex 应答消息数据 + + + 808数据上下行日志接口 + + diff --git a/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj b/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj index df491b1..e6b6ec0 100644 --- a/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj +++ b/src/JT808.Gateway.Benchmark/JT808.Gateway.CleintBenchmark/JT808.Gateway.CleintBenchmark.csproj @@ -19,8 +19,8 @@ - - + + diff --git a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj index be7b47a..add755b 100644 --- a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj +++ b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/JT808.Gateway.ServerBenchmark.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/Program.cs b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/Program.cs index ea66a2f..31fc2e4 100644 --- a/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/Program.cs +++ b/src/JT808.Gateway.Benchmark/JT808.Gateway.ServerBenchmark/Program.cs @@ -29,8 +29,6 @@ namespace JT808.Gateway.ServerBenchmark }) .ConfigureServices((hostContext, services) => { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); services.AddJT808Configure() .AddGateway(hostContext.Configuration) .AddTcp() diff --git a/src/JT808.Gateway.Client/IJT808ClientBuilder.cs b/src/JT808.Gateway.Client/IJT808ClientBuilder.cs index 319a361..a2ddf13 100644 --- a/src/JT808.Gateway.Client/IJT808ClientBuilder.cs +++ b/src/JT808.Gateway.Client/IJT808ClientBuilder.cs @@ -1,4 +1,5 @@ using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -8,7 +9,7 @@ namespace JT808.Gateway.Client { public interface IJT808ClientBuilder { - IJT808Builder JT808Builder { get; } - IJT808Builder Builder(); + IJT808DIBuilder JT808Builder { get; } + IJT808DIBuilder Builder(); } } diff --git a/src/JT808.Gateway.Client/Internal/JT808ClientBuilderDefault.cs b/src/JT808.Gateway.Client/Internal/JT808ClientBuilderDefault.cs index 54b26d0..4fefdbc 100644 --- a/src/JT808.Gateway.Client/Internal/JT808ClientBuilderDefault.cs +++ b/src/JT808.Gateway.Client/Internal/JT808ClientBuilderDefault.cs @@ -1,4 +1,5 @@ using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System; @@ -9,14 +10,14 @@ namespace JT808.Gateway.Client { internal class JT808ClientBuilderDefault : IJT808ClientBuilder { - public IJT808Builder JT808Builder { get; } + public IJT808DIBuilder JT808Builder { get; } - public JT808ClientBuilderDefault(IJT808Builder builder) + public JT808ClientBuilderDefault(IJT808DIBuilder builder) { JT808Builder = builder; } - public IJT808Builder Builder() + public IJT808DIBuilder Builder() { return JT808Builder; } diff --git a/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj b/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj index bc82b84..24ae0e6 100644 --- a/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj +++ b/src/JT808.Gateway.Client/JT808.Gateway.Client.csproj @@ -10,7 +10,8 @@ - + + diff --git a/src/JT808.Gateway.Client/JT808ClientExtensions.cs b/src/JT808.Gateway.Client/JT808ClientExtensions.cs index 4fbecb3..614300f 100644 --- a/src/JT808.Gateway.Client/JT808ClientExtensions.cs +++ b/src/JT808.Gateway.Client/JT808ClientExtensions.cs @@ -7,12 +7,13 @@ using Microsoft.Extensions.Configuration; using JT808.Gateway.Client.Services; using Microsoft.Extensions.DependencyInjection.Extensions; using JT808.Gateway.Client.Internal; +using JT808.Protocol.DependencyInjection; namespace JT808.Gateway.Client { public static class JT808ClientExtensions { - public static IJT808ClientBuilder AddClient(this IJT808Builder jT808Builder) + public static IJT808ClientBuilder AddClient(this IJT808DIBuilder jT808Builder) { JT808ClientBuilderDefault jT808ClientBuilderDefault = new JT808ClientBuilderDefault(jT808Builder); jT808ClientBuilderDefault.JT808Builder.Services.AddSingleton(); diff --git a/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj b/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj index 41339f7..8616aa3 100644 --- a/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj +++ b/src/JT808.Gateway.Kafka/JT808.Gateway.Kafka.csproj @@ -8,7 +8,7 @@ JT808.Gateway.Kafka.xml - + diff --git a/src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs b/src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs index d34e239..f929d1b 100644 --- a/src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs +++ b/src/JT808.Gateway.Kafka/JT808ClientBuilderDefault.cs @@ -1,5 +1,6 @@ using JT808.Gateway.Abstractions; using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System; @@ -10,14 +11,14 @@ namespace JT808.Gateway.Kafka { internal class JT808ClientBuilderDefault : IJT808ClientBuilder { - public IJT808Builder JT808Builder { get; } + public IJT808DIBuilder JT808Builder { get; } - public JT808ClientBuilderDefault(IJT808Builder builder) + public JT808ClientBuilderDefault(IJT808DIBuilder builder) { JT808Builder = builder; } - public IJT808Builder Builder() + public IJT808DIBuilder Builder() { return JT808Builder; } diff --git a/src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs b/src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs index 412bb6f..505a072 100644 --- a/src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs +++ b/src/JT808.Gateway.Kafka/JT808ClientKafkaExtensions.cs @@ -5,12 +5,13 @@ using JT808.Protocol; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using JT808.Protocol.DependencyInjection; namespace JT808.Gateway.Kafka { public static class JT808ClientKafkaExtensions { - public static IJT808ClientBuilder AddClientKafka(this IJT808Builder builder) + public static IJT808ClientBuilder AddClientKafka(this IJT808DIBuilder builder) { return new JT808ClientBuilderDefault(builder); } diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808.Gateway.MsgIdHandler.csproj b/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808.Gateway.MsgIdHandler.csproj deleted file mode 100644 index 9ede09c..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808.Gateway.MsgIdHandler.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - JT808.Gateway.MsgIdHandler - JT808.Gateway.MsgIdHandler - 基于JT808消息业务处理程序服务 - 基于JT808消息业务处理程序服务 - LICENSE - - - - - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/IJT808MsgLogging.cs b/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/IJT808MsgLogging.cs deleted file mode 100644 index 6f2d5e9..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/IJT808MsgLogging.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace JT808.Gateway.MsgLogging -{ - /// - /// 808数据上下行日志接口 - /// - public interface IJT808MsgLogging - { - void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType); - } -} diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj b/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj deleted file mode 100644 index ba94a91..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - - JT808.Gateway.MsgLogging - JT808.Gateway.MsgLogging - 基于JT808消息上下行日志服务 - 基于JT808消息上下行日志服务 - LICENSE - JT808.Gateway.MsgLogging.xml - - - - - - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.xml b/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.xml deleted file mode 100644 index 1a364fe..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808.Gateway.MsgLogging.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - JT808.Gateway.MsgLogging - - - - - 808数据上下行日志接口 - - - - - 数据上行 - - - - - 数据下行 - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj b/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj deleted file mode 100644 index f367e6d..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - JT808.Gateway.ReplyMessage - JT808.Gateway.ReplyMessage - 基于JT808消息业务处理程序服务 - 基于JT808消息业务处理程序服务 - LICENSE - JT808.Gateway.ReplyMessage.xml - - - - - - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.xml b/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.xml deleted file mode 100644 index 67a013d..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808.Gateway.ReplyMessage.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - JT808.Gateway.ReplyMessage - - - - - 消息应答服务扩展 - - - - - 消息下行服务 - - - - - - - - - - - - - - - - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj b/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj deleted file mode 100644 index c048e40..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - - JT808.Gateway.SessionNotice - JT808.Gateway.SessionNotice - 基于JT808会话通知服务 - 基于JT808会话通知服务 - LICENSE - JT808.Gateway.SessionNotice.xml - - - - - - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.xml b/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.xml deleted file mode 100644 index 425470e..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808.Gateway.SessionNotice.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - JT808.Gateway.SessionNotice - - - - - 会话通知服务 - - - - - - - 消息会话通知服务 - - 自定义会话通知服务 - - - - - - 会话通知服务 - - - - - - - 消息会话通知服务 - - 自定义会话通知服务 - - - - - diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj b/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj deleted file mode 100644 index e20d151..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - JT808.Gateway.Transmit - JT808.Gateway.Transmit - 基于JT808实现的数据转发服务 - 基于JT808实现的数据转发服务 - LICENSE - JT808.Gateway.Transmit.xml - - - - - - - - - \ No newline at end of file diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.xml b/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.xml deleted file mode 100644 index 09a84a7..0000000 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808.Gateway.Transmit.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - JT808.Gateway.Transmit - - - - - 转发服务(不同的消费者实例) - - - - - - - - 转发服务(不同的消费者实例) - - - - - - - - 初始化远程服务器 - - - - - - - - 动态删除远程服务器 - - - - - - 动态添加远程服务器 - - - - - - diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808CustomMessageHandlerImpl.cs b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808CustomMessageHandlerImpl.cs index 62495e6..da3634e 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808CustomMessageHandlerImpl.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808CustomMessageHandlerImpl.cs @@ -1,7 +1,7 @@ using JT808.Gateway.Abstractions; using JT808.Gateway.Abstractions.Configurations; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.Transmit; +using JT808.Gateway.Abstractions.Enums; +using JT808.Gateway.Services; using JT808.Protocol; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808MsgLogging.cs b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808MsgLogging.cs index 79f5c91..78a95b0 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808MsgLogging.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Impl/JT808MsgLogging.cs @@ -1,4 +1,5 @@ -using JT808.Gateway.MsgLogging; +using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Enums; using JT808.Protocol.Extensions; using Microsoft.Extensions.Logging; using System; @@ -16,7 +17,10 @@ namespace JT808.Gateway.NormalHosting.Impl } public void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType) { - Logger.LogDebug($"{jT808MsgLoggingType.ToString()}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); + if(Logger.IsEnabled(LogLevel.Debug)) + { + Logger.LogDebug($"{jT808MsgLoggingType.ToString()}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); + } } } } diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj index 04f9a26..b93680b 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/JT808.Gateway.NormalHosting.csproj @@ -24,16 +24,13 @@ - - - + + + - - - diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs index d29a9b2..483e479 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs @@ -7,21 +7,14 @@ using JT808.Protocol; using Microsoft.Extensions.Configuration; using NLog.Extensions.Logging; using JT808.Gateway.NormalHosting.Impl; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.Transmit; using JT808.Gateway.NormalHosting.Services; using JT808.Gateway.Abstractions; -using JT808.Gateway.SessionNotice; using JT808.Gateway.Client; using JT808.Gateway.NormalHosting.Jobs; using JT808.Gateway.WebApiClientTool; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Server; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration.Json; using JT808.Gateway.Abstractions.Configurations; -using System.Net; using JT808.Gateway.Extensions; using JT808.Gateway.NormalHosting.Customs; @@ -34,20 +27,13 @@ namespace JT808.Gateway.NormalHosting //ref:https://andrewlock.net/exploring-dotnet-6-part-2-comparing-webapplicationbuilder-to-the-generic-host/ //the new hotness in .NET 6. var builder = WebApplication.CreateBuilder(); - builder.Host.ConfigureAppConfiguration((hostingContext, config) => - { - config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddJsonFile($"appsettings.{ hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); - }) - .ConfigureLogging((context, logging) => - { - Console.WriteLine($"Environment.OSVersion.Platform:{Environment.OSVersion.Platform.ToString()}"); - NLog.LogManager.LoadConfiguration($"Configs/nlog.{Environment.OSVersion.Platform.ToString()}.config"); - logging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); - logging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => + builder.Configuration.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true); + Console.WriteLine($"Environment.OSVersion.Platform:{Environment.OSVersion.Platform.ToString()}"); + NLog.LogManager.LoadConfiguration($"Configs/nlog.{Environment.OSVersion.Platform.ToString()}.config"); + builder.Logging.SetMinimumLevel(LogLevel.Trace); + builder.Host.ConfigureServices((hostContext, services) => { //使用内存队列实现会话通知 services.AddSingleton(); diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Impl/JT808CustomMessageHandlerImpl.cs b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Impl/JT808CustomMessageHandlerImpl.cs index 11ad5ee..2a99705 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Impl/JT808CustomMessageHandlerImpl.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Impl/JT808CustomMessageHandlerImpl.cs @@ -1,7 +1,4 @@ using JT808.Gateway.Abstractions; -using JT808.Gateway.Abstractions.Configurations; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.Transmit; using JT808.Protocol; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj index 16918a6..7a82e04 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/JT808.Gateway.QueueHosting.csproj @@ -11,19 +11,14 @@ - - - + + + - - - - - diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs index f635636..858da20 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.QueueHosting/Program.cs @@ -3,23 +3,18 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using JT808.Protocol; using Microsoft.Extensions.Configuration; using NLog.Extensions.Logging; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.ReplyMessage; -using JT808.Gateway.Transmit; -using JT808.Gateway.Abstractions; -using JT808.Gateway.SessionNotice; using JT808.Gateway.Client; using JT808.Gateway.QueueHosting.Jobs; using JT808.Gateway.Kafka; using JT808.Gateway.WebApiClientTool; using JT808.Gateway.QueueHosting.Impl; -using JT808.Gateway.MsgIdHandler; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using JT808.Gateway.Abstractions.Configurations; +using JT808.Protocol; +using JT808.Gateway.Extensions; namespace JT808.Gateway.QueueHosting { @@ -44,8 +39,7 @@ namespace JT808.Gateway.QueueHosting }) .ConfigureServices((hostContext, services) => { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.AddJT808Configure() //添加客户端工具 .AddClient() diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj b/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj index 40e3605..c24921d 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj +++ b/src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj @@ -9,7 +9,7 @@ - + all diff --git a/src/JT808.Gateway.Tests/JT808.Gateway.Test/Session/JT808SessionManagerTest.cs b/src/JT808.Gateway.Tests/JT808.Gateway.Test/Session/JT808SessionManagerTest.cs index 99d4560..4c11724 100644 --- a/src/JT808.Gateway.Tests/JT808.Gateway.Test/Session/JT808SessionManagerTest.cs +++ b/src/JT808.Gateway.Tests/JT808.Gateway.Test/Session/JT808SessionManagerTest.cs @@ -5,6 +5,9 @@ using System.Text; using Xunit; using Microsoft.Extensions.Logging; using System.Net.Sockets; +using System.Threading; +using System.Diagnostics; +using System.Threading.Tasks; namespace JT808.Gateway.Test.Session { @@ -32,6 +35,21 @@ namespace JT808.Gateway.Test.Session Assert.True(jT808SessionManager.TerminalPhoneNoSessions.ContainsKey(tno)); } + [Fact] + public void PerfSession1M() + { + //Random.Shared.Next(0,1000000) + int number = 1000000; + JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); + Parallel.For(0, number, (i) => + { + string tno = i.ToString(); + var session = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); + var result1 = jT808SessionManager.TryAdd(session); + jT808SessionManager.TryLink(tno, session); + }); + } + /// /// 用于转发过来的车辆 /// diff --git a/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml b/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml index 3240afa..912463c 100644 --- a/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml +++ b/src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml @@ -121,7 +121,7 @@ - + @@ -129,7 +129,7 @@ - + @@ -155,7 +155,7 @@ - + @@ -163,7 +163,7 @@ - + diff --git a/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs b/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs index c07ff70..19ed5d4 100644 --- a/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs +++ b/src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs @@ -1,5 +1,6 @@ using JT808.Gateway.Abstractions; using JT808.Protocol; +using JT808.Protocol.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; @@ -60,7 +61,7 @@ namespace JT808.Gateway.WebApiClientTool /// /// /// - public static IJT808Builder AddWebApiClientTool(this IJT808Builder jT808Builder, IConfiguration configuration) + public static IJT808DIBuilder AddWebApiClientTool(this IJT808DIBuilder jT808Builder, IConfiguration configuration) { jT808Builder.Services.AddHttpClient("JT808WebApiClientTool", c => { @@ -80,7 +81,7 @@ namespace JT808.Gateway.WebApiClientTool /// /// /// - public static IJT808Builder AddWebApiClientTool(this IJT808Builder jT808Builder, Uri webapiUri, string token) + public static IJT808DIBuilder AddWebApiClientTool(this IJT808DIBuilder jT808Builder, Uri webapiUri, string token) { jT808Builder.Services.AddHttpClient("JT808WebApiClientTool", c => { @@ -140,7 +141,7 @@ namespace JT808.Gateway.WebApiClientTool /// /// /// - public static IJT808Builder AddWebApiClientTool(this IJT808Builder jT808Builder, IConfiguration configuration) + public static IJT808DIBuilder AddWebApiClientTool(this IJT808DIBuilder jT808Builder, IConfiguration configuration) where TJT808HttpClient : JT808HttpClient { jT808Builder.Services.AddHttpClient("JT808WebApiClientToolExt", c => @@ -161,7 +162,7 @@ namespace JT808.Gateway.WebApiClientTool /// /// /// - public static IJT808Builder AddWebApiClientTool(this IJT808Builder jT808Builder, Uri webapiUri, string token) + public static IJT808DIBuilder AddWebApiClientTool(this IJT808DIBuilder jT808Builder, Uri webapiUri, string token) where TJT808HttpClient: JT808HttpClient { jT808Builder.Services.AddHttpClient("JT808WebApiClientToolExt", c => diff --git a/src/JT808.Gateway.sln b/src/JT808.Gateway.sln index ab5a8ea..746f76d 100644 --- a/src/JT808.Gateway.sln +++ b/src/JT808.Gateway.sln @@ -9,14 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Abstractions" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Kafka", "JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj", "{274C048E-A8E3-4422-A578-A10A97DF36F2}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{3EF8490D-C993-49D8-8A3D-493B7F259D70}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.MsgLogging", "JT808.Gateway.Services\JT808.Gateway.MsgLogging\JT808.Gateway.MsgLogging.csproj", "{A242A839-4F00-4434-A7E8-7E3BEBA5B75C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.SessionNotice", "JT808.Gateway.Services\JT808.Gateway.SessionNotice\JT808.Gateway.SessionNotice.csproj", "{1CB84599-5F56-4461-A451-DF16E3854AB9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Transmit", "JT808.Gateway.Services\JT808.Gateway.Transmit\JT808.Gateway.Transmit.csproj", "{598E445A-AF2E-42F0-98F4-18EC22E473FC}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.Client", "JT808.Gateway.Client\JT808.Gateway.Client.csproj", "{AC3070AC-A938-4213-A562-C079BB4A3F9E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{7CBAACEE-19BF-499A-8C41-36A1324D45E9}" @@ -31,18 +23,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmark", "Benchmark", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.WebApiClientTool", "JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj", "{479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ReplyMessage", "JT808.Gateway.Services\JT808.Gateway.ReplyMessage\JT808.Gateway.ReplyMessage.csproj", "{886D0A3F-C974-442B-9820-F1C4C04EAAB6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.ServerBenchmark", "JT808.Gateway.Benchmark\JT808.Gateway.ServerBenchmark\JT808.Gateway.ServerBenchmark.csproj", "{8B32DDBF-F118-4216-A49A-C067F6107D0A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.CleintBenchmark", "JT808.Gateway.Benchmark\JT808.Gateway.CleintBenchmark\JT808.Gateway.CleintBenchmark.csproj", "{45113CCF-2556-459F-B330-D0A5A885FC4C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Gateway.MsgIdHandler", "JT808.Gateway.Services\JT808.Gateway.MsgIdHandler\JT808.Gateway.MsgIdHandler.csproj", "{41E5252C-CA52-453A-BBFE-CBCB58D232ED}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2336747A-28A3-443E-8E23-4B25E3F2D971}" ProjectSection(SolutionItems) = preProject PipelineInfo.props = PipelineInfo.props - ..\api\README_Pipeline.md = ..\api\README_Pipeline.md + ..\README.md = ..\README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "api", "api", "{FFEDF975-4F2A-47CA-9003-A02382894C5B}" + ProjectSection(SolutionItems) = preProject + ..\api\README.md = ..\api\README.md EndProjectSection EndProject Global @@ -63,18 +56,6 @@ Global {274C048E-A8E3-4422-A578-A10A97DF36F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {274C048E-A8E3-4422-A578-A10A97DF36F2}.Release|Any CPU.ActiveCfg = Release|Any CPU {274C048E-A8E3-4422-A578-A10A97DF36F2}.Release|Any CPU.Build.0 = Release|Any CPU - {A242A839-4F00-4434-A7E8-7E3BEBA5B75C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A242A839-4F00-4434-A7E8-7E3BEBA5B75C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A242A839-4F00-4434-A7E8-7E3BEBA5B75C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A242A839-4F00-4434-A7E8-7E3BEBA5B75C}.Release|Any CPU.Build.0 = Release|Any CPU - {1CB84599-5F56-4461-A451-DF16E3854AB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CB84599-5F56-4461-A451-DF16E3854AB9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CB84599-5F56-4461-A451-DF16E3854AB9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CB84599-5F56-4461-A451-DF16E3854AB9}.Release|Any CPU.Build.0 = Release|Any CPU - {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {598E445A-AF2E-42F0-98F4-18EC22E473FC}.Release|Any CPU.Build.0 = Release|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU {AC3070AC-A938-4213-A562-C079BB4A3F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -95,10 +76,6 @@ Global {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Release|Any CPU.ActiveCfg = Release|Any CPU {479DFD02-4777-4DC2-9E2E-8EA33BFB36C9}.Release|Any CPU.Build.0 = Release|Any CPU - {886D0A3F-C974-442B-9820-F1C4C04EAAB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {886D0A3F-C974-442B-9820-F1C4C04EAAB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {886D0A3F-C974-442B-9820-F1C4C04EAAB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {886D0A3F-C974-442B-9820-F1C4C04EAAB6}.Release|Any CPU.Build.0 = Release|Any CPU {8B32DDBF-F118-4216-A49A-C067F6107D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8B32DDBF-F118-4216-A49A-C067F6107D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B32DDBF-F118-4216-A49A-C067F6107D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -107,25 +84,17 @@ Global {45113CCF-2556-459F-B330-D0A5A885FC4C}.Debug|Any CPU.Build.0 = Debug|Any CPU {45113CCF-2556-459F-B330-D0A5A885FC4C}.Release|Any CPU.ActiveCfg = Release|Any CPU {45113CCF-2556-459F-B330-D0A5A885FC4C}.Release|Any CPU.Build.0 = Release|Any CPU - {41E5252C-CA52-453A-BBFE-CBCB58D232ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41E5252C-CA52-453A-BBFE-CBCB58D232ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41E5252C-CA52-453A-BBFE-CBCB58D232ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41E5252C-CA52-453A-BBFE-CBCB58D232ED}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {A242A839-4F00-4434-A7E8-7E3BEBA5B75C} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} - {1CB84599-5F56-4461-A451-DF16E3854AB9} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} - {598E445A-AF2E-42F0-98F4-18EC22E473FC} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} {E3DC260E-0B55-4993-B051-402E44D4E883} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} {22368AAD-A1F3-446B-B68F-98A0933BF1F6} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} {52D895BD-C60B-42D8-9229-C85927546FDA} = {7CBAACEE-19BF-499A-8C41-36A1324D45E9} - {886D0A3F-C974-442B-9820-F1C4C04EAAB6} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} {8B32DDBF-F118-4216-A49A-C067F6107D0A} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} {45113CCF-2556-459F-B330-D0A5A885FC4C} = {6FAEC008-93CB-4730-8C58-D31FFD342C4F} - {41E5252C-CA52-453A-BBFE-CBCB58D232ED} = {3EF8490D-C993-49D8-8A3D-493B7F259D70} + {FFEDF975-4F2A-47CA-9003-A02382894C5B} = {2336747A-28A3-443E-8E23-4B25E3F2D971} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AA9303A7-6FB3-4572-88AA-3302E85330D1} diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerExtensions.cs b/src/JT808.Gateway/Extensions/JT808MsgIdHandlerExtensions.cs similarity index 90% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerExtensions.cs rename to src/JT808.Gateway/Extensions/JT808MsgIdHandlerExtensions.cs index 1492a4e..99b0d8f 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerExtensions.cs +++ b/src/JT808.Gateway/Extensions/JT808MsgIdHandlerExtensions.cs @@ -1,10 +1,11 @@ using JT808.Gateway.Abstractions; +using JT808.Gateway.HostedServices; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.MsgIdHandler +namespace JT808.Gateway.Extensions { public static class JT808MsgIdHandlerExtensions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingExtensions.cs b/src/JT808.Gateway/Extensions/JT808MsgLoggingExtensions.cs similarity index 94% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingExtensions.cs rename to src/JT808.Gateway/Extensions/JT808MsgLoggingExtensions.cs index a5068a7..231e527 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgLoggingExtensions.cs +++ b/src/JT808.Gateway/Extensions/JT808MsgLoggingExtensions.cs @@ -1,10 +1,11 @@ using JT808.Gateway.Abstractions; +using JT808.Gateway.HostedServices; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.MsgLogging +namespace JT808.Gateway.Extensions { public static class JT808MsgLoggingExtensions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageExtensions.cs b/src/JT808.Gateway/Extensions/JT808ReplyMessageExtensions.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageExtensions.cs rename to src/JT808.Gateway/Extensions/JT808ReplyMessageExtensions.cs index a2fb0e3..eb53157 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageExtensions.cs +++ b/src/JT808.Gateway/Extensions/JT808ReplyMessageExtensions.cs @@ -1,12 +1,13 @@  using JT808.Gateway.Abstractions; +using JT808.Gateway.HostedServices; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System; using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.ReplyMessage +namespace JT808.Gateway.Extensions { /// /// 消息应答服务扩展 diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeExtensions.cs b/src/JT808.Gateway/Extensions/JT808SessionNoticeExtensions.cs similarity index 96% rename from src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeExtensions.cs rename to src/JT808.Gateway/Extensions/JT808SessionNoticeExtensions.cs index 5b6682d..9dd18ad 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeExtensions.cs +++ b/src/JT808.Gateway/Extensions/JT808SessionNoticeExtensions.cs @@ -1,11 +1,13 @@  using JT808.Gateway.Abstractions; +using JT808.Gateway.HostedServices; +using JT808.Gateway.Services; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; -namespace JT808.Gateway.SessionNotice +namespace JT808.Gateway.Extensions { public static class JT808SessionNoticeExtensions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitExtensions.cs b/src/JT808.Gateway/Extensions/JT808TransmitExtensions.cs similarity index 91% rename from src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitExtensions.cs rename to src/JT808.Gateway/Extensions/JT808TransmitExtensions.cs index bd47827..a767a25 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitExtensions.cs +++ b/src/JT808.Gateway/Extensions/JT808TransmitExtensions.cs @@ -5,9 +5,11 @@ using System.Text; using JT808.Protocol; using Microsoft.Extensions.Configuration; using JT808.Gateway.Abstractions; -using JT808.Gateway.Transmit.Configs; +using JT808.Gateway.Abstractions.Configurations; +using JT808.Gateway.Services; +using JT808.Gateway.HostedServices; -namespace JT808.Gateway.Transmit +namespace JT808.Gateway.Extensions { public static class JT808TransmitExtensions { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownLoggingHostedService.cs b/src/JT808.Gateway/HostedServices/JT808MsgDownLoggingHostedService.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownLoggingHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808MsgDownLoggingHostedService.cs index c32b51a..d477200 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownLoggingHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808MsgDownLoggingHostedService.cs @@ -2,8 +2,9 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Enums; -namespace JT808.Gateway.MsgLogging +namespace JT808.Gateway.HostedServices { public class JT808MsgDownLoggingHostedService : IHostedService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownReplyLoggingHostedService.cs b/src/JT808.Gateway/HostedServices/JT808MsgDownReplyLoggingHostedService.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownReplyLoggingHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808MsgDownReplyLoggingHostedService.cs index 0aa2ed9..6a06c94 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgDownReplyLoggingHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808MsgDownReplyLoggingHostedService.cs @@ -2,8 +2,9 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Enums; -namespace JT808.Gateway.MsgLogging +namespace JT808.Gateway.HostedServices { public class JT808MsgDownReplyLoggingHostedService : IHostedService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerHostedService.cs b/src/JT808.Gateway/HostedServices/JT808MsgIdHandlerHostedService.cs similarity index 96% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808MsgIdHandlerHostedService.cs index 295ee46..9b5b9d5 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgIdHandler/JT808MsgIdHandlerHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808MsgIdHandlerHostedService.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; -namespace JT808.Gateway.MsgIdHandler +namespace JT808.Gateway.HostedServices { public class JT808MsgIdHandlerHostedService : IHostedService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgUpLoggingHostedService.cs b/src/JT808.Gateway/HostedServices/JT808MsgUpLoggingHostedService.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgUpLoggingHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808MsgUpLoggingHostedService.cs index ec75324..f6c40c5 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.MsgLogging/JT808MsgUpLoggingHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808MsgUpLoggingHostedService.cs @@ -2,8 +2,9 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Enums; -namespace JT808.Gateway.MsgLogging +namespace JT808.Gateway.HostedServices { public class JT808MsgUpLoggingHostedService : IHostedService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageHostedService.cs b/src/JT808.Gateway/HostedServices/JT808ReplyMessageHostedService.cs similarity index 98% rename from src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808ReplyMessageHostedService.cs index 1e5aee4..9ddb9bc 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.ReplyMessage/JT808ReplyMessageHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808ReplyMessageHostedService.cs @@ -4,7 +4,7 @@ using System.Threading; using JT808.Gateway.Abstractions; using Microsoft.Extensions.Logging; -namespace JT808.Gateway.ReplyMessage +namespace JT808.Gateway.HostedServices { /// /// diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeHostedService.cs b/src/JT808.Gateway/HostedServices/JT808SessionNoticeHostedService.cs similarity index 94% rename from src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808SessionNoticeHostedService.cs index fcfcbd3..8bd2473 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808SessionNoticeHostedService.cs @@ -2,8 +2,9 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; +using JT808.Gateway.Services; -namespace JT808.Gateway.SessionNotice +namespace JT808.Gateway.HostedServices { public class JT808SessionNoticeHostedService : IHostedService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitHostedService.cs b/src/JT808.Gateway/HostedServices/JT808TransmitHostedService.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitHostedService.cs rename to src/JT808.Gateway/HostedServices/JT808TransmitHostedService.cs index 8b243fb..27ede5f 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitHostedService.cs +++ b/src/JT808.Gateway/HostedServices/JT808TransmitHostedService.cs @@ -2,8 +2,9 @@ using Microsoft.Extensions.Hosting; using System.Threading; using JT808.Gateway.Abstractions; +using JT808.Gateway.Services; -namespace JT808.Gateway.Transmit +namespace JT808.Gateway.HostedServices { public class JT808TransmitHostedService:IHostedService { diff --git a/src/JT808.Gateway/Internal/JT808GatewayBuilderDefault.cs b/src/JT808.Gateway/Internal/JT808GatewayBuilderDefault.cs index 1ef7110..76723e9 100644 --- a/src/JT808.Gateway/Internal/JT808GatewayBuilderDefault.cs +++ b/src/JT808.Gateway/Internal/JT808GatewayBuilderDefault.cs @@ -1,18 +1,19 @@ using JT808.Gateway.Abstractions; using JT808.Protocol; +using JT808.Protocol.DependencyInjection; namespace JT808.Gateway.Internal { public class JT808GatewayBuilderDefault : IJT808GatewayBuilder { - public IJT808Builder JT808Builder { get; } + public IJT808DIBuilder JT808Builder { get; } - public JT808GatewayBuilderDefault(IJT808Builder builder) + public JT808GatewayBuilderDefault(IJT808DIBuilder builder) { JT808Builder = builder; } - public IJT808Builder Builder() + public IJT808DIBuilder Builder() { return JT808Builder; } diff --git a/src/JT808.Gateway/JT808.Gateway.csproj b/src/JT808.Gateway/JT808.Gateway.csproj index a323d1d..847801c 100644 --- a/src/JT808.Gateway/JT808.Gateway.csproj +++ b/src/JT808.Gateway/JT808.Gateway.csproj @@ -1,4 +1,4 @@ - + 基于Pipeline实现的JT808Gateway的网络库 @@ -6,8 +6,7 @@ JT808.Gateway.xml JT808.Gateway JT808.Gateway - Library - true + true @@ -16,6 +15,7 @@ + diff --git a/src/JT808.Gateway/JT808.Gateway.xml b/src/JT808.Gateway/JT808.Gateway.xml index 821451f..94fe8e0 100644 --- a/src/JT808.Gateway/JT808.Gateway.xml +++ b/src/JT808.Gateway/JT808.Gateway.xml @@ -15,12 +15,84 @@ + + + 消息应答服务扩展 + + + + + 消息下行服务 + + + + + + + 会话通知服务 + + + + + + + 消息会话通知服务 + + 自定义会话通知服务 + + + + + + 会话通知服务 + + + + + + + 消息会话通知服务 + + 自定义会话通知服务 + + + + + + 转发服务(不同的消费者实例) + + + + + + + + 转发服务(不同的消费者实例) + + + + + + + + + + + + + + + + + + + JT808网关注册扩展 - + 添加808网关 @@ -28,7 +100,7 @@ - + 添加808网关 @@ -250,6 +322,40 @@ + + + + + + + + + + + + + + + + + + + 初始化远程服务器 + + + + + + 动态删除远程服务器 + + + + + + 动态添加远程服务器 + + + diff --git a/src/JT808.Gateway/JT808GatewayExtensions.cs b/src/JT808.Gateway/JT808GatewayExtensions.cs index c685871..780b26c 100644 --- a/src/JT808.Gateway/JT808GatewayExtensions.cs +++ b/src/JT808.Gateway/JT808GatewayExtensions.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using System; using System.Runtime.CompilerServices; using System.Linq; +using JT808.Protocol.DependencyInjection; [assembly: InternalsVisibleTo("JT808.Gateway.TestHosting")] [assembly: InternalsVisibleTo("JT808.Gateway.Test")] @@ -27,7 +28,7 @@ namespace JT808.Gateway /// /// /// - public static IJT808GatewayBuilder AddGateway(this IJT808Builder jT808Builder, Action config) + public static IJT808GatewayBuilder AddGateway(this IJT808DIBuilder jT808Builder, Action config) { JT808GatewayBuilderDefault jT808GatewayBuilderDefault = new JT808GatewayBuilderDefault(jT808Builder); jT808GatewayBuilderDefault.JT808Builder.Services.Configure(config); @@ -40,7 +41,7 @@ namespace JT808.Gateway /// /// /// - public static IJT808GatewayBuilder AddGateway(this IJT808Builder jT808Builder, IConfiguration configuration) + public static IJT808GatewayBuilder AddGateway(this IJT808DIBuilder jT808Builder, IConfiguration configuration) { JT808GatewayBuilderDefault jT808GatewayBuilderDefault = new JT808GatewayBuilderDefault(jT808Builder); jT808GatewayBuilderDefault.JT808Builder.Services.Configure(configuration.GetSection("JT808Configuration")); diff --git a/src/JT808.Gateway/JT808TcpServer.cs b/src/JT808.Gateway/JT808TcpServer.cs index 8f6ecda..b6cea50 100644 --- a/src/JT808.Gateway/JT808TcpServer.cs +++ b/src/JT808.Gateway/JT808TcpServer.cs @@ -234,7 +234,7 @@ namespace JT808.Gateway # if DEBUG Interlocked.Increment(ref MessageReceiveCounter); if (Logger.IsEnabled(LogLevel.Trace)) - Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()},Counter:{MessageReceiveCounter}"); + Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{package.Header.TerminalPhoneNo}]:{package.OriginalData.ToHexString()},Counter:{MessageReceiveCounter}"); #else if (Logger.IsEnabled(LogLevel.Trace)) Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()}"); diff --git a/src/JT808.Gateway/JT808UdpServer.cs b/src/JT808.Gateway/JT808UdpServer.cs index f00344c..7338c36 100644 --- a/src/JT808.Gateway/JT808UdpServer.cs +++ b/src/JT808.Gateway/JT808UdpServer.cs @@ -100,7 +100,7 @@ namespace JT808.Gateway { try { - var package = Serializer.HeaderDeserialize(buffer, minBufferSize: 10240); + var package = Serializer.HeaderDeserialize(buffer, minBufferSize: 4096); if (Logger.IsEnabled(LogLevel.Trace)) Logger.LogTrace($"[Accept Hex {receiveMessageFromResult.RemoteEndPoint}]:{package.OriginalData.ToHexString()}"); var session = SessionManager.TryLink(package.Header.TerminalPhoneNo, socket, receiveMessageFromResult.RemoteEndPoint); if (Logger.IsEnabled(LogLevel.Information)) diff --git a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeService.cs b/src/JT808.Gateway/Services/JT808SessionNoticeService.cs similarity index 93% rename from src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeService.cs rename to src/JT808.Gateway/Services/JT808SessionNoticeService.cs index a3d9735..2fbea38 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.SessionNotice/JT808SessionNoticeService.cs +++ b/src/JT808.Gateway/Services/JT808SessionNoticeService.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Logging; -namespace JT808.Gateway.SessionNotice +namespace JT808.Gateway.Services { public class JT808SessionNoticeService { diff --git a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitService.cs b/src/JT808.Gateway/Services/JT808TransmitService.cs similarity index 97% rename from src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitService.cs rename to src/JT808.Gateway/Services/JT808TransmitService.cs index fed580e..8a5ac8e 100644 --- a/src/JT808.Gateway.Services/JT808.Gateway.Transmit/JT808TransmitService.cs +++ b/src/JT808.Gateway/Services/JT808TransmitService.cs @@ -5,12 +5,12 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Linq; -using JT808.Gateway.Transmit.Configs; using System.Net.Sockets; using System.Collections.Concurrent; using System.Threading; +using JT808.Gateway.Abstractions.Configurations; -namespace JT808.Gateway.Transmit +namespace JT808.Gateway.Services { public class JT808TransmitService { @@ -26,6 +26,10 @@ namespace JT808.Gateway.Transmit this.optionsMonitor = optionsMonitor; InitialDispatcherClient(); } + /// + /// + /// + /// public async void SendAsync((string TerminalNo, byte[] Data) parameter) { if (optionsMonitor.CurrentValue.DataTransfer != null) @@ -96,12 +100,16 @@ namespace JT808.Gateway.Transmit } } } - + /// + /// + /// public void Stop() { cts.Cancel(); } - + /// + /// + /// public void InitialDispatcherClient() { Task.Run(async () => @@ -207,8 +215,6 @@ namespace JT808.Gateway.Transmit /// /// 初始化远程服务器 /// - /// - /// /// private async Task InitRemoteServsers() { @@ -292,7 +298,6 @@ namespace JT808.Gateway.Transmit /// /// 动态添加远程服务器 /// - /// /// private async void AddRemoteServsers(List lastRemoteServers) { diff --git a/src/PipelineInfo.props b/src/PipelineInfo.props index cf58ab9..66c048d 100644 --- a/src/PipelineInfo.props +++ b/src/PipelineInfo.props @@ -8,7 +8,7 @@ https://github.com/SmallChi/JT808Gateway https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE - 1.1.8-preview3 + 1.1.8-preview5 LICENSE true latest diff --git a/src/Version.props b/src/Version.props deleted file mode 100644 index cfc6d11..0000000 --- a/src/Version.props +++ /dev/null @@ -1,5 +0,0 @@ - - - 2.3.6 - - \ No newline at end of file diff --git a/src/global.json b/src/global.json deleted file mode 100644 index 08585a2..0000000 --- a/src/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "7.0.100" - } -} \ No newline at end of file

56gspK#r(FfR&gUJUd<2--yM?Zw%9v^P6 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 W>06m%W7iAVpR)WLxf&Vsp#K9qWUQ+I diff --git a/global.json b/global.json new file mode 100644 index 0000000..0f11ff6 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "7.0.203" + } +} \ No newline at end of file diff --git a/publish.bat b/publish.bat deleted file mode 100644 index e5ad773..0000000 --- a/publish.bat +++ /dev/null @@ -1,18 +0,0 @@ -dotnet pack .\src\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.WebApi\JT808.DotNetty.WebApi.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Core\JT808.DotNetty.Core.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Client\JT808.DotNetty.Client.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj -c Release --output nupkgs - -echo 'push service pacakge...' -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.MsgIdHandler\JT808.DotNetty.MsgIdHandler.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.MsgLogging\JT808.DotNetty.MsgLogging.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.ReplyMessage\JT808.DotNetty.ReplyMessage.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.SessionNotice\JT808.DotNetty.SessionNotice.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.Traffic\JT808.DotNetty.Traffic.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.Transmit\JT808.DotNetty.Transmit.csproj -c Release --output nupkgs - -pause \ No newline at end of file diff --git a/publish.gateway.bat b/publish.gateway.bat index 3b4d61a..8108c37 100644 --- a/publish.gateway.bat +++ b/publish.gateway.bat @@ -4,10 +4,4 @@ dotnet pack .\src\JT808.Gateway.Abstractions\JT808.Gateway.Abstractions.csproj - dotnet pack .\src\JT808.Gateway.Client\JT808.Gateway.Client.csproj -c Release --output nupkgs dotnet pack .\src\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj -c Release --output nupkgs -echo 'push service pacakge...' -dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.MsgLogging\JT808.Gateway.MsgLogging.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.ReplyMessage\JT808.Gateway.ReplyMessage.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.SessionNotice\JT808.Gateway.SessionNotice.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.Transmit\JT808.Gateway.Transmit.csproj -c Release --output nupkgs -dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.MsgIdHandler\JT808.Gateway.MsgIdHandler.csproj -c Release --output nupkgs pause \ No newline at end of file diff --git a/simples/JT808.DotNetty.SimpleClient/JT808.DotNetty.SimpleClient.csproj b/simples/JT808.DotNetty.SimpleClient/JT808.DotNetty.SimpleClient.csproj deleted file mode 100644 index f7fbdb1..0000000 --- a/simples/JT808.DotNetty.SimpleClient/JT808.DotNetty.SimpleClient.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - netcoreapp3.1 - 7.3 - - - - - - - - - - diff --git a/simples/JT808.DotNetty.SimpleClient/Program.cs b/simples/JT808.DotNetty.SimpleClient/Program.cs deleted file mode 100644 index e54e2ec..0000000 --- a/simples/JT808.DotNetty.SimpleClient/Program.cs +++ /dev/null @@ -1,42 +0,0 @@ -using JT808.DotNetty.Client; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System; -using JT808.Protocol; -using JT808.Protocol.MessageBody; -using System.Text; -using System.Threading.Tasks; -using System.Threading; -using Microsoft.Extensions.Hosting; -using JT808.DotNetty.SimpleClient.Services; - -namespace JT808.DotNetty.SimpleClient -{ - class Program - { - static async Task Main(string[] args) - { - var serverHostBuilder = new HostBuilder() - .ConfigureLogging((context, logging) => - { - logging.AddConsole(); - logging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => - { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddLogging(options => { - options.AddConsole(); - options.SetMinimumLevel(LogLevel.Trace); - }); - services.AddJT808Configure() - .AddJT808Client(); - services.AddHostedService(); - services.AddHostedService(); - services.AddHostedService(); - }); - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/simples/JT808.DotNetty.SimpleClient/Services/Up2011Service.cs b/simples/JT808.DotNetty.SimpleClient/Services/Up2011Service.cs deleted file mode 100644 index b2510ec..0000000 --- a/simples/JT808.DotNetty.SimpleClient/Services/Up2011Service.cs +++ /dev/null @@ -1,72 +0,0 @@ -using JT808.DotNetty.Client; -using JT808.Protocol.MessageBody; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.SimpleClient.Services -{ - public class Up2011Service : IHostedService - { - private readonly IJT808TcpClientFactory jT808TcpClientFactory; - - public Up2011Service(IJT808TcpClientFactory jT808TcpClientFactory) - { - this.jT808TcpClientFactory = jT808TcpClientFactory; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - string sim = "44444444444"; - JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2011)); - Thread.Sleep(5000); - //1.终端注册 - client1.Send(JT808MsgId.终端注册.Create(sim, new JT808_0x0100() - { - PlateNo = "粤A12346", - PlateColor = 2, - AreaID = 0, - CityOrCountyId = 0, - MakerId = "Koike", - TerminalId = "Koike01", - TerminalModel = "Koike001" - })); - //2.终端鉴权 - client1.Send(JT808MsgId.终端鉴权.Create(sim, new JT808_0x0102() - { - Code = "1234" - })); - Task.Run(() => { - while (true) - { - var i = 0; - //3.每5秒发一次 - client1.Send(JT808MsgId.位置信息汇报.Create(sim, 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/simples/JT808.DotNetty.SimpleClient/Services/Up2013Service.cs b/simples/JT808.DotNetty.SimpleClient/Services/Up2013Service.cs deleted file mode 100644 index 8b163ce..0000000 --- a/simples/JT808.DotNetty.SimpleClient/Services/Up2013Service.cs +++ /dev/null @@ -1,100 +0,0 @@ -using JT808.DotNetty.Client; -using JT808.Protocol.MessageBody; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.SimpleClient.Services -{ - public class Up2013Service : IHostedService - { - private readonly IJT808TcpClientFactory jT808TcpClientFactory; - - public Up2013Service(IJT808TcpClientFactory jT808TcpClientFactory) - { - this.jT808TcpClientFactory = jT808TcpClientFactory; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - string sim = "11111111111"; - JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2013)); - string sim2 = "33333333333"; - JT808TcpClient client2 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim2, "127.0.0.1", 808, JT808Version.JTT2013)); - Thread.Sleep(5000); - //1.终端注册 - client1.Send(JT808MsgId.终端注册.Create(sim, new JT808_0x0100() - { - PlateNo = "粤A12345", - PlateColor = 2, - AreaID = 0, - CityOrCountyId = 0, - MakerId = "Koike", - TerminalId = "Koike01", - TerminalModel = "Koike001" - })); - client2.Send(JT808MsgId.终端注册.Create(sim2, new JT808_0x0100() - { - PlateNo = "粤A12345", - PlateColor = 2, - AreaID = 0, - CityOrCountyId = 0, - MakerId = "Koike", - TerminalId = "Koike02", - TerminalModel = "Koike002" - })); - //2.终端鉴权 - client1.Send(JT808MsgId.终端鉴权.Create(sim, new JT808_0x0102() - { - Code = "1234" - })); - //2.终端鉴权 - client2.Send(JT808MsgId.终端鉴权.Create(sim2, new JT808_0x0102() - { - Code = "1234" - })); - Task.Run(() => { - while (true) - { - var i = 0; - //3.每5秒发一次 - client1.Send(JT808MsgId.位置信息汇报.Create(sim, new JT808_0x0200() - { - Lat = 110000 + i, - Lng = 100000 + i, - GPSTime = DateTime.Now, - Speed = 50, - Direction = 30, - AlarmFlag = 5, - Altitude = 50, - StatusFlag = 10 - })); - client2.Send(JT808MsgId.位置信息汇报.Create(sim2, 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/simples/JT808.DotNetty.SimpleClient/Services/Up2019Service.cs b/simples/JT808.DotNetty.SimpleClient/Services/Up2019Service.cs deleted file mode 100644 index 1f4a9ce..0000000 --- a/simples/JT808.DotNetty.SimpleClient/Services/Up2019Service.cs +++ /dev/null @@ -1,74 +0,0 @@ -using JT808.DotNetty.Client; -using JT808.Protocol.MessageBody; -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace JT808.DotNetty.SimpleClient.Services -{ - public class Up2019Service : IHostedService - { - private readonly IJT808TcpClientFactory jT808TcpClientFactory; - - public Up2019Service(IJT808TcpClientFactory jT808TcpClientFactory) - { - this.jT808TcpClientFactory = jT808TcpClientFactory; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - string sim = "22222222222"; - JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2019)); - Thread.Sleep(5000); - //1.终端注册 - client1.Send(JT808MsgId.终端注册.Create2019(sim, new JT808_0x0100() - { - PlateNo = "粤A12346", - PlateColor = 2, - AreaID = 0, - CityOrCountyId = 0, - MakerId = "Koike002", - TerminalId = "Koike002", - TerminalModel = "Koike002" - })); - //2.终端鉴权 - client1.Send(JT808MsgId.终端鉴权.Create2019(sim, new JT808_0x0102() - { - Code = "6666", - IMEI="123456", - SoftwareVersion="v1.0.0" - })); - Task.Run(() => { - while (true) - { - var i = 0; - //3.每5秒发一次 - client1.Send(JT808MsgId.位置信息汇报.Create2019(sim, 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/simples/JT808.DotNetty.SimpleQueueServer/JT808.DotNetty.SimpleQueueServer.csproj b/simples/JT808.DotNetty.SimpleQueueServer/JT808.DotNetty.SimpleQueueServer.csproj deleted file mode 100644 index 5a2d2e6..0000000 --- a/simples/JT808.DotNetty.SimpleQueueServer/JT808.DotNetty.SimpleQueueServer.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - Always - - - - - - - - - - - diff --git a/simples/JT808.DotNetty.SimpleQueueServer/Program.cs b/simples/JT808.DotNetty.SimpleQueueServer/Program.cs deleted file mode 100644 index 1969612..0000000 --- a/simples/JT808.DotNetty.SimpleQueueServer/Program.cs +++ /dev/null @@ -1,44 +0,0 @@ -using JT808.DotNetty.Core; -using JT808.DotNetty.Tcp; -using JT808.DotNetty.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.DotNetty.SimpleQueueServer -{ - 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) => - { - logging.AddConsole(); - logging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => - { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808NettyCore(hostContext.Configuration) - .AddJT808TcpNettyHost() - .AddJT808ServerKafkaMsgProducer(hostContext.Configuration) - .AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) - .Builder(); - }); - - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/simples/JT808.DotNetty.SimpleQueueServer/appsettings.json b/simples/JT808.DotNetty.SimpleQueueServer/appsettings.json deleted file mode 100644 index 2c1f010..0000000 --- a/simples/JT808.DotNetty.SimpleQueueServer/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgProducerConfig": { - "TopicName": "JT808NettyMsg", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyConsumerConfig": { - "TopicName": "JT808NettyMsgReply", - "EnableAutoCommit": true, - "GroupId": "JT808.NettyMsgReply", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/simples/JT808.DotNetty.SimpleQueueService/Impl/JT808DotNettyReplyMessageServiceInherited.cs b/simples/JT808.DotNetty.SimpleQueueService/Impl/JT808DotNettyReplyMessageServiceInherited.cs deleted file mode 100644 index 37a5f1f..0000000 --- a/simples/JT808.DotNetty.SimpleQueueService/Impl/JT808DotNettyReplyMessageServiceInherited.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using JT808.DotNetty.Abstractions; -using JT808.DotNetty.Kafka; -using JT808.DotNetty.ReplyMessage; -using JT808.Protocol; -using JT808.Protocol.Extensions; -using Microsoft.Extensions.Logging; - -namespace JT808.DotNetty.SimpleQueueService.Impl -{ - public class JT808DotNettyReplyMessageServiceInherited : JT808DotNettyReplyMessageService - { - public readonly ILogger logger; - - public JT808DotNettyReplyMessageServiceInherited(IJT808Config jT808Config, - IJT808MsgReplyProducer jT808MsgReplyProducer, - ILoggerFactory loggerFactory) - : base(jT808Config, jT808MsgReplyProducer) - { - logger = loggerFactory.CreateLogger(); - } - - public override void Processor((string TerminalNo, byte[] Data) parameter) - { - logger.LogDebug($"{parameter.TerminalNo}:{parameter.Data.ToHexString()}"); - base.Processor(parameter); - } - - public override byte[] Msg0x0200(JT808HeaderPackage request) - { - logger.LogWarning("==========================================="); - logger.LogWarning($"{request.Header.TerminalPhoneNo}---{request.OriginalData.ToHexString()}"); - logger.LogWarning("==========================================="); - return base.Msg0x0200(request); - } - } -} diff --git a/simples/JT808.DotNetty.SimpleQueueService/JT808.DotNetty.SimpleQueueService.csproj b/simples/JT808.DotNetty.SimpleQueueService/JT808.DotNetty.SimpleQueueService.csproj deleted file mode 100644 index b647c44..0000000 --- a/simples/JT808.DotNetty.SimpleQueueService/JT808.DotNetty.SimpleQueueService.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - Always - - - - - - - - - - - diff --git a/simples/JT808.DotNetty.SimpleQueueService/Program.cs b/simples/JT808.DotNetty.SimpleQueueService/Program.cs deleted file mode 100644 index 934e423..0000000 --- a/simples/JT808.DotNetty.SimpleQueueService/Program.cs +++ /dev/null @@ -1,41 +0,0 @@ -using JT808.DotNetty.Kafka; -using JT808.DotNetty.ReplyMessage; -using JT808.DotNetty.SimpleQueueService.Impl; -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.DotNetty.SimpleQueueService -{ - class Program - { - static async Task Main(string[] args) - { - var hostBuilder = new HostBuilder() - .ConfigureAppConfiguration((hostContext, config) => { - config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); - config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); - }) - .ConfigureLogging((hostContext, configLogging) => { - configLogging.AddConsole(); - configLogging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808ClientKafka() - .AddMsgReplyProducer(hostContext.Configuration) - .AddMsgConsumer(hostContext.Configuration) - .AddInprocJT808ReplyMessage(); - ; - }); - - await hostBuilder.RunConsoleAsync(); - } - } -} diff --git a/simples/JT808.DotNetty.SimpleQueueService/appsettings.json b/simples/JT808.DotNetty.SimpleQueueService/appsettings.json deleted file mode 100644 index 62d7485..0000000 --- a/simples/JT808.DotNetty.SimpleQueueService/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808MsgConsumerConfig": { - "TopicName": "JT808NettyMsg", - "EnableAutoCommit": true, - "GroupId": "JT808.NettyMsgHandler", - "BootstrapServers": "127.0.0.1:9092" - }, - "JT808MsgReplyProducerConfig": { - "TopicName": "JT808NettyMsgReply", - "BootstrapServers": "127.0.0.1:9092" - } -} diff --git a/simples/JT808.DotNetty.SimpleServer/JT808.DotNetty.SimpleServer.csproj b/simples/JT808.DotNetty.SimpleServer/JT808.DotNetty.SimpleServer.csproj deleted file mode 100644 index 2918d80..0000000 --- a/simples/JT808.DotNetty.SimpleServer/JT808.DotNetty.SimpleServer.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Exe - netcoreapp3.1 - 7.3 - - - - - - - - - - - Always - - - - diff --git a/simples/JT808.DotNetty.SimpleServer/Program.cs b/simples/JT808.DotNetty.SimpleServer/Program.cs deleted file mode 100644 index 8aaf524..0000000 --- a/simples/JT808.DotNetty.SimpleServer/Program.cs +++ /dev/null @@ -1,44 +0,0 @@ - -using JT808.DotNetty.Core; -using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Tcp; -using JT808.Protocol; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using System; -using System.Threading.Tasks; - -namespace JT808.DotNetty.SimpleServer -{ - 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) => - { - logging.AddConsole(); - logging.SetMinimumLevel(LogLevel.Trace); - }) - .ConfigureServices((hostContext, services) => - { - services.AddSingleton(); - services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - services.AddJT808Configure() - .AddJT808NettyCore(hostContext.Configuration) - .AddJT808TcpNettyHost() - .Builder(); - }); - - await serverHostBuilder.RunConsoleAsync(); - } - } -} diff --git a/simples/JT808.DotNetty.SimpleServer/appsettings.json b/simples/JT808.DotNetty.SimpleServer/appsettings.json deleted file mode 100644 index f656c3e..0000000 --- a/simples/JT808.DotNetty.SimpleServer/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Trace" - } - }, - "Console": { - "LogLevel": { - "Default": "Trace" - } - } - }, - "JT808Configuration": { - "TcpPort": 808, - "UdpPort": 808, - "WebApiPort": 828 - } -} diff --git a/simples/JT808.DotNettySimples.sln b/simples/JT808.DotNettySimples.sln deleted file mode 100644 index 52705a4..0000000 --- a/simples/JT808.DotNettySimples.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "simples", "simples", "{2459FB59-8A33-49A4-ADBC-A0B12C5886A6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleClient", "JT808.DotNetty.SimpleClient\JT808.DotNetty.SimpleClient.csproj", "{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleServer", "JT808.DotNetty.SimpleServer\JT808.DotNetty.SimpleServer.csproj", "{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleQueueServer", "JT808.DotNetty.SimpleQueueServer\JT808.DotNetty.SimpleQueueServer.csproj", "{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleQueueService", "JT808.DotNetty.SimpleQueueService\JT808.DotNetty.SimpleQueueService.csproj", "{90E1F1C9-A953-4341-9792-9E2AF4471B68}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Release|Any CPU.Build.0 = Release|Any CPU - {CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Release|Any CPU.Build.0 = Release|Any CPU - {1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Release|Any CPU.Build.0 = Release|Any CPU - {90E1F1C9-A953-4341-9792-9E2AF4471B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90E1F1C9-A953-4341-9792-9E2AF4471B68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90E1F1C9-A953-4341-9792-9E2AF4471B68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90E1F1C9-A953-4341-9792-9E2AF4471B68}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {E6F61CE8-BFB4-4946-A0D3-AECCE77824E5} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} - {CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} - {1DEAC7EA-D662-420B-A1A7-A6E840568F7B} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} - {90E1F1C9-A953-4341-9792-9E2AF4471B68} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {FC0FFCEA-E1EF-4C97-A1C5-F89418B6834B} - EndGlobalSection -EndGlobal diff --git a/simples/JT808.Gateway.SimpleQueueNotification/Impl/JT808MsgIdHandlerImpl.cs b/simples/JT808.Gateway.SimpleQueueNotification/Impl/JT808MsgIdHandlerImpl.cs index d30a0cd..a0c981a 100644 --- a/simples/JT808.Gateway.SimpleQueueNotification/Impl/JT808MsgIdHandlerImpl.cs +++ b/simples/JT808.Gateway.SimpleQueueNotification/Impl/JT808MsgIdHandlerImpl.cs @@ -1,5 +1,4 @@ using JT808.Gateway.Abstractions; -using JT808.Gateway.MsgIdHandler; using JT808.Gateway.SimpleQueueNotification.Hubs; using JT808.Protocol.Extensions; using Microsoft.AspNetCore.SignalR; diff --git a/simples/JT808.Gateway.SimpleQueueNotification/Startup.cs b/simples/JT808.Gateway.SimpleQueueNotification/Startup.cs index e39f8e1..30e3ec6 100644 --- a/simples/JT808.Gateway.SimpleQueueNotification/Startup.cs +++ b/simples/JT808.Gateway.SimpleQueueNotification/Startup.cs @@ -14,8 +14,8 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using JT808.Protocol; using JT808.Gateway.Kafka; -using JT808.Gateway.MsgIdHandler; using JT808.Gateway.SimpleQueueNotification.Impl; +using JT808.Gateway.Extensions; namespace JT808.Gateway.SimpleQueueNotification { diff --git a/simples/JT808.Gateway.SimpleQueueService/Impl/JT808SessionNoticeServiceImpl.cs b/simples/JT808.Gateway.SimpleQueueService/Impl/JT808SessionNoticeServiceImpl.cs index 404ed26..d4d961b 100644 --- a/simples/JT808.Gateway.SimpleQueueService/Impl/JT808SessionNoticeServiceImpl.cs +++ b/simples/JT808.Gateway.SimpleQueueService/Impl/JT808SessionNoticeServiceImpl.cs @@ -1,4 +1,4 @@ -using JT808.Gateway.SessionNotice; +using JT808.Gateway.Services; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; diff --git a/simples/JT808.Gateway.SimpleQueueService/Program.cs b/simples/JT808.Gateway.SimpleQueueService/Program.cs index add3c80..6927d49 100644 --- a/simples/JT808.Gateway.SimpleQueueService/Program.cs +++ b/simples/JT808.Gateway.SimpleQueueService/Program.cs @@ -1,7 +1,5 @@ using JT808.Protocol; using JT808.Gateway.Kafka; -using JT808.Gateway.ReplyMessage; -using JT808.Gateway.SessionNotice; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -9,6 +7,7 @@ using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using JT808.Gateway.SimpleQueueService.Impl; +using JT808.Gateway.Extensions; namespace JT808.Gateway.SimpleQueueService { diff --git a/simples/JT808.Gateway.SimpleServer/Impl/JT808MessageHandlerImpl.cs b/simples/JT808.Gateway.SimpleServer/Impl/JT808MessageHandlerImpl.cs index e5ac379..7530dd2 100644 --- a/simples/JT808.Gateway.SimpleServer/Impl/JT808MessageHandlerImpl.cs +++ b/simples/JT808.Gateway.SimpleServer/Impl/JT808MessageHandlerImpl.cs @@ -1,7 +1,7 @@ using JT808.Gateway.Abstractions; using JT808.Gateway.Abstractions.Configurations; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.Transmit; +using JT808.Gateway.Abstractions.Enums; +using JT808.Gateway.Services; using JT808.Protocol; using JT808.Protocol.Extensions; using Microsoft.Extensions.Logging; @@ -67,7 +67,10 @@ namespace JT808.Gateway.SimpleServer.Impl public override byte[] Msg0x0200(JT808HeaderPackage request) { //logger.LogDebug("重写自带Msg0x0200的消息"); - logger.LogDebug($"重写自带Msg0x0200的消息{request.Header.TerminalPhoneNo}-{request.OriginalData.ToHexString()}"); + if (logger.IsEnabled(LogLevel.Debug)) + { + logger.LogDebug($"重写自带Msg0x0200的消息{request.Header.TerminalPhoneNo}-{request.OriginalData.ToHexString()}"); + } return base.Msg0x0200(request); } @@ -78,7 +81,10 @@ namespace JT808.Gateway.SimpleServer.Impl /// public byte[] Msg0x9999(JT808HeaderPackage request) { - logger.LogDebug("自定义消息"); + if (logger.IsEnabled(LogLevel.Debug)) + { + logger.LogDebug("自定义消息"); + } return default; } } diff --git a/simples/JT808.Gateway.SimpleServer/Impl/JT808MsgLogging.cs b/simples/JT808.Gateway.SimpleServer/Impl/JT808MsgLogging.cs index 61c827f..36f2968 100644 --- a/simples/JT808.Gateway.SimpleServer/Impl/JT808MsgLogging.cs +++ b/simples/JT808.Gateway.SimpleServer/Impl/JT808MsgLogging.cs @@ -1,4 +1,5 @@ -using JT808.Gateway.MsgLogging; +using JT808.Gateway.Abstractions; +using JT808.Gateway.Abstractions.Enums; using JT808.Protocol.Extensions; using Microsoft.Extensions.Logging; using System; @@ -16,7 +17,10 @@ namespace JT808.Gateway.SimpleServer.Impl } public void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType) { - Logger.LogDebug($"{jT808MsgLoggingType.ToString()}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); + if(Logger.IsEnabled(LogLevel.Debug)) + { + Logger.LogDebug($"{jT808MsgLoggingType}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); + } } } } diff --git a/simples/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj b/simples/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj index 3becff5..dea479b 100644 --- a/simples/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj +++ b/simples/JT808.Gateway.SimpleServer/JT808.Gateway.SimpleServer.csproj @@ -7,7 +7,7 @@ - + diff --git a/simples/JT808.Gateway.SimpleServer/Program.cs b/simples/JT808.Gateway.SimpleServer/Program.cs index c7975db..670c92e 100644 --- a/simples/JT808.Gateway.SimpleServer/Program.cs +++ b/simples/JT808.Gateway.SimpleServer/Program.cs @@ -1,22 +1,19 @@ -using System; -using System.Threading.Tasks; -using JT808.Gateway.Abstractions; -using JT808.Gateway.Abstractions.Configurations; -using JT808.Gateway.Abstractions.Enums; -using JT808.Gateway.MsgLogging; -using JT808.Gateway.ReplyMessage; -using JT808.Gateway.SessionNotice; -using JT808.Gateway.SimpleServer.Impl; -using JT808.Gateway.SimpleServer.Services; -using JT808.Gateway.Transmit; +using JT808.Gateway.Abstractions.Enums; using JT808.Protocol; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using JT808.Gateway.SimpleServer.Impl; +using JT808.Gateway.SimpleServer.Services; +using JT808.Gateway.Abstractions; +using Microsoft.AspNetCore.Hosting; +using JT808.Gateway.Abstractions.Configurations; +using Microsoft.AspNetCore.Builder; +using JT808.Gateway.Extensions; namespace JT808.Gateway.SimpleServer { diff --git a/simples/build.bat b/simples/build.bat index e159953..1e33542 100644 --- a/simples/build.bat +++ b/simples/build.bat @@ -1,4 +1,3 @@ dotnet build JT808.PipelineSimples.sln -dotnet build JT808.DotNettySimples.sln pause \ No newline at end of file diff --git a/simples/global.json b/simples/global.json deleted file mode 100644 index 08585a2..0000000 --- a/simples/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "7.0.100" - } -} \ No newline at end of file diff --git a/simples/netty.props b/simples/netty.props deleted file mode 100644 index 93803a2..0000000 --- a/simples/netty.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/simples/pipeline.props b/simples/pipeline.props index c2ade37..087f616 100644 --- a/simples/pipeline.props +++ b/simples/pipeline.props @@ -9,10 +9,5 @@ - - - - - \ No newline at end of file diff --git a/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs b/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs deleted file mode 100644 index b61c2a8..0000000 --- a/src/JT808.DotNetty.Abstractions/Dtos/JT808AtomicCounterDto.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace JT808.DotNetty.Abstractions.Dtos -{ - ///