From ff3b80fcd420ff91d42c420ece915c78eb2c0012 Mon Sep 17 00:00:00 2001 From: SmallChi <564952747@qq.com> Date: Thu, 27 Dec 2018 22:04:22 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=95=B4=E5=90=88808=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E5=99=A8=202.=E5=A2=9E=E5=8A=A0=E5=9F=BA=E4=BA=8Etcp=E5=92=8Cu?= =?UTF-8?q?dp=E7=9A=84=E4=BC=9A=E8=AF=9D=E5=8F=8A=E4=B8=8B=E5=8F=91?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=203.=E5=B0=86webapi?= =?UTF-8?q?=E7=9A=84url=E6=8E=A5=E5=8F=A3=E7=A7=BB=E5=85=A5=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E7=B1=BB=E4=B8=AD=E4=BE=BF=E4=BA=8E=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JT808Constants.cs | 54 +++++++++ .../Codecs/JT808TcpDecoder.cs | 20 ++++ .../Codecs/JT808UdpDecoder.cs | 20 ++++ .../Handlers/JT808MsgIdHttpHandlerBase.cs | 3 +- .../JT808.DotNetty.Core.csproj | 2 + .../JT808CoreDotnettyExtensions.cs | 6 +- .../JT808SimpleTcpClient.cs | 41 +++++++ .../JT808SimpleUdpClient.cs | 38 +++++++ .../Session/JT808UdpSessionManager.cs | 29 +---- .../JT808.DotNetty.Tcp.csproj | 1 - .../JT808TcpDotnettyExtensions.cs | 4 +- src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs | 2 +- src/JT808.DotNetty.Test/TestBase.cs | 2 +- .../JT808.DotNetty.Core.Test.csproj | 28 +++++ .../JT808DefaultChannelId.cs | 36 ++++++ .../JT808TcpSessionManagerTest.cs | 87 +++++++++++++++ .../JT808TransmitAddressFilterServiceTest.cs | 104 ++++++++++++++++++ .../SeedTcpSession.cs | 37 +++++++ .../JT808.DotNetty.Core.Test/TestBase.cs | 35 ++++++ .../JT808.DotNetty.Tcp.Test.csproj | 28 +++++ .../JT808SessionServiceTest.cs | 81 ++++++++++++++ .../JT808UnificationTcpSendServiceTest.cs | 76 +++++++++++++ .../JT808.DotNetty.Tcp.Test/TestBase.cs | 37 +++++++ .../JT808.DotNetty.Udp.Test.csproj | 34 ++++++ .../JT808SessionServiceTest.cs | 79 +++++++++++++ .../JT808UnificationUdpSendServiceTest.cs | 77 +++++++++++++ .../JT808.DotNetty.Udp.Test/TestBase.cs | 37 +++++++ .../JT808.DotNetty.WebApi.Test.csproj | 30 +++++ .../JT808.DotNetty.WebApi.Test/TestBase.cs | 41 +++++++ .../Handlers/JT808UdpServerHandler.cs | 6 +- .../JT808.DotNetty.Udp.csproj | 1 - .../JT808UdpDotnettyExtensions.cs | 12 +- src/JT808.DotNetty.Udp/JT808UdpServerHost.cs | 6 +- .../JT808MsgIdDefaultWebApiHandler.cs | 29 +++-- .../JT808WebApiDotnettyExtensions.cs | 2 +- src/JT808.DotNetty.sln | 52 +++++++-- 36 files changed, 1101 insertions(+), 76 deletions(-) create mode 100644 src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs create mode 100644 src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs create mode 100644 src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs create mode 100644 src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808DefaultChannelId.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TransmitAddressFilterServiceTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/TestBase.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808UnificationTcpSendServiceTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808UnificationUdpSendServiceTest.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj create mode 100644 src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/TestBase.cs diff --git a/src/JT808.DotNetty.Abstractions/JT808Constants.cs b/src/JT808.DotNetty.Abstractions/JT808Constants.cs index 4f591d5..ea9a959 100644 --- a/src/JT808.DotNetty.Abstractions/JT808Constants.cs +++ b/src/JT808.DotNetty.Abstractions/JT808Constants.cs @@ -5,5 +5,59 @@ public const string SessionOnline= "JT808SessionOnline"; public const string SessionOffline = "JT808SessionOffline"; + + public static class JT808WebApiRouteTable + { + public const string RouteTablePrefix = "/jt808api"; + + public const string SessionPrefix = "Session"; + + public const string TransmitPrefix = "Transmit"; + /// + /// 添加转发过滤地址 + /// + public static string TransmitAdd = $"{RouteTablePrefix}/{TransmitPrefix}/Add"; + /// + /// 删除转发过滤地址(不能删除在网关服务器配置文件配的地址) + /// + public static string TransmitRemove = $"{RouteTablePrefix}/{TransmitPrefix}/Remove"; + /// + /// 获取转发过滤地址信息集合 + /// + public static string TransmitGetAll = $"{RouteTablePrefix}/{TransmitPrefix}/GetAll"; + /// + /// 获取Tcp包计数器 + /// + public static string GetTcpAtomicCounter = $"{RouteTablePrefix}/GetTcpAtomicCounter"; + /// + /// 基于Tcp的会话服务集合 + /// + public static string SessionTcpGetAll = $"{RouteTablePrefix}/{SessionPrefix}/Tcp/GetAll"; + /// + /// 基于Tcp的会话服务-通过设备终端号移除对应会话 + /// + public static string SessionTcpRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/Tcp/RemoveByTerminalPhoneNo"; + /// + /// 基于Tcp的统一下发信息 + /// + public static string UnificationTcpSend = $"{RouteTablePrefix}/UnificationTcpSend"; + /// + /// 获取Udp包计数器 + /// + public static string GetUdpAtomicCounter = $"{RouteTablePrefix}/GetUdpAtomicCounter"; + /// + /// 基于Udp的统一下发信息 + /// + public static string UnificationUdpSend = $"{RouteTablePrefix}/UnificationUdpSend"; + /// + /// 基于Udp的会话服务集合 + /// + public static string SessionUdpGetAll = $"{RouteTablePrefix}/{SessionPrefix}/Udp/GetAll"; + /// + /// 基于Udp的会话服务-通过设备终端号移除对应会话 + /// + public static string SessionUdpRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/Udp/RemoveByTerminalPhoneNo"; + + } } } diff --git a/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs new file mode 100644 index 0000000..3eb3006 --- /dev/null +++ b/src/JT808.DotNetty.Core/Codecs/JT808TcpDecoder.cs @@ -0,0 +1,20 @@ +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) + { + 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/JT808UdpDecoder.cs b/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs new file mode 100644 index 0000000..399c9cc --- /dev/null +++ b/src/JT808.DotNetty.Core/Codecs/JT808UdpDecoder.cs @@ -0,0 +1,20 @@ +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) + { + IByteBuffer byteBuffer = message.Content; + byte[] buffer = new byte[byteBuffer.ReadableBytes]; + byteBuffer.ReadBytes(buffer); + output.Add(new JT808UdpPackage(buffer, message.Sender)); + } + } +} diff --git a/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs b/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs index 88bd089..62e8b76 100644 --- a/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs +++ b/src/JT808.DotNetty.Core/Handlers/JT808MsgIdHttpHandlerBase.cs @@ -17,7 +17,6 @@ namespace JT808.DotNetty.Core.Handlers /// public abstract class JT808MsgIdHttpHandlerBase { - private const string RouteTablePrefix = "/jt808api"; /// /// 初始化消息处理业务 /// @@ -28,7 +27,7 @@ namespace JT808.DotNetty.Core.Handlers protected void CreateRoute(string url, Func func) { - HandlerDict.Add($"{RouteTablePrefix}/{url}", func); + HandlerDict.Add(url, func); } public Dictionary> HandlerDict { get; } diff --git a/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj b/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj index d0f8873..01d9fc8 100644 --- a/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj +++ b/src/JT808.DotNetty.Core/JT808.DotNetty.Core.csproj @@ -18,7 +18,9 @@ + + diff --git a/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs b/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs index 010ba24..5dd16a3 100644 --- a/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs +++ b/src/JT808.DotNetty.Core/JT808CoreDotnettyExtensions.cs @@ -9,8 +9,10 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("JT808.DotNetty.Test")] - +[assembly: InternalsVisibleTo("JT808.DotNetty.Core.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.Udp.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.WebApi.Test")] namespace JT808.DotNetty.Core { public static class JT808CoreDotnettyExtensions diff --git a/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs b/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs new file mode 100644 index 0000000..adcb04a --- /dev/null +++ b/src/JT808.DotNetty.Core/JT808SimpleTcpClient.cs @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace JT808.DotNetty.Core +{ + internal class JT808SimpleTcpClient + { + private TcpClient tcpClient; + + public JT808SimpleTcpClient(IPEndPoint remoteAddress) + { + tcpClient = new TcpClient(); + tcpClient.Connect(remoteAddress); + Task.Run(()=> { + while (true) + { + byte[] buffer = new byte[100]; + tcpClient.GetStream().Read(buffer, 0, 100); + Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " "+string.Join(" ", buffer)); + Thread.Sleep(1000); + } + }); + } + + + + public void WriteAsync(byte[] data) + { + tcpClient.GetStream().WriteAsync(data, 0, data.Length); + } + + public void Down() + { + tcpClient.Close(); + } + } +} diff --git a/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs b/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs new file mode 100644 index 0000000..507fee3 --- /dev/null +++ b/src/JT808.DotNetty.Core/JT808SimpleUdpClient.cs @@ -0,0 +1,38 @@ +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace JT808.DotNetty.Core +{ + internal class JT808SimpleUdpClient + { + private UdpClient udpClient; + + public JT808SimpleUdpClient(IPEndPoint remoteAddress) + { + udpClient = new UdpClient(); + udpClient.Connect(remoteAddress); + Task.Run(() => { + while (true) + { + string tmp = string.Join(" ", udpClient.Receive(ref remoteAddress)); + Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + tmp); + Thread.Sleep(1000); + } + }); + } + + public void WriteAsync(byte[] data) + { + udpClient.SendAsync(data, data.Length); + } + + public void Down() + { + udpClient.Close(); + } + } +} diff --git a/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs b/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs index 850dbdf..d4b36ca 100644 --- a/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs +++ b/src/JT808.DotNetty.Core/Session/JT808UdpSessionManager.cs @@ -87,34 +87,15 @@ namespace JT808.DotNetty.Core { return default; } - // 处理转发过来的是数据 这时候通道对设备是1对多关系,需要清理垃圾数据 - //1.用当前会话的通道Id找出通过转发过来的其他设备的终端号 - var terminalPhoneNos = SessionIdDict.Where(w => w.Value.Channel.Id == jT808Session.Channel.Id).Select(s => s.Key).ToList(); - //2.存在则一个个移除 - if (terminalPhoneNos.Count > 1) + if (SessionIdDict.TryRemove(terminalPhoneNo, out JT808UdpSession jT808SessionRemove)) { - //3.移除包括当前的设备号 - foreach (var key in terminalPhoneNos) - { - SessionIdDict.TryRemove(key, out JT808UdpSession jT808SessionRemove); - } - string nos = string.Join(",", terminalPhoneNos); - logger.LogInformation($">>>{terminalPhoneNo}-{nos} 1-n Session Remove."); - jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline, nos); - return jT808Session; + logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); + jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline,terminalPhoneNo); + return jT808SessionRemove; } else { - if (SessionIdDict.TryRemove(terminalPhoneNo, out JT808UdpSession jT808SessionRemove)) - { - logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); - jT808SessionPublishing.PublishAsync(JT808Constants.SessionOffline,terminalPhoneNo); - return jT808SessionRemove; - } - else - { - return default; - } + return default; } } diff --git a/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj b/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj index b637e79..1edbeda 100644 --- a/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj +++ b/src/JT808.DotNetty.Tcp/JT808.DotNetty.Tcp.csproj @@ -25,7 +25,6 @@ - diff --git a/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs b/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs index adbe54a..db194ce 100644 --- a/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs +++ b/src/JT808.DotNetty.Tcp/JT808TcpDotnettyExtensions.cs @@ -1,4 +1,4 @@ -using JT808.DotNetty.Codecs; +using JT808.DotNetty.Core.Codecs; using JT808.DotNetty.Core; using JT808.DotNetty.Core.Handlers; using JT808.DotNetty.Core.Services; @@ -12,7 +12,7 @@ using System; using System.Reflection; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("JT808.DotNetty.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] namespace JT808.DotNetty.Tcp { diff --git a/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs b/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs index 30c53cb..394449d 100644 --- a/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs +++ b/src/JT808.DotNetty.Tcp/JT808TcpServerHost.cs @@ -4,7 +4,7 @@ using DotNetty.Handlers.Timeout; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Libuv; -using JT808.DotNetty.Codecs; +using JT808.DotNetty.Core.Codecs; using JT808.DotNetty.Core.Configurations; using JT808.DotNetty.Handlers; using JT808.DotNetty.Tcp.Handlers; diff --git a/src/JT808.DotNetty.Test/TestBase.cs b/src/JT808.DotNetty.Test/TestBase.cs index e30f4eb..55bad9d 100644 --- a/src/JT808.DotNetty.Test/TestBase.cs +++ b/src/JT808.DotNetty.Test/TestBase.cs @@ -32,7 +32,7 @@ namespace JT808.DotNetty.Test services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); }) .UseJT808Host(); - var build=serverHostBuilder.Build(); + var build = serverHostBuilder.Build(); build.Start(); ServiceProvider = build.Services; 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 new file mode 100644 index 0000000..2de938d --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808.DotNetty.Core.Test.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808DefaultChannelId.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808DefaultChannelId.cs new file mode 100644 index 0000000..c60dc1d --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808DefaultChannelId.cs @@ -0,0 +1,36 @@ +using DotNetty.Transport.Channels; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Core.Test +{ + public class JT808DefaultChannelId : IChannelId + { + private string Id { + get + { + return Guid.NewGuid().ToString("N"); + } + } + + 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.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs new file mode 100644 index 0000000..a076428 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TcpSessionManagerTest.cs @@ -0,0 +1,87 @@ +using DotNetty.Transport.Channels.Embedded; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + + +namespace JT808.DotNetty.Core.Test +{ + [TestClass] + public class JT808SessionManagerTest: SeedTcpSession + { + [TestMethod] + public void Test1() + { + var no = "test150"; + var channel = new EmbeddedChannel(new JT808DefaultChannelId()); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no)); + Thread.Sleep(1000); + jT80TcpSessionManager.Heartbeat(no); + } + + [TestMethod] + public void Test2() + { + var no = "test151"; + var channel = new EmbeddedChannel(new JT808DefaultChannelId()); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no)); + var sessionInfo = jT80TcpSessionManager.RemoveSession(no); + Assert.AreEqual(no, sessionInfo.TerminalPhoneNo); + } + + [TestMethod] + public void Test3() + { + var realSessionInfos = jT80TcpSessionManager.GetAll(); + } + + [TestMethod] + public void Test4() + { + var realSessionCount = jT80TcpSessionManager.SessionCount; + } + + [TestMethod] + public void Test5() + { + //转发过来的数据 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(new Metadata.JT808TcpSession(channel, no)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no1)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no2)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no3)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, no4)); + var removeSession = jT80TcpSessionManager.RemoveSession(no); + Assert.AreEqual(no, removeSession.TerminalPhoneNo); + Assert.AreEqual(channel, removeSession.Channel); + Assert.AreEqual(channel.Id, removeSession.Channel.Id); + } + + [TestMethod] + public void Test6() + { + //转发过来的数据 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(new Metadata.JT808TcpSession(channel1, no)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel1, no1)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel1, no2)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel2, no3)); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel2, no4)); + jT80TcpSessionManager.RemoveSessionByChannel(channel1); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TransmitAddressFilterServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TransmitAddressFilterServiceTest.cs new file mode 100644 index 0000000..2173db5 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/JT808TransmitAddressFilterServiceTest.cs @@ -0,0 +1,104 @@ +using JT808.DotNetty.Abstractions.Dtos; +using JT808.DotNetty.Core.Configurations; +using JT808.DotNetty.Core.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; + +namespace JT808.DotNetty.Core.Test +{ + [TestClass] + public class JT808TransmitAddressFilterServiceTest + { + private JT808TransmitAddressFilterService jT808TransmitAddressFilterService; + + public JT808TransmitAddressFilterServiceTest() + { + var serverHostBuilder = new HostBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.Configure(hostContext.Configuration.GetSection("JT808Configuration")); + services.AddSingleton(); + }); + var serviceProvider = serverHostBuilder.Build().Services; + jT808TransmitAddressFilterService = serviceProvider.GetService(); + jT808TransmitAddressFilterService.Add(new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12345 + }); + jT808TransmitAddressFilterService.Add(new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12346 + }); + jT808TransmitAddressFilterService.Add(new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12347 + }); + jT808TransmitAddressFilterService.Add(new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12348 + }); + } + + [TestMethod] + public void Test1() + { + Assert.IsTrue(jT808TransmitAddressFilterService.ContainsKey(new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12348 + }.EndPoint)); + } + + [TestMethod] + public void Test2() + { + var result = jT808TransmitAddressFilterService.GetAll(); + } + + [TestMethod] + public void Test3() + { + var ip1 = new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 12349 + }; + var result1= jT808TransmitAddressFilterService.Add(ip1); + Assert.AreEqual(JT808ResultCode.Ok, result1.Code); + Assert.IsTrue(result1.Data); + var result2 = jT808TransmitAddressFilterService.Remove(ip1); + Assert.AreEqual(JT808ResultCode.Ok, result2.Code); + Assert.IsTrue(result2.Data); + } + + [TestMethod] + public void Test4() + { + var configIp = new JT808IPAddressDto + { + Host = "127.0.0.1", + Port = 6561 + }; + var result2 = jT808TransmitAddressFilterService.Remove(configIp); + Assert.AreEqual(JT808ResultCode.Ok, result2.Code); + Assert.IsFalse(result2.Data); + Assert.AreEqual("不能删除服务器配置的地址", result2.Message); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs new file mode 100644 index 0000000..bacfa00 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/SeedTcpSession.cs @@ -0,0 +1,37 @@ +using DotNetty.Transport.Channels.Embedded; +using JT808.DotNetty.Internal; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; + +namespace JT808.DotNetty.Core.Test +{ + [TestClass] + public class SeedTcpSession + { + public JT808TcpSessionManager jT80TcpSessionManager = new JT808TcpSessionManager( + new JT808SessionPublishingEmptyImpl(), + new LoggerFactory()); + + public SeedTcpSession() + { + for (var i = 0; i < 10; i++) + { + var channel = new EmbeddedChannel(new JT808DefaultChannelId()); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, i.ToString())); + } + } + + [TestMethod] + public void Init() + { + for (var i = 0; i < 10; i++) + { + var channel = new EmbeddedChannel(new JT808DefaultChannelId()); + jT80TcpSessionManager.TryAdd(new Metadata.JT808TcpSession(channel, i.ToString())); + } + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/TestBase.cs new file mode 100644 index 0000000..4fb1916 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Core.Test/TestBase.cs @@ -0,0 +1,35 @@ +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.Core.Test +{ + public class TestBase + { + public static IServiceProvider ServiceProvider; + + static TestBase() + { + var serverHostBuilder = new HostBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.AddJT808Core(hostContext.Configuration); + }); + var build = serverHostBuilder.Build(); + build.Start(); + ServiceProvider = build.Services; + + } + } +} 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 new file mode 100644 index 0000000..c72c6a7 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808.DotNetty.Tcp.Test.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs new file mode 100644 index 0000000..e63fa26 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808SessionServiceTest.cs @@ -0,0 +1,81 @@ +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 Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace JT808.DotNetty.Tcp.Test +{ + [TestClass] + public class JT808SessionServiceTest:TestBase,IDisposable + { + static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6565); + + JT808SimpleTcpClient SimpleTcpClient1; + JT808SimpleTcpClient SimpleTcpClient2; + JT808SimpleTcpClient SimpleTcpClient3; + JT808SimpleTcpClient SimpleTcpClient4; + JT808SimpleTcpClient SimpleTcpClient5; + + public JT808SessionServiceTest() + { + SimpleTcpClient1 = new JT808SimpleTcpClient(endPoint); + SimpleTcpClient2 = new JT808SimpleTcpClient(endPoint); + SimpleTcpClient3 = new JT808SimpleTcpClient(endPoint); + SimpleTcpClient4 = new JT808SimpleTcpClient(endPoint); + SimpleTcpClient5 = new JT808SimpleTcpClient(endPoint); + // 心跳会话包 + JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); + SimpleTcpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1)); + + // 心跳会话包 + JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002"); + SimpleTcpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2)); + + // 心跳会话包 + JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003"); + SimpleTcpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3)); + + // 心跳会话包 + JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004"); + SimpleTcpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4)); + + // 心跳会话包 + JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005"); + SimpleTcpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5)); + Thread.Sleep(1000); + } + + public void Dispose() + { + SimpleTcpClient1.Down(); + SimpleTcpClient2.Down(); + SimpleTcpClient3.Down(); + SimpleTcpClient4.Down(); + SimpleTcpClient5.Down(); + } + + [TestMethod] + public void Test1() + { + IJT808TcpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + var result = jT808SessionServiceDefaultImpl.GetAll(); + Thread.Sleep(5000); + } + + [TestMethod] + public void Test2() + { + IJT808TcpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + var result1 = jT808SessionServiceDefaultImpl.GetAll(); + var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001"); + var result3 = jT808SessionServiceDefaultImpl.GetAll(); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808UnificationTcpSendServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808UnificationTcpSendServiceTest.cs new file mode 100644 index 0000000..d2070e7 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/JT808UnificationTcpSendServiceTest.cs @@ -0,0 +1,76 @@ +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 Microsoft.VisualStudio.TestTools.UnitTesting; +using JT808.Protocol.MessageBody; +using JT808.DotNetty.Abstractions.Dtos; + +namespace JT808.DotNetty.Tcp.Test +{ + [TestClass] + public class JT808UnificationTcpSendServiceTest: TestBase + { + static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6565); + + private IJT808UnificationTcpSendService jT808UnificationTcpSendService; + private IJT808TcpSessionService jT808SessionServiceDefaultImpl; + + public JT808UnificationTcpSendServiceTest() + { + + JT808SimpleTcpClient SimpleTcpClient1 = new JT808SimpleTcpClient(endPoint); + JT808SimpleTcpClient SimpleTcpClient2 = new JT808SimpleTcpClient(endPoint); + JT808SimpleTcpClient SimpleTcpClient3 = new JT808SimpleTcpClient(endPoint); + JT808SimpleTcpClient SimpleTcpClient4 = new JT808SimpleTcpClient(endPoint); + JT808SimpleTcpClient SimpleTcpClient5 = new JT808SimpleTcpClient(endPoint); + // 心跳会话包 + JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); + SimpleTcpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1)); + + // 心跳会话包 + JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002"); + SimpleTcpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2)); + + // 心跳会话包 + JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003"); + SimpleTcpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3)); + + // 心跳会话包 + JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004"); + SimpleTcpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4)); + + // 心跳会话包 + JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005"); + SimpleTcpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5)); + + Thread.Sleep(300); + } + + [TestMethod] + public void Test1() + { + jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + jT808UnificationTcpSendService = ServiceProvider.GetService(); + jT808SessionServiceDefaultImpl.GetAll(); + 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 = jT808UnificationTcpSendService.Send(no, data); + Thread.Sleep(1000); + Assert.AreEqual(200, jt808Result.Code); + Assert.IsTrue(jt808Result.Data); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs new file mode 100644 index 0000000..257f6df --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Tcp.Test/TestBase.cs @@ -0,0 +1,37 @@ +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; + +namespace JT808.DotNetty.Tcp.Test +{ + public class TestBase + { + public static IServiceProvider ServiceProvider; + + static TestBase() + { + var serverHostBuilder = new HostBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.AddJT808Core(hostContext.Configuration) + .AddJT808TcpHost(); + }); + var build = serverHostBuilder.Build(); + build.Start(); + ServiceProvider = build.Services; + + } + } +} 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 new file mode 100644 index 0000000..64634d8 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808.DotNetty.Udp.Test.csproj @@ -0,0 +1,34 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + + Always + + + + + + Always + + + + diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs new file mode 100644 index 0000000..e23c0f3 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808SessionServiceTest.cs @@ -0,0 +1,79 @@ +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 Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace JT808.DotNetty.Udp.Test +{ + [TestClass] + public class JT808SessionServiceTest:TestBase,IDisposable + { + static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 818); + JT808SimpleUdpClient SimpleUdpClient1; + JT808SimpleUdpClient SimpleUdpClient2; + JT808SimpleUdpClient SimpleUdpClient3; + JT808SimpleUdpClient SimpleUdpClient4; + JT808SimpleUdpClient SimpleUdpClient5; + + public void Dispose() + { + SimpleUdpClient1.Down(); + SimpleUdpClient2.Down(); + SimpleUdpClient3.Down(); + SimpleUdpClient4.Down(); + SimpleUdpClient5.Down(); + } + + public JT808SessionServiceTest() + { + SimpleUdpClient1 = new JT808SimpleUdpClient(endPoint); + SimpleUdpClient2 = new JT808SimpleUdpClient(endPoint); + SimpleUdpClient3 = new JT808SimpleUdpClient(endPoint); + SimpleUdpClient4 = new JT808SimpleUdpClient(endPoint); + SimpleUdpClient5 = new JT808SimpleUdpClient(endPoint); + // 心跳会话包 + JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); + SimpleUdpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1)); + + // 心跳会话包 + JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002"); + SimpleUdpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2)); + + // 心跳会话包 + JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003"); + SimpleUdpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3)); + + // 心跳会话包 + JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004"); + SimpleUdpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4)); + + // 心跳会话包 + JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005"); + SimpleUdpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5)); + Thread.Sleep(1000); + } + + [TestMethod] + public void Test1() + { + IJT808UdpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + var result = jT808SessionServiceDefaultImpl.GetAll(); + } + + [TestMethod] + public void Test2() + { + IJT808UdpSessionService jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + var result1 = jT808SessionServiceDefaultImpl.GetAll(); + var result2 = jT808SessionServiceDefaultImpl.RemoveByTerminalPhoneNo("123456789001"); + var result3 = jT808SessionServiceDefaultImpl.GetAll(); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808UnificationUdpSendServiceTest.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808UnificationUdpSendServiceTest.cs new file mode 100644 index 0000000..61b8623 --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/JT808UnificationUdpSendServiceTest.cs @@ -0,0 +1,77 @@ +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 Microsoft.VisualStudio.TestTools.UnitTesting; +using JT808.Protocol.MessageBody; +using JT808.DotNetty.Abstractions.Dtos; + +namespace JT808.DotNetty.Udp.Test +{ + [TestClass] + public class JT808UnificationUdpSendServiceTest : TestBase + { + static IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 818); + + private IJT808UnificationUdpSendService jT808UnificationUdpSendService; + private IJT808UdpSessionService jT808SessionServiceDefaultImpl; + + public JT808UnificationUdpSendServiceTest() + { + + JT808SimpleUdpClient SimpleUdpClient1 = new JT808SimpleUdpClient(endPoint); + JT808SimpleUdpClient SimpleUdpClient2 = new JT808SimpleUdpClient(endPoint); + JT808SimpleUdpClient SimpleUdpClient3 = new JT808SimpleUdpClient(endPoint); + JT808SimpleUdpClient SimpleUdpClient4 = new JT808SimpleUdpClient(endPoint); + JT808SimpleUdpClient SimpleUdpClient5 = new JT808SimpleUdpClient(endPoint); + // 心跳会话包 + JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789001"); + SimpleUdpClient1.WriteAsync(JT808Serializer.Serialize(jT808Package1)); + + // 心跳会话包 + JT808Package jT808Package2 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789002"); + SimpleUdpClient2.WriteAsync(JT808Serializer.Serialize(jT808Package2)); + + // 心跳会话包 + JT808Package jT808Package3 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789003"); + SimpleUdpClient3.WriteAsync(JT808Serializer.Serialize(jT808Package3)); + + // 心跳会话包 + JT808Package jT808Package4 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789004"); + SimpleUdpClient4.WriteAsync(JT808Serializer.Serialize(jT808Package4)); + + // 心跳会话包 + JT808Package jT808Package5 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("123456789005"); + SimpleUdpClient5.WriteAsync(JT808Serializer.Serialize(jT808Package5)); + + Thread.Sleep(300); + } + + [TestMethod] + public void Test1() + { + //"126 131 0 0 13 18 52 86 120 144 1 0 11 5 115 109 97 108 108 99 104 105 32 53 49 56 24 126" + jT808SessionServiceDefaultImpl = ServiceProvider.GetService(); + jT808UnificationUdpSendService = ServiceProvider.GetService(); + jT808SessionServiceDefaultImpl.GetAll(); + 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 = jT808UnificationUdpSendService.Send(no, data); + Thread.Sleep(1000); + Assert.AreEqual(200, jt808Result.Code); + Assert.IsTrue(jt808Result.Data); + } + } +} diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs new file mode 100644 index 0000000..ed2128c --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.Udp.Test/TestBase.cs @@ -0,0 +1,37 @@ +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; + +namespace JT808.DotNetty.Udp.Test +{ + public class TestBase + { + public static IServiceProvider ServiceProvider; + + static TestBase() + { + var serverHostBuilder = new HostBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.AddJT808Core(hostContext.Configuration) + .AddJT808UdpHost(); + }); + var build = serverHostBuilder.Build(); + build.Start(); + ServiceProvider = build.Services; + + } + } +} 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 new file mode 100644 index 0000000..f84995f --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/JT808.DotNetty.WebApi.Test.csproj @@ -0,0 +1,30 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/TestBase.cs b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/TestBase.cs new file mode 100644 index 0000000..013689e --- /dev/null +++ b/src/JT808.DotNetty.Tests/JT808.DotNetty.WebApi.Test/TestBase.cs @@ -0,0 +1,41 @@ +using JT808.DotNetty.Core; +using JT808.DotNetty.Udp; +using JT808.DotNetty.Tcp; +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.WebApi.Test +{ + public class TestBase + { + public static IServiceProvider ServiceProvider; + + static TestBase() + { + var serverHostBuilder = new HostBuilder() + .ConfigureAppConfiguration((hostingContext, config) => + { + config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + services.AddJT808Core(hostContext.Configuration) + .AddJT808TcpHost() + .AddJT808UdpHost(); + }); + var build = serverHostBuilder.Build(); + build.Start(); + ServiceProvider = build.Services; + } + + + } +} diff --git a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs b/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs index 29cc648..cb5086f 100644 --- a/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs +++ b/src/JT808.DotNetty.Udp/Handlers/JT808UdpServerHandler.cs @@ -51,11 +51,7 @@ namespace JT808.DotNetty.Udp.Handlers //解析具体的消息体,具体调用JT808Serializer.Deserialize JT808HeaderPackage jT808HeaderPackage = JT808Serializer.Deserialize(msg.Buffer); jT808UdpAtomicCounterService.MsgSuccessIncrement(); - jT808UdpSessionManager.TryAdd(new JT808UdpSession { - Channel= ctx.Channel, - Sender= msg.Sender, - TerminalPhoneNo= jT808HeaderPackage.Header.TerminalPhoneNo - }); + jT808UdpSessionManager.TryAdd(new JT808UdpSession(ctx.Channel, msg.Sender, jT808HeaderPackage.Header.TerminalPhoneNo)); if (logger.IsEnabled(LogLevel.Debug)) { logger.LogDebug("accept package success count<<<" + jT808UdpAtomicCounterService.MsgSuccessCount.ToString()); diff --git a/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj b/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj index ca0c59e..8641a7f 100644 --- a/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj +++ b/src/JT808.DotNetty.Udp/JT808.DotNetty.Udp.csproj @@ -27,7 +27,6 @@ - diff --git a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs b/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs index 30e4ea2..1677769 100644 --- a/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs +++ b/src/JT808.DotNetty.Udp/JT808UdpDotnettyExtensions.cs @@ -1,19 +1,13 @@ -using JT808.DotNetty.Codecs; -using JT808.DotNetty.Core; +using JT808.DotNetty.Core; +using JT808.DotNetty.Core.Codecs; using JT808.DotNetty.Core.Handlers; -using JT808.DotNetty.Core.Interfaces; using JT808.DotNetty.Core.Services; -using JT808.DotNetty.Udp; using JT808.DotNetty.Udp.Handlers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; -using System; -using System.Reflection; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("JT808.DotNetty.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.Udp.Test")] namespace JT808.DotNetty.Udp { diff --git a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs b/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs index dc35f8a..a37ba94 100644 --- a/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs +++ b/src/JT808.DotNetty.Udp/JT808UdpServerHost.cs @@ -1,7 +1,7 @@ using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; -using JT808.DotNetty.Codecs; +using JT808.DotNetty.Core.Codecs; using JT808.DotNetty.Core.Configurations; using JT808.DotNetty.Udp.Handlers; using Microsoft.Extensions.DependencyInjection; @@ -50,13 +50,13 @@ namespace JT808.DotNetty.Udp .Option(ChannelOption.SoReuseport, true); } bootstrap - .Option(ChannelOption.SoBacklog, configuration.SoBacklog) + .Option(ChannelOption.SoBroadcast, true) .Handler(new ActionChannelInitializer(channel => { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) { - pipeline.AddLast(new JT808UdpDecoder()); + pipeline.AddLast("jt808UdpDecoder", scope.ServiceProvider.GetRequiredService()); pipeline.AddLast("jt808UdpService", scope.ServiceProvider.GetRequiredService()); } })); diff --git a/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs b/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs index a70eba9..55aca29 100644 --- a/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs +++ b/src/JT808.DotNetty.WebApi/Handlers/JT808MsgIdDefaultWebApiHandler.cs @@ -1,4 +1,5 @@ -using JT808.DotNetty.Abstractions.Dtos; +using JT808.DotNetty.Abstractions; +using JT808.DotNetty.Abstractions.Dtos; using JT808.DotNetty.Core.Handlers; using JT808.DotNetty.Core.Interfaces; using JT808.DotNetty.Core.Metadata; @@ -12,10 +13,6 @@ namespace JT808.DotNetty.WebApi.Handlers /// public class JT808MsgIdDefaultWebApiHandler : JT808MsgIdHttpHandlerBase { - private const string sessionRoutePrefix = "Session"; - - private const string transmitPrefix = "Transmit"; - private readonly JT808TcpAtomicCounterService jT808TcpAtomicCounterService; private readonly JT808UdpAtomicCounterService jT808UdpAtomicCounterService; @@ -250,21 +247,21 @@ namespace JT808.DotNetty.WebApi.Handlers protected virtual void InitTcpRoute() { - CreateRoute($"{transmitPrefix}/Add", AddTransmitAddress); - CreateRoute($"{transmitPrefix}/Remove", RemoveTransmitAddress); - CreateRoute($"{transmitPrefix}/GetAll", GetTransmitAll); - CreateRoute($"GetTcpAtomicCounter", GetTcpAtomicCounter); - CreateRoute($"{sessionRoutePrefix}/Tcp/GetAll", GetTcpSessionAll); - CreateRoute($"{sessionRoutePrefix}/Tcp/RemoveByTerminalPhoneNo", RemoveTcpSessionByTerminalPhoneNo); - CreateRoute($"UnificationTcpSend", UnificationTcpSend); + CreateRoute(JT808Constants.JT808WebApiRouteTable.TransmitAdd, AddTransmitAddress); + CreateRoute(JT808Constants.JT808WebApiRouteTable.TransmitRemove, RemoveTransmitAddress); + CreateRoute(JT808Constants.JT808WebApiRouteTable.TransmitGetAll, GetTransmitAll); + CreateRoute(JT808Constants.JT808WebApiRouteTable.GetTcpAtomicCounter, GetTcpAtomicCounter); + CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionTcpGetAll, GetTcpSessionAll); + CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionTcpRemoveByTerminalPhoneNo, RemoveTcpSessionByTerminalPhoneNo); + CreateRoute(JT808Constants.JT808WebApiRouteTable.UnificationTcpSend, UnificationTcpSend); } protected virtual void InitUdpRoute() { - CreateRoute($"GetUdpAtomicCounter", GetUdpAtomicCounter); - CreateRoute($"UnificationUdpSend", UnificationUdpSend); - CreateRoute($"{sessionRoutePrefix}/Udp/GetAll", GetUdpSessionAll); - CreateRoute($"{sessionRoutePrefix}/Udp/RemoveByTerminalPhoneNo", RemoveUdpSessionByTerminalPhoneNo); + CreateRoute(JT808Constants.JT808WebApiRouteTable.GetUdpAtomicCounter, GetUdpAtomicCounter); + CreateRoute(JT808Constants.JT808WebApiRouteTable.UnificationUdpSend, UnificationUdpSend); + CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionUdpGetAll, GetUdpSessionAll); + CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionUdpRemoveByTerminalPhoneNo, RemoveUdpSessionByTerminalPhoneNo); } } } diff --git a/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs b/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs index e662f20..fe0ed82 100644 --- a/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs +++ b/src/JT808.DotNetty.WebApi/JT808WebApiDotnettyExtensions.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("JT808.DotNetty.Test")] +[assembly: InternalsVisibleTo("JT808.DotNetty.WebApi.Test")] namespace JT808.DotNetty.WebApi { diff --git a/src/JT808.DotNetty.sln b/src/JT808.DotNetty.sln index 79aa084..924361b 100644 --- a/src/JT808.DotNetty.sln +++ b/src/JT808.DotNetty.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28407.52 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.168 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B5A80356-5AF6-449F-9D8B-3C1BBB9D2443}" EndProject @@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.Protocol", "JT808.Pro EndProject 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.Codecs", "JT808.DotNetty.Codecs\JT808.DotNetty.Codecs.csproj", "{42513FBA-1D8F-4F91-A74F-25E06C7BD027}" -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}" @@ -21,6 +19,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Tcp", "JT808 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.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}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -35,10 +45,6 @@ Global {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 - {42513FBA-1D8F-4F91-A74F-25E06C7BD027}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42513FBA-1D8F-4F91-A74F-25E06C7BD027}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42513FBA-1D8F-4F91-A74F-25E06C7BD027}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42513FBA-1D8F-4F91-A74F-25E06C7BD027}.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 @@ -55,12 +61,42 @@ Global {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 + {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 + {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 + {EDE77A29-0840-450C-8B08-2D3388845AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection 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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FC0FFCEA-E1EF-4C97-A1C5-F89418B6834B}