@@ -42,6 +42,7 @@ namespace JT809Netty.Core.Handlers | |||
if (logger.IsEnabled(LogLevel.Debug)) | |||
{ | |||
msg = ByteBufferUtil.HexDump(buffer); | |||
logger.LogDebug("accept package <<<" + msg); | |||
logger.LogDebug("accept package success count<<<" + MsgSuccessCounter.Count.ToString()); | |||
} | |||
} | |||
@@ -10,6 +10,8 @@ using System.Threading.Tasks; | |||
using JT809.Protocol; | |||
using DotNetty.Buffers; | |||
using JT809Netty.Core.ServiceHandlers; | |||
using System.Threading; | |||
using System; | |||
namespace JT809Netty.Core.Handlers | |||
{ | |||
@@ -22,20 +24,22 @@ namespace JT809Netty.Core.Handlers | |||
private readonly IOptionsMonitor<JT809NettyOptions> optionsMonitor; | |||
private readonly JT809BusinessTypeHandler jT809BusinessTypeHandler; | |||
private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler; | |||
public JT809DownMasterLinkConnectionHandler( | |||
JT809BusinessTypeHandler jT809BusinessTypeHandler, | |||
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler, | |||
IOptionsMonitor<JT809NettyOptions> optionsMonitor, | |||
ILoggerFactory loggerFactory) | |||
{ | |||
this.jT809BusinessTypeHandler = jT809BusinessTypeHandler; | |||
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler; | |||
this.optionsMonitor = optionsMonitor; | |||
logger = loggerFactory.CreateLogger<JT809DownMasterLinkConnectionHandler>(); | |||
} | |||
public override void ChannelActive(IChannelHandlerContext context) | |||
{ | |||
if (logger.IsEnabled(LogLevel.Debug)) | |||
logger.LogDebug(">>>Activate the channel."); | |||
base.ChannelActive(context); | |||
} | |||
@@ -75,12 +79,12 @@ namespace JT809Netty.Core.Handlers | |||
if (idleStateEvent != null) | |||
{ | |||
string channelId = context.Channel.Id.AsShortText(); | |||
logger.LogInformation($"{idleStateEvent.State.ToString()}>>>{channelId}"); | |||
switch (idleStateEvent.State) | |||
{ | |||
case IdleState.WriterIdle: | |||
//发送心跳保持 | |||
jT809BusinessTypeHandler.Msg0x1005(context); | |||
logger.LogInformation($"{idleStateEvent.State.ToString()} heartbeat>>>{channelId}"); | |||
jT809DownMasterLinkBusinessTypeHandler.Msg0x1005(context); | |||
break; | |||
} | |||
} | |||
@@ -14,17 +14,20 @@ using JT809.Protocol.JT809Exceptions; | |||
namespace JT809Netty.Core.Handlers | |||
{ | |||
/// <summary> | |||
/// 下级平台主链路 | |||
/// </summary> | |||
public class JT809DownMasterLinkServiceHandler : ChannelHandlerAdapter | |||
{ | |||
private readonly ILogger<JT809DownMasterLinkServiceHandler> logger; | |||
private readonly JT809BusinessTypeHandler jT809BusinessTypeHandler; | |||
private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler; | |||
public JT809DownMasterLinkServiceHandler( | |||
JT809BusinessTypeHandler jT809BusinessTypeHandler, | |||
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler, | |||
ILoggerFactory loggerFactory) | |||
{ | |||
this.jT809BusinessTypeHandler = jT809BusinessTypeHandler; | |||
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler; | |||
logger = loggerFactory.CreateLogger<JT809DownMasterLinkServiceHandler>(); | |||
} | |||
@@ -34,7 +37,12 @@ namespace JT809Netty.Core.Handlers | |||
string receive = string.Empty; | |||
try | |||
{ | |||
if (logger.IsEnabled(LogLevel.Debug)) | |||
logger.LogDebug(JsonConvert.SerializeObject(jT809Package)); | |||
if (jT809DownMasterLinkBusinessTypeHandler.ResponseHandlerDict.TryGetValue(jT809Package.Header.BusinessType,out var action)) | |||
{ | |||
action(jT809Package, context); | |||
} | |||
} | |||
catch (JT809Exception ex) | |||
{ | |||
@@ -73,15 +73,6 @@ namespace JT809Netty.Core.Handlers | |||
case IdleState.ReaderIdle: | |||
//下级平台连续 3min 未收到上级平台发送的从链路保持应答数据包,则认为上级平台的连接中断,将主动断开数据传输从链路。 | |||
context.CloseAsync(); | |||
break; | |||
//case IdleState.WriterIdle: | |||
// break; | |||
//case IdleState.AllIdle: | |||
// break; | |||
default: | |||
break; | |||
} | |||
} | |||
@@ -7,8 +7,10 @@ using DotNetty.Transport.Channels.Sockets; | |||
using DotNetty.Transport.Libuv; | |||
using JT809Netty.Core.Configs; | |||
using JT809Netty.Core.Handlers; | |||
using JT809Netty.Core.ServiceHandlers; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Hosting; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using System; | |||
using System.Collections.Generic; | |||
@@ -32,10 +34,20 @@ namespace JT809Netty.Core | |||
readonly IOptionsMonitor<JT809NettyOptions> nettyOptions; | |||
IChannel ClientChannel; | |||
private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler; | |||
private readonly ILogger<JT809DownMasterLinkNettyService> logger; | |||
public JT809DownMasterLinkNettyService( | |||
ILoggerFactory loggerFactory, | |||
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler, | |||
IOptionsMonitor<JT809NettyOptions> nettyOptionsAccessor, | |||
IServiceProvider serviceProvider) | |||
{ | |||
logger = loggerFactory.CreateLogger<JT809DownMasterLinkNettyService>(); | |||
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler; | |||
nettyOptions = nettyOptionsAccessor; | |||
this.serviceProvider = serviceProvider; | |||
} | |||
@@ -54,8 +66,10 @@ namespace JT809Netty.Core | |||
{ | |||
InitChannel(channel); | |||
})) | |||
.Option(ChannelOption.SoBacklog, 1048576); | |||
IChannel clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(nettyOptions.CurrentValue.Host), nettyOptions.CurrentValue.Port)); | |||
.Option(ChannelOption.SoBacklog, 1048576); | |||
ClientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(nettyOptions.CurrentValue.Host), nettyOptions.CurrentValue.Port)); | |||
jT809DownMasterLinkBusinessTypeHandler.Msg0x1001(ClientChannel); | |||
} | |||
catch (Exception ex) | |||
{ | |||
@@ -69,11 +83,19 @@ namespace JT809Netty.Core | |||
{ | |||
try | |||
{ | |||
Task.WhenAll(workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); | |||
jT809DownMasterLinkBusinessTypeHandler.Msg0x1003(ClientChannel); | |||
// 已发送注销请求,等待30s,待服务器响应 | |||
int sleepTime = 50000; | |||
logger.LogInformation($">>>The logout request has been sent, waiting for {sleepTime/1000}s for the server to respond..."); | |||
Thread.Sleep(sleepTime); | |||
logger.LogInformation($"Check Status:<<<{jT809DownMasterLinkBusinessTypeHandler.Status.ToString()}"); | |||
ClientChannel.CloseAsync().ContinueWith((state) => { | |||
Task.WhenAll(workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); | |||
}); | |||
} | |||
catch (Exception ex) | |||
{ | |||
logger.LogError(ex,""); | |||
} | |||
return Task.CompletedTask; | |||
} | |||
@@ -84,7 +106,7 @@ namespace JT809Netty.Core | |||
try | |||
{ | |||
//下级平台应每 1min 发送一个主链路保持清求数据包到上级平台以保持链路连接 | |||
channel.Pipeline.AddLast("systemIdleState", new WriteTimeoutHandler(60)); | |||
channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(0, 60, 0)); | |||
channel.Pipeline.AddLast("jt809DownMasterLinkConnection", scope.ServiceProvider.GetRequiredService<JT809DownMasterLinkConnectionHandler>()); | |||
channel.Pipeline.AddLast("jt809Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.BEGINFLAG }), Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.ENDFLAG }))); | |||
channel.Pipeline.AddLast("jt809Decode", scope.ServiceProvider.GetRequiredService<JT809DecodeHandler>()); | |||
@@ -93,7 +93,7 @@ namespace JT809Netty.Core | |||
{ | |||
var scope = serviceProvider.CreateScope(); | |||
//下级平台连续 3min 未收到上级平台发送的从链路保持应答数据包,则认为上级平台的连接中断,将主动断开数据传输从链路。 | |||
channel.Pipeline.AddLast("systemIdleState", new ReadTimeoutHandler(180)); | |||
channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(180, 0, 0)); | |||
channel.Pipeline.AddLast("jt809DownSlaveLinkConnection", scope.ServiceProvider.GetRequiredService<JT809DownSlaveLinkConnectionHandler>()); | |||
channel.Pipeline.AddLast("jt809Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.BEGINFLAG }), Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.ENDFLAG }))); | |||
channel.Pipeline.AddLast("jt809Decode", scope.ServiceProvider.GetRequiredService<JT809DecodeHandler>()); | |||
@@ -10,9 +10,9 @@ | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="DotNetty.Handlers" Version="0.5.0" /> | |||
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.5.0" /> | |||
<PackageReference Include="JT809" Version="1.0.2" /> | |||
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | |||
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" /> | |||
<PackageReference Include="JT809" Version="1.0.3" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" /> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" /> | |||
@@ -1,108 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using DotNetty.Transport.Channels; | |||
using JT809.Protocol; | |||
using JT809.Protocol.JT809Enums; | |||
using JT809.Protocol.JT809MessageBody; | |||
using JT809.Protocol.JT809Extensions; | |||
using DotNetty.Buffers; | |||
using Microsoft.Extensions.Logging; | |||
using Newtonsoft.Json; | |||
namespace JT809Netty.Core.ServiceHandlers | |||
{ | |||
public class JT809BusinessTypeHandler | |||
{ | |||
public Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> RequestHandlerDict { get; } | |||
public Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> ResponseHandlerDict { get; } | |||
private readonly ILogger<JT809BusinessTypeHandler> logger; | |||
/// <summary> | |||
/// 初始化业务处理 | |||
/// </summary> | |||
public JT809BusinessTypeHandler( | |||
ILoggerFactory loggerFactory | |||
) | |||
{ | |||
logger = loggerFactory.CreateLogger<JT809BusinessTypeHandler>(); | |||
//RequestHandlerDict = new Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> | |||
//{ | |||
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_CONNECT_REQ, Msg0x1001}, | |||
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_REQ, Msg0x1003}, | |||
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_LINKTEST_REQ, Msg0x1005}, | |||
// //{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_INFORM, Msg0x1007}, | |||
// //{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CLOSELINK_INFORM, Msg0x1008}, | |||
//}; | |||
ResponseHandlerDict = new Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> | |||
{ | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CONNECT_RSP, Msg0x1002}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_RSP, Msg0x1004}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_LINKTEST_RSP, Msg0x1006}, | |||
}; | |||
} | |||
public JT809Package Msg0x1001(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
JT809Package loginPackage = JT809BusinessType.UP_CONNECT_REQ.Create(new JT809_0x1001 | |||
{ | |||
UserId=1234, | |||
DownLinkIP="127.0.0.1", | |||
DownLinkPort=8091, | |||
Password="20181009" | |||
}); | |||
try | |||
{ | |||
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 1000); | |||
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData)); | |||
return loginPackage; | |||
} | |||
catch (Exception) | |||
{ | |||
throw; | |||
} | |||
} | |||
public void Msg0x1002(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
logger.LogDebug(JsonConvert.SerializeObject(jT809Package)); | |||
} | |||
public JT809Package Msg0x1003(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
return null; | |||
} | |||
public void Msg0x1004(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
public JT809Package Msg0x1005(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
JT809Package heartbeatPackage = JT809BusinessType.UP_LINKTEST_REQ.Create(new JT809_0x1005()); | |||
byte[] sendHeartbeatData = JT809Serializer.Serialize(heartbeatPackage, 100); | |||
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendHeartbeatData)); | |||
return heartbeatPackage; | |||
} | |||
public void Msg0x1006(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
public JT809Package Msg0x1007(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
return null; | |||
} | |||
public void Msg0x1008(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,139 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using DotNetty.Transport.Channels; | |||
using JT809.Protocol; | |||
using JT809.Protocol.JT809Enums; | |||
using JT809.Protocol.JT809MessageBody; | |||
using JT809.Protocol.JT809Extensions; | |||
using DotNetty.Buffers; | |||
using Microsoft.Extensions.Logging; | |||
namespace JT809Netty.Core.ServiceHandlers | |||
{ | |||
public class JT809DownMasterLinkBusinessTypeHandler | |||
{ | |||
public ConnectionStatus Status { get; private set; } = ConnectionStatus.蓄势待发; | |||
public Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> RequestHandlerDict { get; } | |||
public Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> ResponseHandlerDict { get; } | |||
private readonly ILogger<JT809DownMasterLinkBusinessTypeHandler> logger; | |||
public JT809DownMasterLinkBusinessTypeHandler( | |||
ILoggerFactory loggerFactory) | |||
{ | |||
logger = loggerFactory.CreateLogger<JT809DownMasterLinkBusinessTypeHandler>(); | |||
RequestHandlerDict = new Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> | |||
{ | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路登录请求消息, Msg0x1001}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路注销请求消息, Msg0x1003}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路连接保持请求消息, Msg0x1005}, | |||
//{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_INFORM, Msg0x1007}, | |||
//{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CLOSELINK_INFORM, Msg0x1008}, | |||
}; | |||
ResponseHandlerDict = new Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> | |||
{ | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路登录应答消息, Msg0x1002}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路注销应答消息, Msg0x1004}, | |||
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路连接保持应答消息, Msg0x1006}, | |||
}; | |||
} | |||
public enum ConnectionStatus | |||
{ | |||
蓄势待发=0, | |||
下级平台主链路已发送注销请求=1, | |||
上级级平台主链路已发送注销应答 = 2, | |||
} | |||
public JT809Package Msg0x1001(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001 | |||
{ | |||
UserId = 1234, | |||
Password = "20181009", | |||
DownLinkIP = "127.0.0.1", | |||
DownLinkPort = 8091 | |||
}); | |||
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256); | |||
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData)); | |||
return loginPackage; | |||
} | |||
public JT809Package Msg0x1001(IChannel channel) | |||
{ | |||
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001 | |||
{ | |||
UserId = 1234, | |||
Password = "20181009", | |||
DownLinkIP = "127.0.0.1", | |||
DownLinkPort = 8091 | |||
}); | |||
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256); | |||
channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData)); | |||
return loginPackage; | |||
} | |||
public JT809Package Msg0x1003(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001 | |||
{ | |||
UserId = 1234, | |||
Password = "20181009", | |||
DownLinkIP = "127.0.0.1", | |||
DownLinkPort = 8091 | |||
}); | |||
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256); | |||
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData)); | |||
return loginPackage; | |||
} | |||
public JT809Package Msg0x1003(IChannel channel) | |||
{ | |||
JT809Package logoutPackage = JT809BusinessType.主链路注销请求消息.Create(new JT809_0x1003 | |||
{ | |||
UserId = 1234, | |||
Password = "20181009", | |||
}); | |||
byte[] sendLoginData = JT809Serializer.Serialize(logoutPackage, 128); | |||
channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData)); | |||
Status = ConnectionStatus.下级平台主链路已发送注销请求; | |||
return logoutPackage; | |||
} | |||
public JT809Package Msg0x1005(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
JT809Package heartbeatPackage = JT809BusinessType.主链路连接保持请求消息.Create(); | |||
byte[] sendHeartbeatData = JT809Serializer.Serialize(heartbeatPackage, 100); | |||
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendHeartbeatData)); | |||
return heartbeatPackage; | |||
} | |||
public JT809Package Msg0x1007(IChannelHandlerContext channelHandlerContext) | |||
{ | |||
return null; | |||
} | |||
public void Msg0x1002(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
public void Msg0x1004(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
Status = ConnectionStatus.上级级平台主链路已发送注销应答; | |||
} | |||
public void Msg0x1006(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
public void Msg0x1008(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext) | |||
{ | |||
} | |||
} | |||
} |
@@ -16,6 +16,14 @@ namespace JT809Netty.DownMasterLink | |||
{ | |||
static async Task Main(string[] args) | |||
{ | |||
JT809.Protocol.JT809GlobalConfig.Instance | |||
.SetHeaderOptions(new JT809.Protocol.JT809Configs.JT809HeaderOptions | |||
{ | |||
MsgGNSSCENTERID= 20141013, | |||
Version=new JT809.Protocol.JT809Header_Version (2,0,0), | |||
EncryptKey=9595 | |||
}); | |||
var serverHostBuilder = new HostBuilder() | |||
.UseEnvironment(args[0].Split('=')[1]) | |||
.ConfigureAppConfiguration((hostingContext, config) => | |||
@@ -36,7 +44,7 @@ namespace JT809Netty.DownMasterLink | |||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||
services.Configure<JT809NettyOptions>(hostContext.Configuration.GetSection("JT809NettyOptions")); | |||
services.AddSingleton<JT809BusinessTypeHandler, JT809BusinessTypeHandler>(); | |||
services.AddSingleton<JT809DownMasterLinkBusinessTypeHandler, JT809DownMasterLinkBusinessTypeHandler>(); | |||
services.AddScoped<JT809DownMasterLinkConnectionHandler, JT809DownMasterLinkConnectionHandler>(); | |||
services.AddScoped<JT809DownMasterLinkServiceHandler, JT809DownMasterLinkServiceHandler>(); | |||
services.AddScoped<JT809DecodeHandler, JT809DecodeHandler>(); | |||
@@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.28010.2016 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809Netty.Core", "JT809Netty.Core\JT809Netty.Core.csproj", "{2054D7E6-53B6-412F-BE9D-C6DABD80A111}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT809Netty.DownMasterLink", "JT809Netty.DownMasterLink\JT809Netty.DownMasterLink.csproj", "{3BF1D40D-A17D-4FBC-B3FF-B6DF8B3F13ED}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809Netty.DownMasterLink", "JT809Netty.DownMasterLink\JT809Netty.DownMasterLink.csproj", "{3BF1D40D-A17D-4FBC-B3FF-B6DF8B3F13ED}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||