From 4bfada2fb71379f5d88e35a878f618e1e8a267b7 Mon Sep 17 00:00:00 2001 From: SmallChi <564952747@qq.com> Date: Fri, 28 Dec 2018 17:42:58 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=85=83=E6=97=A6=E5=BF=AB=E4=B9=90,?= =?UTF-8?q?=E6=9C=89=E4=BA=8B=E5=81=9C=E5=86=994=E5=A4=A9=202.=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E6=97=A0=E7=94=A8=E9=A1=B9=E7=9B=AE=203.=E8=B0=83?= =?UTF-8?q?=E6=95=B4UDP=E7=9A=84=E4=BC=9A=E8=AF=9D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E3=80=81=E8=A7=A3=E7=A0=81=E5=99=A8=204.=E8=B0=83=E6=95=B4TCP/?= =?UTF-8?q?UDP=E7=9A=84=E7=BB=9F=E4=B8=80=E4=B8=8B=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Codecs/JT808UdpDecoder.cs | 1 + .../JT808SimpleTcpClient.cs | 15 ++++- .../JT808SimpleUdpClient.cs | 16 ++++- .../JT808UnificationTcpSendService.cs | 17 ++--- .../JT808UnificationUdpSendService.cs | 15 +---- .../Session/JT808TcpSessionManager.cs | 15 +++-- .../Session/JT808UdpSessionManager.cs | 62 +++++++++++++++---- .../JT808.DotNetty.Hosting.csproj | 4 +- .../JT808MsgIdCustomHandler.cs | 22 ------- src/JT808.DotNetty.Hosting/Program.cs | 17 +++-- src/JT808.DotNetty.Hosting/appsettings.json | 4 +- .../JT808SessionServiceTest.cs | 13 ++++ .../JT808SessionServiceTest.cs | 17 +++++ .../Handlers/JT808UdpServerHandler.cs | 4 ++ .../JT808UdpDotnettyExtensions.cs | 2 +- src/JT808.DotNetty.Udp/JT808UdpServerHost.cs | 2 +- src/JT808.DotNetty.sln | 23 +++---- 17 files changed, 152 insertions(+), 97 deletions(-) delete mode 100644 src/JT808.DotNetty.Hosting/JT808MsgIdCustomHandler.cs diff --git a/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs index 399c9cc..df27984 100644 --- a/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs +++ b/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs @@ -11,6 +11,7 @@ namespace JT808.DotNetty.Core.Codecs { protected override void Decode(IChannelHandlerContext context, DatagramPacket message, List output) { + if (!message.Content.IsReadable()) return; IByteBuffer byteBuffer = message.Content; byte[] buffer = new byte[byteBuffer.ReadableBytes]; byteBuffer.ReadBytes(buffer); diff --git a/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs b/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs index adcb04a..8887a27 100644 --- a/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs +++ b/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs @@ -18,9 +18,18 @@ namespace JT808.DotNetty.Core Task.Run(()=> { while (true) { - byte[] buffer = new byte[100]; - tcpClient.GetStream().Read(buffer, 0, 100); - Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " "+string.Join(" ", buffer)); + try + { + byte[] buffer = new byte[100]; + tcpClient.GetStream().Read(buffer, 0, 100); + Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + string.Join(" ", buffer)); + + } + catch + { + + + } Thread.Sleep(1000); } }); diff --git a/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs b/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs index 507fee3..568658f 100644 --- a/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs +++ b/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs @@ -15,11 +15,21 @@ namespace JT808.DotNetty.Core { udpClient = new UdpClient(); udpClient.Connect(remoteAddress); - Task.Run(() => { + Task.Run(() => + { while (true) { - string tmp = string.Join(" ", udpClient.Receive(ref remoteAddress)); - Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + tmp); + try + { + string tmp = string.Join(" ", udpClient.Receive(ref remoteAddress)); + Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + tmp); + Thread.Sleep(1000); + } + catch + { + + + } Thread.Sleep(1000); } }); diff --git a/src/JT808.DotNetty.Core/Services/JT808UnificationTcpSendService.cs b/src/JT808.DotNetty.Core/Services/JT808UnificationTcpSendService.cs index 7b50fdc..c60e803 100644 --- a/src/JT808.DotNetty.Core/Services/JT808UnificationTcpSendService.cs +++ b/src/JT808.DotNetty.Core/Services/JT808UnificationTcpSendService.cs @@ -22,19 +22,10 @@ namespace JT808.DotNetty.Internal { var session = jT808SessionManager.GetSession(terminalPhoneNo); if (session != null) - { - if (session.Channel.Open) - { - session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = true; - } - else - { - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = false; - resultDto.Message = "offline"; - } + { + session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); + resultDto.Code = JT808ResultCode.Ok; + resultDto.Data = true; } else { diff --git a/src/JT808.DotNetty.Core/Services/JT808UnificationUdpSendService.cs b/src/JT808.DotNetty.Core/Services/JT808UnificationUdpSendService.cs index 82abe77..6b267bf 100644 --- a/src/JT808.DotNetty.Core/Services/JT808UnificationUdpSendService.cs +++ b/src/JT808.DotNetty.Core/Services/JT808UnificationUdpSendService.cs @@ -24,18 +24,9 @@ namespace JT808.DotNetty.Internal var session = jT808SessionManager.GetSession(terminalPhoneNo); if (session != null) { - if (session.Channel.Open) - { - session.Channel.WriteAndFlushAsync(new DatagramPacket(Unpooled.WrappedBuffer(data), session.Sender)); - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = true; - } - else - { - resultDto.Code = JT808ResultCode.Ok; - resultDto.Data = false; - resultDto.Message = "offline"; - } + session.Channel.WriteAndFlushAsync(new DatagramPacket(Unpooled.WrappedBuffer(data), session.Sender)); + resultDto.Code = JT808ResultCode.Ok; + resultDto.Data = true; } else { diff --git a/src/JT808.DotNetty.Core/Session/JT808TcpSessionManager.cs b/src/JT808.DotNetty.Core/Session/JT808TcpSessionManager.cs index 7c7cbcb..b75cf1e 100644 --- a/src/JT808.DotNetty.Core/Session/JT808TcpSessionManager.cs +++ b/src/JT808.DotNetty.Core/Session/JT808TcpSessionManager.cs @@ -123,13 +123,16 @@ namespace JT808.DotNetty.Core //todo: 设备离线可以进行通知 //todo: 使用Redis 发布订阅 var terminalPhoneNos = SessionIdDict.Where(w => w.Value.Channel.Id == channel.Id).Select(s => s.Key).ToList(); - foreach (var key in terminalPhoneNos) + if (terminalPhoneNos.Count > 0) { - SessionIdDict.TryRemove(key, out JT808TcpSession jT808SessionRemove); - } - string nos = string.Join(",", terminalPhoneNos); - logger.LogInformation($">>>{nos} Channel Remove."); - jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline,nos); + foreach (var key in terminalPhoneNos) + { + SessionIdDict.TryRemove(key, out JT808TcpSession jT808SessionRemove); + } + string nos = string.Join(",", terminalPhoneNos); + logger.LogInformation($">>>{nos} Channel Remove."); + jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline, nos); + } } public IEnumerable GetAll() diff --git a/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs b/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs index d4b36ca..4ee8061 100644 --- a/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs +++ b/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using JT808.DotNetty.Abstractions; using JT808.DotNetty.Core.Metadata; +using DotNetty.Transport.Channels; namespace JT808.DotNetty.Core { @@ -51,20 +52,38 @@ namespace JT808.DotNetty.Core } public void TryAdd(JT808UdpSession appSession) - { - // 解决了设备号跟通道绑定到一起,不需要用到通道本身的SessionId - // 不管设备下发更改了设备终端号,只要是没有在内存中就当是新的 - // 存在的问题: - // 1.原先老的如何销毁 - // 2.这时候用的通道是相同的,设备终端是不同的 - // 当设备主动或者服务器断开以后,可以释放,这点内存忽略不计,况且更改设备号不是很频繁。 - if (SessionIdDict.TryAdd(appSession.TerminalPhoneNo, appSession)) + { + //1.先判断是否在缓存里面 + if(SessionIdDict.TryGetValue(appSession.TerminalPhoneNo,out JT808UdpSession jT808UdpSession)) { - //使用场景: - //部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, - //这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 - //todo: 有设备关联上来可以进行通知 例如:使用Redis发布订阅 - jT808SessionPublishing.PublishAsync(JT808Constants.SessionOnline, appSession.TerminalPhoneNo); + //处理缓存 + //判断设备的终结点是否相同 + if (jT808UdpSession.Sender.Equals(appSession.Sender)) + { + //相同 更新最后上线时间 + //每次使用最新的通道 + //将设备第一次上线时间赋值给当前上线的时间 + appSession.StartTime = jT808UdpSession.StartTime; + SessionIdDict.TryUpdate(appSession.TerminalPhoneNo, appSession, appSession); + } + else + { + //不同 算成新设备上来并且推送通知 + SessionIdDict.TryUpdate(appSession.TerminalPhoneNo, appSession, appSession); + jT808SessionPublishing.PublishAsync(JT808Constants.SessionOnline, appSession.TerminalPhoneNo); + } + } + else + { + //添加缓存 + if (SessionIdDict.TryAdd(appSession.TerminalPhoneNo, appSession)) + { + //使用场景: + //部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, + //这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 + //todo: 有设备关联上来可以进行通知 例如:使用Redis发布订阅 + jT808SessionPublishing.PublishAsync(JT808Constants.SessionOnline, appSession.TerminalPhoneNo); + } } } @@ -99,6 +118,23 @@ namespace JT808.DotNetty.Core } } + public void RemoveSessionByChannel(IChannel channel) + { + //todo: 设备离线可以进行通知 + //todo: 使用Redis 发布订阅 + var terminalPhoneNos = SessionIdDict.Where(w => w.Value.Channel.Id == channel.Id).Select(s => s.Key).ToList(); + if (terminalPhoneNos.Count > 0) + { + foreach (var key in terminalPhoneNos) + { + SessionIdDict.TryRemove(key, out JT808UdpSession jT808SessionRemove); + } + string nos = string.Join(",", terminalPhoneNos); + logger.LogInformation($">>>{nos} Channel Remove."); + jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline, nos); + } + } + public IEnumerable GetAll() { return SessionIdDict.Select(s => s.Value).ToList(); diff --git a/src/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj b/src/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj index 5fb9d07..f695859 100644 --- a/src/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj +++ b/src/JT808.DotNetty.Hosting/JT808.DotNetty.Hosting.csproj @@ -15,7 +15,9 @@ - + + + diff --git a/src/JT808.DotNetty.Hosting/JT808MsgIdCustomHandler.cs b/src/JT808.DotNetty.Hosting/JT808MsgIdCustomHandler.cs deleted file mode 100644 index e4cbbb5..0000000 --- a/src/JT808.DotNetty.Hosting/JT808MsgIdCustomHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -using JT808.DotNetty.Metadata; -using Microsoft.Extensions.Logging; - -namespace JT808.DotNetty.Hosting -{ - public class JT808MsgIdCustomHandler : JT808MsgIdHandlerBase - { - private readonly ILogger logger; - public JT808MsgIdCustomHandler( - ILoggerFactory loggerFactory, - JT808SessionManager sessionManager) : base(sessionManager) - { - logger = loggerFactory.CreateLogger(); - } - - public override JT808Response Msg0x0102(JT808Request request) - { - logger.LogDebug("Msg0x0102"); - return base.Msg0x0102(request); - } - } -} diff --git a/src/JT808.DotNetty.Hosting/Program.cs b/src/JT808.DotNetty.Hosting/Program.cs index cf8095d..57c4630 100644 --- a/src/JT808.DotNetty.Hosting/Program.cs +++ b/src/JT808.DotNetty.Hosting/Program.cs @@ -1,4 +1,8 @@ -using Microsoft.Extensions.Configuration; +using JT808.DotNetty.Core; +using JT808.DotNetty.Tcp; +using JT808.DotNetty.Udp; +using JT808.DotNetty.WebApi; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -24,16 +28,17 @@ namespace JT808.DotNetty.Hosting .ConfigureLogging((context, logging) => { logging.AddConsole(); - logging.SetMinimumLevel(LogLevel.Debug); + logging.SetMinimumLevel(LogLevel.Trace); }) .ConfigureServices((hostContext, services) => { services.AddSingleton(); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); - // 自定义消息处理业务 - services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHandlerBase), typeof(JT808MsgIdCustomHandler), ServiceLifetime.Singleton)); - }) - .UseJT808Host(); + services.AddJT808Core(hostContext.Configuration) + .AddJT808TcpHost() + .AddJT808UdpHost() + .AddJT808WebApiHost(); + }); await serverHostBuilder.RunConsoleAsync(); } diff --git a/src/JT808.DotNetty.Hosting/appsettings.json b/src/JT808.DotNetty.Hosting/appsettings.json index 9d4795f..b4243da 100644 --- a/src/JT808.DotNetty.Hosting/appsettings.json +++ b/src/JT808.DotNetty.Hosting/appsettings.json @@ -13,6 +13,8 @@ } }, "JT808Configuration": { - "Port": 6565 + "TcpPort": 12808, + "UdpPort": 12818, + "WebApiPort": 12828 } } diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs index e63fa26..3a483d8 100644 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs @@ -77,5 +77,18 @@ namespace JT808.DotNetty.Tcp.Test var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001"); var result3 = jT808SessionServiceDefaultImpl.GetAll(); } + + [TestMethod] + public void Test3() + { + // 判断通道是否关闭 + IJT808TcpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + JT808TcpSessionManager jT808TcpSessionManager = ServiceProvider.GetService(); + var result1 = jT808SessionServiceDefaultImpl.GetAll(); + SimpleTcpClient1.Down(); + Thread.Sleep(5000); + var session = jT808TcpSessionManager.GetSession("123456789001"); + Thread.Sleep(100000); + } } } diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs index e23c0f3..f3c0d9f 100644 --- a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs @@ -33,6 +33,10 @@ namespace JT808.DotNetty.Udp.Test public JT808SessionServiceTest() { + JT808SimpleUdpClient SimpleUdpClient11 = new JT808SimpleUdpClient(new IPEndPoint(IPAddress.Parse("157.255.57.82"), 12818)); + + JT808Package jT808Package11 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); + SimpleUdpClient11.WriteAsync(JT808Serializer.Serialize(jT808Package11)); SimpleUdpClient1 = new JT808SimpleUdpClient(endPoint); SimpleUdpClient2 = new JT808SimpleUdpClient(endPoint); SimpleUdpClient3 = new JT808SimpleUdpClient(endPoint); @@ -75,5 +79,18 @@ namespace JT808.DotNetty.Udp.Test var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001"); var result3 = jT808SessionServiceDefaultImpl.GetAll(); } + + [TestMethod] + public void Test3() + { + // 判断通道是否关闭 + IJT808UdpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + JT808UdpSessionManager jT808UdpSessionManager = ServiceProvider.GetService(); + var result1 = jT808SessionServiceDefaultImpl.GetAll(); + SimpleUdpClient1.Down(); + var session = jT808UdpSessionManager.GetSession("123456789001"); + var result3 = jT808UdpSessionManager.GetAll(); + Thread.Sleep(100000); + } } } diff --git a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs b/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs index cb5086f..63c0f79 100644 --- a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs +++ b/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs @@ -9,6 +9,7 @@ using JT808.DotNetty.Abstractions; using JT808.DotNetty.Core.Services; using JT808.DotNetty.Core; using JT808.DotNetty.Core.Handlers; +using System.Threading.Tasks; namespace JT808.DotNetty.Udp.Handlers { @@ -85,5 +86,8 @@ namespace JT808.DotNetty.Udp.Handlers } } } + + public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush(); + } } diff --git a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs b/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs index 1677769..dbc16f4 100644 --- a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs +++ b/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs @@ -15,7 +15,7 @@ namespace JT808.DotNetty.Udp { public static IServiceCollection AddJT808UdpHost(this IServiceCollection serviceDescriptors) { - serviceDescriptors.TryAddSingleton(); + serviceDescriptors.TryAddSingleton(); serviceDescriptors.TryAddSingleton(); serviceDescriptors.TryAddSingleton(); serviceDescriptors.TryAddScoped(); diff --git a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs b/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs index a37ba94..5c3a7eb 100644 --- a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs +++ b/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs @@ -55,7 +55,7 @@ namespace JT808.DotNetty.Udp { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) - { + { pipeline.AddLast("jt808UdpDecoder", scope.ServiceProvider.GetRequiredService()); pipeline.AddLast("jt808UdpService", scope.ServiceProvider.GetRequiredService()); } diff --git a/src/JT808.DotNetty.sln b/src/JT808.DotNetty.sln index 924361b..f3a1123 100644 --- a/src/JT808.DotNetty.sln +++ b/src/JT808.DotNetty.sln @@ -21,15 +21,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.WebApi", "JT 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.Test", "JT808.DotNetty.Test\JT808.DotNetty.Test.csproj", "{7BF06DFC-5F7B-4DEB-8005-B460ADF65B95}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty", "JT808.DotNetty\JT808.DotNetty.csproj", "{042C719D-9545-44C4-9EFE-500C1DA5DAC2}" -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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT808.DotNetty.WebApi.Test", "JT808.DotNetty.Tests\JT808.DotNetty.WebApi.Test\JT808.DotNetty.WebApi.Test.csproj", "{EDE77A29-0840-450C-8B08-2D3388845AE5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.WebApi.Test", "JT808.DotNetty.Tests\JT808.DotNetty.WebApi.Test\JT808.DotNetty.WebApi.Test.csproj", "{EDE77A29-0840-450C-8B08-2D3388845AE5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Hosting", "JT808.DotNetty.Hosting\JT808.DotNetty.Hosting.csproj", "{2E95C08A-B512-4252-A412-84E4EDCAE717}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -65,14 +63,6 @@ Global {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 - {7BF06DFC-5F7B-4DEB-8005-B460ADF65B95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7BF06DFC-5F7B-4DEB-8005-B460ADF65B95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7BF06DFC-5F7B-4DEB-8005-B460ADF65B95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7BF06DFC-5F7B-4DEB-8005-B460ADF65B95}.Release|Any CPU.Build.0 = Release|Any CPU - {042C719D-9545-44C4-9EFE-500C1DA5DAC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {042C719D-9545-44C4-9EFE-500C1DA5DAC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {042C719D-9545-44C4-9EFE-500C1DA5DAC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {042C719D-9545-44C4-9EFE-500C1DA5DAC2}.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 @@ -85,6 +75,10 @@ Global {EDE77A29-0840-450C-8B08-2D3388845AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDE77A29-0840-450C-8B08-2D3388845AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDE77A29-0840-450C-8B08-2D3388845AE5}.Release|Any CPU.Build.0 = Release|Any CPU + {2E95C08A-B512-4252-A412-84E4EDCAE717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E95C08A-B512-4252-A412-84E4EDCAE717}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E95C08A-B512-4252-A412-84E4EDCAE717}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E95C08A-B512-4252-A412-84E4EDCAE717}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -92,11 +86,10 @@ Global GlobalSection(NestedProjects) = preSolution {9FCA2EE9-8253-41AA-A64C-9883413864F9} = {B5A80356-5AF6-449F-9D8B-3C1BBB9D2443} {1C4CCE9B-761B-4581-B5DA-5B6D83572D56} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} - {7BF06DFC-5F7B-4DEB-8005-B460ADF65B95} = {B5A80356-5AF6-449F-9D8B-3C1BBB9D2443} - {042C719D-9545-44C4-9EFE-500C1DA5DAC2} = {B5A80356-5AF6-449F-9D8B-3C1BBB9D2443} {AEF1E1E2-C861-4268-86F6-6F376FAF79A7} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} {E503BFD8-D90A-4610-97C7-5B9A0497303B} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} {EDE77A29-0840-450C-8B08-2D3388845AE5} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} + {2E95C08A-B512-4252-A412-84E4EDCAE717} = {3BD7FF02-8516-4A77-A385-9FDCDD792E22} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FC0FFCEA-E1EF-4C97-A1C5-F89418B6834B}