From 249d3f9eb05e60094d3d0624e3fe43189da3b27a Mon Sep 17 00:00:00 2001
From: SmallChi <564952747@qq.com>
Date: Wed, 28 Nov 2018 17:09:02 +0800
Subject: [PATCH] =?UTF-8?q?1.=E5=A2=9E=E5=8A=A0=E4=BB=AA=E8=A1=A8=E7=9B=98?=
 =?UTF-8?q?=202.=E5=8E=BB=E9=99=A4=E5=A4=9A=E4=BD=99=E4=BC=9A=E8=AF=9D?=
 =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=8E=A5=E5=8F=A3=203.=E4=BF=AE=E5=A4=8D?=
 =?UTF-8?q?=E8=BD=AC=E5=8F=91=E8=BF=87=E6=9D=A5=E6=95=B0=E6=8D=AE=E4=BC=9A?=
 =?UTF-8?q?=E8=AF=9D=E7=AE=A1=E7=90=86bug=204.=E4=BF=AE=E6=94=B9=E6=96=87?=
 =?UTF-8?q?=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                                     | 174 ++--------
 src/JT808.DotNetty.Dashbord.sln               |  25 ++
 .../Configurations/JT808Options.cs            |  15 +
 .../JT808UnificationSendController.cs         |  48 +++
 .../Dtos/JT808ResultDto.cs                    |  15 +
 .../Dtos/JT808SessionInfoDto.cs               |  38 +++
 .../Dtos/JT808UnificationSendRequestDto.cs    |  15 +
 .../JT808.DotNetty.Dashbord.csproj            |  16 +
 src/JT808.DotNetty.Dashbord/Program.cs        |  24 ++
 src/JT808.DotNetty.Dashbord/Startup.cs        |  41 +++
 .../appsettings.Development.json              |   9 +
 src/JT808.DotNetty.Dashbord/appsettings.json  |   8 +
 .../JT808SessionManagerTest.cs                |   3 +-
 .../JT808WebAPIServiceTest.cs                 | 116 +------
 .../Dtos/JT808SessionInfoDto.cs               |  12 +
 .../Interfaces/IJT808SessionService.cs        |  31 +-
 .../JT808SessionServiceDefaultImpl.cs         | 125 +------
 src/JT808.DotNetty/JT808.DotNetty.xml         | 323 ++++++++++++++++++
 src/JT808.DotNetty/JT808DotnettyExtensions.cs |  15 +
 src/JT808.DotNetty/JT808SessionManager.cs     |  53 +--
 src/JT808.DotNetty/JT808WebAPIService.cs      |  77 +----
 src/JT808.DotNetty/Metadata/JT808Session.cs   |   8 +-
 22 files changed, 681 insertions(+), 510 deletions(-)
 create mode 100644 src/JT808.DotNetty.Dashbord.sln
 create mode 100644 src/JT808.DotNetty.Dashbord/Configurations/JT808Options.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/Dtos/JT808ResultDto.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/Dtos/JT808SessionInfoDto.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/Dtos/JT808UnificationSendRequestDto.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/JT808.DotNetty.Dashbord.csproj
 create mode 100644 src/JT808.DotNetty.Dashbord/Program.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/Startup.cs
 create mode 100644 src/JT808.DotNetty.Dashbord/appsettings.Development.json
 create mode 100644 src/JT808.DotNetty.Dashbord/appsettings.json
 create mode 100644 src/JT808.DotNetty/JT808.DotNetty.xml

diff --git a/README.md b/README.md
index 63746da..a499e1d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# JT808DotNetty
+# JT808DotNetty
 
 基于DotNetty封装的JT808DotNetty专注消息业务处理
 
@@ -21,12 +21,6 @@
 
 ![design_model](https://github.com/SmallChi/JT808DotNetty/blob/master/doc/img/design_model.png)
 
-## NuGet安装
-
-| Package Name          | Version                                            | Downloads                                           |
-| --------------------- | -------------------------------------------------- | --------------------------------------------------- |
-| Install-Package JT808DotNetty | ![JT808DotNetty](https://img.shields.io/nuget/v/JT808DotNetty.svg) | ![JT808DotNetty](https://img.shields.io/nuget/dt/JT808DotNetty.svg) |
-
 ## 集成功能实现
 
 ### 1.集成原包分发器
@@ -53,8 +47,7 @@
 
 #### 1.实现业务消息处理程序JT808MsgIdHandlerBase
 
-```business Impl
-using JT808.DotNetty;
+```business Imp
 public class JT808MsgIdCustomHandler : JT808MsgIdHandlerBase
 {
     private readonly ILogger<JT808MsgIdCustomHandler> logger;
@@ -172,50 +165,13 @@ static async Task Main(string[] args)
 | LastActiveTime| DateTime| 最后上线时间|
 | StartTime| DateTime| 上线时间|
 | TerminalPhoneNo|string| 终端手机号|
+| LoaclAddressIP| string| 本地ip地址|
+| WebApiPort| string| WebApi端口号|
+| RemoteAddressIP| string| 远程ip地址|
 
-##### 1.获取实际连接数(存在其他平台转发过来的数据,这时候通道Id和设备属于一对多的关系)
-
-请求地址:Session/GetRealLinkCount
-
-请求方式:GET
-
-返回数据:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| Data| int| 实际连接数|
-
-返回结果:
-``` result1
-{
-    "Message":"",
-    "Code":200,
-    "Data":10
-}
-```
-##### 2.获取设备相关连的连接数
+##### 1.获取会话集合
 
-请求地址:Session/GetRelevanceLinkCount
-
-请求方式:GET
-
-返回数据:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| Data| int | 设备相关连的连接数 |
-
-返回结果:
-``` result2
-{
-    "Message":"",
-    "Code":200,
-    "Data":10
-}
-```
-##### 3.获取实际会话集合
-
-请求地址:Session/GetRealAll
+请求地址:Session/GetAll
 
 请求方式:GET
 
@@ -226,7 +182,7 @@ static async Task Main(string[] args)
 | Data| List\<JT808SessionInfoDto> | 实际会话信息集合 |
 
 返回结果:
-``` result3
+``` session1
 {
     "Message":"",
     "Code":200,
@@ -235,50 +191,23 @@ static async Task Main(string[] args)
             "ChannelId":"eadad23",
             "LastActiveTime":"2018-11-27 20:00:00",
             "StartTime":"2018-11-25 20:00:00",
-            "TerminalPhoneNo":"123456789012"
+            "TerminalPhoneNo":"123456789012",
+            "LoaclAddressIP":"127.0.0.1:808",
+            "WebApiPort":828,
+            "RemoteAddressIP":"127.0.0.1:11808"
         },{
             "ChannelId":"eadad23",
             "LastActiveTime":"2018-11-27 20:00:00",
             "StartTime":"2018-11-25 20:00:00",
-            "TerminalPhoneNo":"123456789013"
+            "TerminalPhoneNo":"123456789013",
+            "LoaclAddressIP":"127.0.0.1:808",
+            "WebApiPort":828,
+            "RemoteAddressIP":"127.0.0.1:11808"
         }
     ]
 }
 ```
-##### 4.获取设备相关联会话集合
-
-请求地址:Session/GetRelevanceAll
-
-请求方式:GET
-
-返回数据:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| Data| List\<JT808SessionInfoDto> | 设备相关联会话信息集合 |
-
-返回结果:
-``` result4
-{
-    "Message":"",
-    "Code":200,
-    "Data":[
-        {
-            "ChannelId":"eadad23",
-            "LastActiveTime":"2018-11-27 20:00:00",
-            "StartTime":"2018-11-25 20:00:00",
-            "TerminalPhoneNo":"123456789012"
-        }, {
-            "ChannelId":"eadad24",
-            "LastActiveTime":"2018-11-26 20:00:00",
-            "StartTime":"2018-11-22 20:00:00",
-            "TerminalPhoneNo":"123456789013"
-        }
-    ]
-}
-```
-
-##### 5.通过通道Id移除对应会话
+##### 2.通过通道Id移除对应会话
 
 请求地址:Session/RemoveByChannelId
 
@@ -297,14 +226,14 @@ static async Task Main(string[] args)
 | Data| bool | 是否成功 |
 
 返回结果:
-``` result5
+``` session2
 {
     "Message":"",
     "Code":200,
     "Data":true
 }
 ```
-##### 6.通过设备终端号移除对应会话
+##### 3.通过设备终端号移除对应会话
 
 请求地址:Session/RemoveByTerminalPhoneNo
 
@@ -323,73 +252,10 @@ static async Task Main(string[] args)
 | Data| bool | 是否成功 
 
 返回结果:
-``` result6
+``` session3
 {
     "Message":"",
     "Code":200,
     "Data":true
 }
 ```
-##### 7.通过通道Id获取会话信息
-
-请求地址:Session/GetByChannelId
-
-请求方式:POST
-
-请求参数:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| channelId| string| 通道Id|
-
-返回数据:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| Data| JT808SessionInfoDto | 会话信息对象 |
-
-返回结果:
-``` result7
-{
-    "Message":"",
-    "Code":200,
-    "Data":{
-        "ChannelId":"eadad24",
-        "LastActiveTime":"2018-11-26 20:00:00",
-        "StartTime":"2018-11-22 20:00:00",
-        "TerminalPhoneNo":"123456789013"
-    }
-}
-```
-
-##### 8.通过设备终端号获取会话信息
-
-请求地址:Session/GetByTerminalPhoneNo
-
-请求方式:POST
-
-请求参数:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| terminalPhoneNo| string| 设备终端号|
-
-返回数据:
-
-|属性|数据类型|参数说明|
-|:------:|:------:|:------|
-| Data| JT808SessionInfoDto | 会话信息对象 |
-
-返回结果:
-``` result8
-{
-    "Message":"",
-    "Code":200,
-    "Data":{
-        "ChannelId":"eadad24",
-        "LastActiveTime":"2018-11-26 20:00:00",
-        "StartTime":"2018-11-22 20:00:00",
-        "TerminalPhoneNo":"123456789013"
-    }
-}
-```
diff --git a/src/JT808.DotNetty.Dashbord.sln b/src/JT808.DotNetty.Dashbord.sln
new file mode 100644
index 0000000..be58372
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28010.2050
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.Dashbord", "JT808.DotNetty.Dashbord\JT808.DotNetty.Dashbord.csproj", "{3A9698C3-CEBB-4C93-A40C-3F7FE650217C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3A9698C3-CEBB-4C93-A40C-3F7FE650217C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3A9698C3-CEBB-4C93-A40C-3F7FE650217C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3A9698C3-CEBB-4C93-A40C-3F7FE650217C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3A9698C3-CEBB-4C93-A40C-3F7FE650217C}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {0DDBE27F-708F-46DC-837F-BEF34A50A0B1}
+	EndGlobalSection
+EndGlobal
diff --git a/src/JT808.DotNetty.Dashbord/Configurations/JT808Options.cs b/src/JT808.DotNetty.Dashbord/Configurations/JT808Options.cs
new file mode 100644
index 0000000..0a67c19
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Configurations/JT808Options.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace JT808.DotNetty.Dashbord.Configurations
+{
+    public class JT808Options
+    {
+        /// <summary>
+        /// 接口服务地址
+        /// </summary>
+        public List<string> WebApiHosts { get; set; }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs b/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs
new file mode 100644
index 0000000..b8a2904
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Controllers/JT808UnificationSendController.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+
+namespace JT808.DotNetty.Dashbord.Controllers
+{
+    /// <summary>
+    /// 统一信息下发
+    /// </summary>
+    [Route("jt808webapi/UnificationSend")]
+    [ApiController]
+    public class JT808UnificationSendController : ControllerBase
+    {
+        // GET api/values
+        [HttpGet]
+        public ActionResult<IEnumerable<string>> Get()
+        {
+            return new string[] { "value1", "value2" };
+        }
+
+        // GET api/values/5
+        [HttpGet("{id}")]
+        public ActionResult<string> Get(int id)
+        {
+            return "value";
+        }
+
+        // POST api/values
+        [HttpPost]
+        public void Post([FromBody] string value)
+        {
+        }
+
+        // PUT api/values/5
+        [HttpPut("{id}")]
+        public void Put(int id, [FromBody] string value)
+        {
+        }
+
+        // DELETE api/values/5
+        [HttpDelete("{id}")]
+        public void Delete(int id)
+        {
+        }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/Dtos/JT808ResultDto.cs b/src/JT808.DotNetty.Dashbord/Dtos/JT808ResultDto.cs
new file mode 100644
index 0000000..cd3bdd7
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Dtos/JT808ResultDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Dashbord.Dtos
+{
+    public class JT808ResultDto<T>
+    {
+        public string Message { get; set; }
+
+        public int Code { get; set; }
+
+        public T Data { get; set; }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/Dtos/JT808SessionInfoDto.cs b/src/JT808.DotNetty.Dashbord/Dtos/JT808SessionInfoDto.cs
new file mode 100644
index 0000000..4759581
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Dtos/JT808SessionInfoDto.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Dashbord.Dtos
+{
+    public class JT808SessionInfoDto
+    {
+        /// <summary>
+        /// 通道Id
+        /// </summary>
+        public string ChannelId { get; set; }
+        /// <summary>
+        /// 最后上线时间
+        /// </summary>
+        public DateTime LastActiveTime { get; set; }
+        /// <summary>
+        /// 上线时间
+        /// </summary>
+        public DateTime StartTime { get; set; }
+        /// <summary>
+        /// 终端手机号
+        /// </summary>
+        public string TerminalPhoneNo { get; set; }
+        /// <summary>
+        /// 本地ip地址
+        /// </summary>
+        public string LoaclAddressIP { get; set; }
+        /// <summary>
+        /// WebApi端口号
+        /// </summary>
+        public int WebApiPort { get; set; }
+        /// <summary>
+        /// 远程ip地址
+        /// </summary>
+        public string RemoteAddressIP { get; set; }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/Dtos/JT808UnificationSendRequestDto.cs b/src/JT808.DotNetty.Dashbord/Dtos/JT808UnificationSendRequestDto.cs
new file mode 100644
index 0000000..5987dfa
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Dtos/JT808UnificationSendRequestDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT808.DotNetty.Dashbord.Dtos
+{
+    /// <summary>
+    /// 统一下发请求参数
+    /// </summary>
+    public class JT808UnificationSendRequestDto
+    {
+        public string TerminalPhoneNo { get; set; }
+        public byte[] Data { get; set; }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/JT808.DotNetty.Dashbord.csproj b/src/JT808.DotNetty.Dashbord/JT808.DotNetty.Dashbord.csproj
new file mode 100644
index 0000000..ffe2b91
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/JT808.DotNetty.Dashbord.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Folder Include="wwwroot\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.App" />
+    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
+  </ItemGroup>
+
+</Project>
diff --git a/src/JT808.DotNetty.Dashbord/Program.cs b/src/JT808.DotNetty.Dashbord/Program.cs
new file mode 100644
index 0000000..181342b
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Program.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+
+namespace JT808.DotNetty.Dashbord
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateWebHostBuilder(args).Build().Run();
+        }
+
+        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+            WebHost.CreateDefaultBuilder(args)
+                .UseStartup<Startup>();
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/Startup.cs b/src/JT808.DotNetty.Dashbord/Startup.cs
new file mode 100644
index 0000000..bd3750f
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/Startup.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace JT808.DotNetty.Dashbord
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseMvc();
+        }
+    }
+}
diff --git a/src/JT808.DotNetty.Dashbord/appsettings.Development.json b/src/JT808.DotNetty.Dashbord/appsettings.Development.json
new file mode 100644
index 0000000..e203e94
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}
diff --git a/src/JT808.DotNetty.Dashbord/appsettings.json b/src/JT808.DotNetty.Dashbord/appsettings.json
new file mode 100644
index 0000000..def9159
--- /dev/null
+++ b/src/JT808.DotNetty.Dashbord/appsettings.json
@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*"
+}
diff --git a/src/JT808.DotNetty.Test/JT808SessionManagerTest.cs b/src/JT808.DotNetty.Test/JT808SessionManagerTest.cs
index d722d52..95c7c2b 100644
--- a/src/JT808.DotNetty.Test/JT808SessionManagerTest.cs
+++ b/src/JT808.DotNetty.Test/JT808SessionManagerTest.cs
@@ -63,8 +63,7 @@ namespace JT808.DotNetty.Test
         [Fact]
         public void Test8()
         {
-            var realSessionInfos = jT808SessionManager.GetRealAll();
-            var relevanceSessionInfos = jT808SessionManager.GetRelevanceAll();
+            var realSessionInfos = jT808SessionManager.GetAll();
         }
 
         [Fact]
diff --git a/src/JT808.DotNetty.Test/JT808WebAPIServiceTest.cs b/src/JT808.DotNetty.Test/JT808WebAPIServiceTest.cs
index 4544f7c..f8fd2fa 100644
--- a/src/JT808.DotNetty.Test/JT808WebAPIServiceTest.cs
+++ b/src/JT808.DotNetty.Test/JT808WebAPIServiceTest.cs
@@ -41,155 +41,45 @@ namespace JT808.DotNetty.Test
         }
 
         [Fact]
-        public void GetRealLinkCountTest()
+        public void GetAllTest()
         {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRealLinkCount").Result;
-            string content = result.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content);
-            Assert.Equal(200, jt808Result.Code);
-            Assert.Equal(1,jt808Result.Data);
-        }
-
-        [Fact]
-        public void GetRelevanceLinkCountTest()
-        {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content = result.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content);
-            Assert.Equal(200, jt808Result.Code);
-            Assert.Equal(length, jt808Result.Data);
-        }
-
-        [Fact]
-        public void GetRealAllTest()
-        {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRealAll").Result;
+            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetAll").Result;
             string content = result.Content.ReadAsStringAsync().Result;
             JT808ResultDto<IEnumerable<JT808SessionInfoDto>> jt808Result = JsonConvert.DeserializeObject<JT808ResultDto<IEnumerable<JT808SessionInfoDto>>>(content);
             Assert.Equal(200, jt808Result.Code);
             Assert.Single(jt808Result.Data);
         }
 
-        [Fact]
-        public void GetRelevanceAllTest()
-        {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceAll").Result;
-            string content = result.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<IEnumerable<JT808SessionInfoDto>> jt808Result = JsonConvert.DeserializeObject<JT808ResultDto<IEnumerable<JT808SessionInfoDto>>>(content);
-            Assert.Equal(200, jt808Result.Code);
-            Assert.Equal(length,jt808Result.Data.Count());
-        }
-
         [Fact]
         public void RemoveByChannelIdTest()
         {
-            var result1 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content1 = result1.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result1 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content1);
-            Assert.Equal(200, jt808Result1.Code);
-            Assert.Equal(length, jt808Result1.Data);
-
             // 心跳会话包
             JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("99");
             SimpleTcpClient.WriteAsync(JT808Serializer.Serialize(jT808Package1));
 
-            var result2 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content2 = result2.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result2 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content2);
-            Assert.Equal(200, jt808Result2.Code);
-            Assert.Equal(length + 1, jt808Result2.Data);
-
-            var result3 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/GetByTerminalPhoneNo", new StringContent("99")).Result;
-            string content3 = result3.Content.ReadAsStringAsync().Result;
-
-            JT808ResultDto<JT808SessionInfoDto> jt808Result3 = JsonConvert.DeserializeObject<JT808ResultDto<JT808SessionInfoDto>>(content3);
-            Assert.Equal(200, jt808Result3.Code);
-            Assert.Equal("99", jt808Result3.Data.TerminalPhoneNo);
-
-            var result4 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/RemoveByChannelId", new StringContent(jt808Result3.Data.ChannelId)).Result;
+            var result4 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/RemoveByChannelId", new StringContent("")).Result;
             string content4 = result4.Content.ReadAsStringAsync().Result;
             JT808ResultDto<bool> jt808Result4= JsonConvert.DeserializeObject<JT808ResultDto<bool>>(content4);
             Assert.Equal(200, jt808Result4.Code);
             Assert.True(jt808Result4.Data);
-
-            var result5 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content5 = result5.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result5 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content5);
-            Assert.Equal(200, jt808Result5.Code);
-            Assert.Equal(length, jt808Result5.Data);
         }
 
 
         [Fact]
         public void RemoveByTerminalPhoneNoTest()
         {
-            var result1 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content1 = result1.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result1 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content1);
-            Assert.Equal(200, jt808Result1.Code);
-            Assert.Equal(length, jt808Result1.Data);
-
             // 心跳会话包
             JT808Package jT808Package1 = JT808.Protocol.Enums.JT808MsgId.终端心跳.Create("999");
             SimpleTcpClient.WriteAsync(JT808Serializer.Serialize(jT808Package1));
 
-            var result2 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content2 = result2.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result2 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content2);
-            Assert.Equal(200, jt808Result2.Code);
-            Assert.Equal(length + 1, jt808Result2.Data);
-
-            var result3 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/GetByTerminalPhoneNo", new StringContent("999")).Result;
-            string content3 = result3.Content.ReadAsStringAsync().Result;
-
-            JT808ResultDto<JT808SessionInfoDto> jt808Result3 = JsonConvert.DeserializeObject<JT808ResultDto<JT808SessionInfoDto>>(content3);
-            Assert.Equal(200, jt808Result3.Code);
-            Assert.Equal("999", jt808Result3.Data.TerminalPhoneNo);
 
             var result4 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/RemoveByTerminalPhoneNo", new StringContent("999")).Result;
             string content4 = result4.Content.ReadAsStringAsync().Result;
             JT808ResultDto<bool> jt808Result4 = JsonConvert.DeserializeObject<JT808ResultDto<bool>>(content4);
             Assert.Equal(200, jt808Result4.Code);
             Assert.True(jt808Result4.Data);
-
-            var result5 = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceLinkCount").Result;
-            string content5 = result5.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<int> jt808Result5 = JsonConvert.DeserializeObject<JT808ResultDto<int>>(content5);
-            Assert.Equal(200, jt808Result5.Code);
-            Assert.Equal(length, jt808Result5.Data);
-        }
-
-        [Fact]
-        public void GetByChannelIdTest()
-        {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRealAll").Result;
-            string content = result.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<IEnumerable<JT808SessionInfoDto>> jt808Result1 = JsonConvert.DeserializeObject<JT808ResultDto<IEnumerable<JT808SessionInfoDto>>>(content);
-            var sessionInfo1 = jt808Result1.Data.FirstOrDefault();
-
-            var result2 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/GetByChannelId",new StringContent(sessionInfo1.ChannelId)).Result;
-            string content2 = result2.Content.ReadAsStringAsync().Result;
-
-            JT808ResultDto<JT808SessionInfoDto> jt808Result2 = JsonConvert.DeserializeObject<JT808ResultDto<JT808SessionInfoDto>>(content2);
-            Assert.Equal(200, jt808Result2.Code);
-            Assert.Equal(sessionInfo1.ChannelId, jt808Result2.Data.ChannelId);
         }
 
-        [Fact]
-        public void GetByTerminalPhoneNoTest()
-        {
-            var result = httpClient.GetAsync($"{Url}/{sessionRoutePrefix}/GetRelevanceAll").Result;
-            string content = result.Content.ReadAsStringAsync().Result;
-            JT808ResultDto<IEnumerable<JT808SessionInfoDto>> jt808Result1 = JsonConvert.DeserializeObject<JT808ResultDto<IEnumerable<JT808SessionInfoDto>>>(content);
-            var sessionInfo1 = jt808Result1.Data.FirstOrDefault();
-
-            var result2 = httpClient.PostAsync($"{Url}/{sessionRoutePrefix}/GetByTerminalPhoneNo", new StringContent(sessionInfo1.TerminalPhoneNo)).Result;
-            string content2 = result2.Content.ReadAsStringAsync().Result;
-
-            JT808ResultDto<JT808SessionInfoDto> jt808Result2 = JsonConvert.DeserializeObject<JT808ResultDto<JT808SessionInfoDto>>(content2);
-            Assert.Equal(200, jt808Result2.Code);
-            Assert.Equal(sessionInfo1.TerminalPhoneNo, jt808Result2.Data.TerminalPhoneNo);
-        }
 
         public override void Dispose()
         {
diff --git a/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs b/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs
index e50a69a..c57be31 100644
--- a/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs
+++ b/src/JT808.DotNetty/Dtos/JT808SessionInfoDto.cs
@@ -22,5 +22,17 @@ namespace JT808.DotNetty.Dtos
         /// 终端手机号
         /// </summary>
         public string TerminalPhoneNo { get; set; }
+        /// <summary>
+        /// 本地ip地址
+        /// </summary>
+        public string LoaclAddressIP { get; set; }
+        /// <summary>
+        /// WebApi端口号
+        /// </summary>
+        public int WebApiPort { get; set; }
+        /// <summary>
+        /// 远程ip地址
+        /// </summary>
+        public string RemoteAddressIP { get; set; }
     }
 }
diff --git a/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
index e08083c..5edd314 100644
--- a/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
+++ b/src/JT808.DotNetty/Interfaces/IJT808SessionService.cs
@@ -11,25 +11,10 @@ namespace JT808.DotNetty.Interfaces
     internal interface IJT808SessionService
     {
         /// <summary>
-        /// 获取真实连接数
+        /// 获取会话集合
         /// </summary>
         /// <returns></returns>
-        JT808ResultDto<int> GetRealLinkCount();
-        /// <summary>
-        /// 获取设备相关连的连接数
-        /// </summary>
-        /// <returns></returns>
-        JT808ResultDto<int> GetRelevanceLinkCount();
-        /// <summary>
-        /// 获取实际会话集合
-        /// </summary>
-        /// <returns></returns>
-        JT808ResultDto<List<JT808SessionInfoDto>> GetRealAll();
-        /// <summary>
-        /// 获取设备相关联会话集合
-        /// </summary>
-        /// <returns></returns>
-        JT808ResultDto<List<JT808SessionInfoDto>> GetRelevanceAll();
+        JT808ResultDto<List<JT808SessionInfoDto>> GetAll();
         /// <summary>
         /// 通过通道Id移除对应会话
         /// </summary>
@@ -42,17 +27,5 @@ namespace JT808.DotNetty.Interfaces
         /// <param name="terminalPhoneNo"></param>
         /// <returns></returns>
         JT808ResultDto<bool> RemoveByTerminalPhoneNo(string terminalPhoneNo);
-        /// <summary>
-        /// 通过通道Id获取会话信息
-        /// </summary>
-        /// <param name="channelId"></param>
-        /// <returns></returns>
-        JT808ResultDto<JT808SessionInfoDto> GetByChannelId(string channelId);
-        /// <summary>
-        /// 通过设备终端号获取会话信息
-        /// </summary>
-        /// <param name="terminalPhoneNo"></param>
-        /// <returns></returns>
-        JT808ResultDto<JT808SessionInfoDto> GetByTerminalPhoneNo(string terminalPhoneNo);
     }
 }
diff --git a/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs b/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs
index 95365bb..a4b558c 100644
--- a/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs
+++ b/src/JT808.DotNetty/Internal/JT808SessionServiceDefaultImpl.cs
@@ -5,6 +5,8 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Runtime.CompilerServices;
+using Microsoft.Extensions.Options;
+using JT808.DotNetty.Configurations;
 
 namespace JT808.DotNetty.Internal
 {
@@ -12,104 +14,30 @@ namespace JT808.DotNetty.Internal
     {
         private readonly JT808SessionManager jT808SessionManager;
 
-        public JT808SessionServiceDefaultImpl(JT808SessionManager jT808SessionManager)
-        {
-            this.jT808SessionManager = jT808SessionManager;
-        }
-
-        public JT808ResultDto<JT808SessionInfoDto> GetByChannelId(string channelId)
-        {
-            JT808ResultDto<JT808SessionInfoDto> resultDto = new JT808ResultDto<JT808SessionInfoDto>();
-            try
-            {
-                var result = jT808SessionManager.GetSessionByID(channelId);
-                JT808SessionInfoDto jT808SessionInfoDto = new JT808SessionInfoDto
-                {
-                    TerminalPhoneNo = result.TerminalPhoneNo,
-                    ChannelId=result.SessionID,
-                    LastActiveTime=result.LastActiveTime,
-                    StartTime=result.StartTime
-                };
-                resultDto.Code = 200;
-                resultDto.Data = jT808SessionInfoDto;
-            }
-            catch (Exception ex)
-            {
-                resultDto.Data = null;
-                resultDto.Code = 500;
-                resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
-            }
-            return resultDto;
-        }
+        private readonly JT808Configuration jT808Configuration;
 
-        public JT808ResultDto<int> GetRelevanceLinkCount()
+        public JT808SessionServiceDefaultImpl(
+            IOptions<JT808Configuration> jT808ConfigurationAccssor,
+            JT808SessionManager jT808SessionManager)
         {
-            JT808ResultDto<int> resultDto = new JT808ResultDto<int>();
-            try
-            {
-                resultDto.Data = jT808SessionManager.RelevanceSessionCount;
-                resultDto.Code = 200;
-            }
-            catch (Exception ex)
-            {
-                resultDto.Data = 0;
-                resultDto.Code = 500;
-                resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
-            }
-            return resultDto;
-        }
-
-        public JT808ResultDto<int> GetRealLinkCount()
-        {
-            JT808ResultDto<int> resultDto = new JT808ResultDto<int>();
-            try
-            {
-                resultDto.Data = jT808SessionManager.RealSessionCount;
-                resultDto.Code = 200;
-            }
-            catch (Exception ex)
-            {
-                resultDto.Data = 0;
-                resultDto.Code = 500;
-                resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
-            }
-            return resultDto;
-        }
-
-        public JT808ResultDto<List<JT808SessionInfoDto>> GetRealAll()
-        {
-            JT808ResultDto<List<JT808SessionInfoDto>> resultDto = new JT808ResultDto<List<JT808SessionInfoDto>>();
-            try
-            {
-                resultDto.Data = jT808SessionManager.GetRealAll().Select(s => new JT808SessionInfoDto
-                {
-                    ChannelId = s.SessionID,
-                    LastActiveTime = s.LastActiveTime,
-                    StartTime = s.StartTime,
-                    TerminalPhoneNo = s.TerminalPhoneNo
-                }).ToList();
-                resultDto.Code = 200;
-            }
-            catch (Exception ex)
-            {
-                resultDto.Data = null;
-                resultDto.Code = 500;
-                resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
-            }
-            return resultDto;
+            this.jT808SessionManager = jT808SessionManager;
+            this.jT808Configuration = jT808ConfigurationAccssor.Value;
         }
 
-        public JT808ResultDto<List<JT808SessionInfoDto>> GetRelevanceAll()
+        public JT808ResultDto<List<JT808SessionInfoDto>> GetAll()
         {
             JT808ResultDto<List<JT808SessionInfoDto>> resultDto = new JT808ResultDto<List<JT808SessionInfoDto>>();
             try
             {
-                resultDto.Data = jT808SessionManager.GetRelevanceAll().Select(s => new JT808SessionInfoDto
+                resultDto.Data = jT808SessionManager.GetAll().Select(s => new JT808SessionInfoDto
                 {
                     ChannelId = s.SessionID,
                     LastActiveTime = s.LastActiveTime,
                     StartTime = s.StartTime,
-                    TerminalPhoneNo = s.TerminalPhoneNo
+                    TerminalPhoneNo = s.TerminalPhoneNo,
+                    WebApiPort = jT808Configuration.WebAPIPort,
+                    LoaclAddressIP = s.Channel.LocalAddress.ToString(),
+                    RemoteAddressIP = s.Channel.RemoteAddress.ToString(),
                 }).ToList();
                 resultDto.Code = 200;
             }
@@ -177,30 +105,5 @@ namespace JT808.DotNetty.Internal
             }
             return resultDto;
         }
-
-        public JT808ResultDto<JT808SessionInfoDto> GetByTerminalPhoneNo(string terminalPhoneNo)
-        {
-            JT808ResultDto<JT808SessionInfoDto> resultDto = new JT808ResultDto<JT808SessionInfoDto>();
-            try
-            {
-                var result = jT808SessionManager.GetSessionByTerminalPhoneNo(terminalPhoneNo);
-                JT808SessionInfoDto jT808SessionInfoDto = new JT808SessionInfoDto
-                {
-                    TerminalPhoneNo = result.TerminalPhoneNo,
-                    ChannelId = result.SessionID,
-                    LastActiveTime = result.LastActiveTime,
-                    StartTime = result.StartTime
-                };
-                resultDto.Code = 200;
-                resultDto.Data = jT808SessionInfoDto;
-            }
-            catch (Exception ex)
-            {
-                resultDto.Data = null;
-                resultDto.Code = 500;
-                resultDto.Message = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
-            }
-            return resultDto;
-        }
     }
 }
diff --git a/src/JT808.DotNetty/JT808.DotNetty.xml b/src/JT808.DotNetty/JT808.DotNetty.xml
new file mode 100644
index 0000000..f19c8ef
--- /dev/null
+++ b/src/JT808.DotNetty/JT808.DotNetty.xml
@@ -0,0 +1,323 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>JT808.DotNetty</name>
+    </assembly>
+    <members>
+        <member name="T:JT808.DotNetty.Codecs.JT808ClientDecoder">
+            <summary>
+            JT808客户端解码(测试客户端)
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Codecs.JT808Decoder">
+            <summary>
+            JT808解码
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Configurations.JT808Configuration.WebAPIPort">
+            <summary>
+            WebAPI服务
+            默认828端口
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Configurations.JT808Configuration.SourcePackageDispatcherClientConfigurations">
+            <summary>
+            源包分发器配置
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.ChannelId">
+            <summary>
+            通道Id
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.LastActiveTime">
+            <summary>
+            最后上线时间
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.StartTime">
+            <summary>
+            上线时间
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.TerminalPhoneNo">
+            <summary>
+            终端手机号
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.LoaclAddressIP">
+            <summary>
+            本地ip地址
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.WebApiPort">
+            <summary>
+            WebApi端口号
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Dtos.JT808SessionInfoDto.RemoteAddressIP">
+            <summary>
+            远程ip地址
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Dtos.JT808UnificationSendRequestDto">
+            <summary>
+            统一下发请求参数
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.Handlers.JT808ConnectionHandler.ChannelActive(DotNetty.Transport.Channels.IChannelHandlerContext)">
+            <summary>
+            通道激活
+            </summary>
+            <param name="context"></param>
+        </member>
+        <member name="M:JT808.DotNetty.Handlers.JT808ConnectionHandler.ChannelInactive(DotNetty.Transport.Channels.IChannelHandlerContext)">
+            <summary>
+            设备主动断开
+            </summary>
+            <param name="context"></param>
+        </member>
+        <member name="M:JT808.DotNetty.Handlers.JT808ConnectionHandler.CloseAsync(DotNetty.Transport.Channels.IChannelHandlerContext)">
+            <summary>
+            服务器主动断开
+            </summary>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.Handlers.JT808ConnectionHandler.UserEventTriggered(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)">
+            <summary>
+            超时策略
+            </summary>
+            <param name="context"></param>
+            <param name="evt"></param>
+        </member>
+        <member name="T:JT808.DotNetty.Handlers.JT808WebAPIServerHandler">
+            <summary>
+            jt808 webapi服务
+            请求量不大,只支持JSON格式并且只支持post发数据
+            ref: dotnetty HttpServer
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Interfaces.IJT808SessionService">
+            <summary>
+            JT808会话服务
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.Interfaces.IJT808SessionService.GetAll">
+            <summary>
+            获取会话集合
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.Interfaces.IJT808SessionService.RemoveByChannelId(System.String)">
+            <summary>
+            通过通道Id移除对应会话
+            </summary>
+            <param name="channelId"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.Interfaces.IJT808SessionService.RemoveByTerminalPhoneNo(System.String)">
+            <summary>
+            通过设备终端号移除对应会话
+            </summary>
+            <param name="terminalPhoneNo"></param>
+            <returns></returns>
+        </member>
+        <member name="T:JT808.DotNetty.Interfaces.IJT808SourcePackageDispatcher">
+            <summary>
+            源包分发器
+            自定义源包分发器业务
+            ConfigureServices:
+            services.Replace(new ServiceDescriptor(typeof(IJT808SourcePackageDispatcher),typeof(JT808SourcePackageDispatcherDefaultImpl),ServiceLifetime.Singleton));
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Interfaces.IJT808UnificationSendService">
+            <summary>
+            JT808统一下发命令
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Internal.JT808AtomicCounterService">
+            <summary>
+            计数包服务
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Internal.JT808MsgIdDefaultHandler">
+            <summary>
+            默认消息处理业务实现
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.Internal.JT808SourcePackageDispatcherDefaultImpl">
+            <summary>
+            源包分发器默认实现
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.Internal.JT808SourcePackageDispatcherDefaultImpl.DelRemoteServsers(System.Collections.Generic.List{JT808.DotNetty.Configurations.JT808ClientConfiguration})">
+            <summary>
+            动态删除远程服务器
+            </summary>
+            <param name="chgRemoteServers"></param>
+        </member>
+        <member name="M:JT808.DotNetty.Internal.JT808SourcePackageDispatcherDefaultImpl.AddRemoteServsers(System.Collections.Generic.List{JT808.DotNetty.Configurations.JT808ClientConfiguration})">
+            <summary>
+            动态添加远程服务器
+            </summary>
+            <param name="bootstrap"></param>
+            <param name="chgRemoteServers"></param>
+        </member>
+        <member name="T:JT808.DotNetty.JT808MsgIdHandlerBase">
+            <summary>
+            抽象消息处理业务
+            自定义消息处理业务
+            ConfigureServices:
+            services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHandlerBase),typeof(JT808MsgIdCustomHandlerImpl),ServiceLifetime.Singleton));
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.#ctor(JT808.DotNetty.JT808SessionManager)">
+            <summary>
+            初始化消息处理业务
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0001(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            终端通用应答
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0002(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            终端心跳
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0003(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            终端注销
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0100(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            终端注册
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0102(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            终端鉴权
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0200(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            位置信息汇报
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0704(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            定位数据批量上传
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808MsgIdHandlerBase.Msg0x0900(JT808.DotNetty.Metadata.JT808Request)">
+            <summary>
+            数据上行透传
+            </summary>
+            <param name="reqJT808Package"></param>
+            <param name="ctx"></param>
+            <returns></returns>
+        </member>
+        <member name="F:JT808.DotNetty.JT808SessionManager.SessionIdDict">
+            <summary>
+            Netty生成的sessionID和Session的对应关系
+            key = seession id
+            value = Session
+            </summary>
+        </member>
+        <member name="F:JT808.DotNetty.JT808SessionManager.TerminalPhoneNo_SessionId_Dict">
+            <summary>
+            终端手机号和netty生成的sessionID的对应关系
+            key = 终端手机号
+            value = seession id
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.JT808SessionManager.RealSessionCount">
+            <summary>
+            获取实际连接数
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.JT808SessionManager.RelevanceSessionCount">
+            <summary>
+            获取设备相关连的连接数
+            </summary>
+        </member>
+        <member name="T:JT808.DotNetty.JT808WebAPIServerHost">
+            <summary>
+            集成一个webapi服务
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.JT808WebAPIService.#ctor(JT808.DotNetty.Interfaces.IJT808SessionService,JT808.DotNetty.Interfaces.IJT808UnificationSendService)">
+            <summary>
+            初始化消息处理业务
+            </summary>
+        </member>
+        <member name="M:JT808.DotNetty.JT808WebAPIService.UnificationSend(JT808.DotNetty.Metadata.JT808HttpRequest)">
+            <summary>
+            统一下发信息
+            </summary>
+            <param name="request"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808WebAPIService.GetAll(JT808.DotNetty.Metadata.JT808HttpRequest)">
+            <summary>
+            会话服务集合
+            </summary>
+            <param name="request"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808WebAPIService.RemoveByChannelId(JT808.DotNetty.Metadata.JT808HttpRequest)">
+            <summary>
+            会话服务-通过通道Id移除对应会话
+            </summary>
+            <param name="request"></param>
+            <returns></returns>
+        </member>
+        <member name="M:JT808.DotNetty.JT808WebAPIService.RemoveByTerminalPhoneNo(JT808.DotNetty.Metadata.JT808HttpRequest)">
+            <summary>
+            会话服务-通过设备终端号移除对应会话
+            </summary>
+            <param name="request"></param>
+            <returns></returns>
+        </member>
+        <member name="T:JT808.DotNetty.Metadata.JT808AtomicCounter">
+            <summary>
+            
+            <see cref="!:Grpc.Core.Internal"/>
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Metadata.JT808Response.MinBufferSize">
+            <summary>
+            根据实际情况适当调整包的大小
+            </summary>
+        </member>
+        <member name="P:JT808.DotNetty.Metadata.JT808Session.TerminalPhoneNo">
+            <summary>
+            终端手机号
+            </summary>
+        </member>
+    </members>
+</doc>
diff --git a/src/JT808.DotNetty/JT808DotnettyExtensions.cs b/src/JT808.DotNetty/JT808DotnettyExtensions.cs
index b89a9d9..ee833dc 100644
--- a/src/JT808.DotNetty/JT808DotnettyExtensions.cs
+++ b/src/JT808.DotNetty/JT808DotnettyExtensions.cs
@@ -6,6 +6,7 @@ using JT808.DotNetty.Internal;
 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;
@@ -15,6 +16,20 @@ namespace JT808.DotNetty
 {
     public static class JT808DotnettyExtensions
     {
+        static JT808DotnettyExtensions()
+        {
+            JsonSerializerSettings setting = new JsonSerializerSettings();
+            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
+            {
+                //日期类型默认格式化处理
+                setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+                setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
+                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
+                setting.NullValueHandling = NullValueHandling.Include;
+                return setting;
+            });
+        }
+
         public static IHostBuilder UseJT808Host(this IHostBuilder builder)
         {
             return builder.ConfigureServices((hostContext, services) =>
diff --git a/src/JT808.DotNetty/JT808SessionManager.cs b/src/JT808.DotNetty/JT808SessionManager.cs
index d58df46..9748b16 100644
--- a/src/JT808.DotNetty/JT808SessionManager.cs
+++ b/src/JT808.DotNetty/JT808SessionManager.cs
@@ -1,12 +1,8 @@
 using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
 using JT808.DotNetty.Metadata;
 
 namespace JT808.DotNetty
@@ -35,7 +31,7 @@ namespace JT808.DotNetty
         private ConcurrentDictionary<string, string> TerminalPhoneNo_SessionId_Dict = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
         /// <summary>
-        /// 实际连接数
+        /// 获取实际连接数
         /// </summary>
         public int RealSessionCount
         {
@@ -121,8 +117,8 @@ namespace JT808.DotNetty
 
         public void TryAddOrUpdateSession(JT808Session appSession)
         {
-            SessionIdDict.AddOrUpdate(appSession.SessionID, appSession, (x, y) => appSession);
-            TerminalPhoneNo_SessionId_Dict.AddOrUpdate(appSession.TerminalPhoneNo, appSession.SessionID, (x, y) => appSession.SessionID);
+            SessionIdDict.TryAdd(appSession.SessionID, appSession);
+            TerminalPhoneNo_SessionId_Dict.TryAdd(appSession.TerminalPhoneNo, appSession.SessionID);
         }
 
         public JT808Session RemoveSessionByID(string sessionID)
@@ -132,17 +128,13 @@ namespace JT808.DotNetty
             {
                 if (SessionIdDict.TryRemove(sessionID, out JT808Session session))
                 {
-                    if (session.TerminalPhoneNo != null)
+                    // 处理转发过来的是数据 这时候通道对设备是1对多关系
+                    var removeKeys = TerminalPhoneNo_SessionId_Dict.Where(s => s.Value == sessionID).Select(s => s.Key).ToList();
+                    foreach(var key in removeKeys)
                     {
-                        if (TerminalPhoneNo_SessionId_Dict.TryRemove(session.TerminalPhoneNo, out string sessionid))
-                        {
-                            logger.LogInformation($">>>{sessionID}-{session.TerminalPhoneNo} Session Remove.");
-                        }
-                    }
-                    else
-                    {
-                        logger.LogInformation($">>>{sessionID} Session Remove.");
+                        TerminalPhoneNo_SessionId_Dict.TryRemove(key, out string sessionid);
                     }
+                    logger.LogInformation($">>>{sessionID}-{string.Join(",",removeKeys)} Session Remove.");
                     return session;
                 }
                 return null;
@@ -161,9 +153,19 @@ namespace JT808.DotNetty
             {
                 if (TerminalPhoneNo_SessionId_Dict.TryRemove(terminalPhoneNo, out string sessionid))
                 {
+                    // 处理转发过来的是数据 这时候通道对设备是1对多关系
+                    var removeKeys = TerminalPhoneNo_SessionId_Dict.Where(w => w.Value == sessionid).Select(s=>s.Key).ToList();
+                    if (removeKeys.Count > 0)
+                    {
+                        foreach (var key in removeKeys)
+                        {
+                            TerminalPhoneNo_SessionId_Dict.TryRemove(key, out string sessionid1);
+                        }
+                        logger.LogInformation($">>>{sessionid}-{string.Join(",", removeKeys)} 1-n Session Remove.");
+                    }
                     if (SessionIdDict.TryRemove(sessionid, out JT808Session session))
                     {
-                        logger.LogInformation($">>>{sessionid}-{session.TerminalPhoneNo} Session Remove.");
+                        logger.LogInformation($">>>{sessionid}-{session.TerminalPhoneNo} 1-1 Session Remove.");
                         return session;
                     }
                     else
@@ -179,16 +181,17 @@ namespace JT808.DotNetty
             return null;
         }
 
-        public IEnumerable<JT808Session> GetRealAll()
-        {
-            return SessionIdDict.Select(s=>s.Value);
-        }
-
-        public IEnumerable<JT808Session> GetRelevanceAll()
+        public IEnumerable<JT808Session> GetAll()
         {
-            return SessionIdDict.Join(TerminalPhoneNo_SessionId_Dict, m => m.Key, s => s.Value, (m, s) => m.Value);
+            return TerminalPhoneNo_SessionId_Dict.Join(SessionIdDict, m => m.Value, s => s.Key, (m, s) => new JT808Session
+            {
+                Channel= s.Value.Channel,
+                LastActiveTime= s.Value.LastActiveTime,
+                SessionID= s.Value.SessionID,
+                StartTime= s.Value.StartTime,
+                TerminalPhoneNo= m.Key
+            }).ToList();
         }
-      
     }
 }
 
diff --git a/src/JT808.DotNetty/JT808WebAPIService.cs b/src/JT808.DotNetty/JT808WebAPIService.cs
index 876cb6f..05e0ce8 100644
--- a/src/JT808.DotNetty/JT808WebAPIService.cs
+++ b/src/JT808.DotNetty/JT808WebAPIService.cs
@@ -32,14 +32,9 @@ namespace JT808.DotNetty
             HandlerDict = new Dictionary<string, Func<JT808HttpRequest, JT808HttpResponse>>
             {
                 {$"{RouteTablePrefix}/UnificationSend", UnificationSend},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRealLinkCount", GetRealLinkCount},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRelevanceLinkCount", GetRelevanceLinkCount},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRealAll", GetRealAll},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetRelevanceAll", GetRelevanceAll},
+                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetAll", GetAll},
                 {$"{RouteTablePrefix}/{sessionRoutePrefix}/RemoveByChannelId", RemoveByChannelId},
                 {$"{RouteTablePrefix}/{sessionRoutePrefix}/RemoveByTerminalPhoneNo", RemoveByTerminalPhoneNo},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetByChannelId", GetByChannelId},
-                {$"{RouteTablePrefix}/{sessionRoutePrefix}/GetByTerminalPhoneNo", GetByTerminalPhoneNo},
             };
         }
 
@@ -60,47 +55,13 @@ namespace JT808.DotNetty
         }
 
         /// <summary>
-        /// 会话服务-获取实际连接数
-        /// 存在其他平台转发过来的数据,这时候通道Id和设备属于一对多的关系
+        /// 会话服务集合
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
-        public JT808HttpResponse GetRealLinkCount(JT808HttpRequest request)
+        public JT808HttpResponse GetAll(JT808HttpRequest request)
         {
-            var result = jT808SessionService.GetRealLinkCount();
-            return CreateJT808HttpResponse(result);
-        }
-
-        /// <summary>
-        /// 会话服务-获取设备相关连的连接数
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public JT808HttpResponse GetRelevanceLinkCount(JT808HttpRequest request)
-        {
-            var result = jT808SessionService.GetRelevanceLinkCount();
-            return CreateJT808HttpResponse(result);
-        }
-
-        /// <summary>
-        /// 会话服务-获取实际会话集合
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public JT808HttpResponse GetRealAll(JT808HttpRequest request)
-        {
-            var result = jT808SessionService.GetRealAll();
-            return CreateJT808HttpResponse(result);
-        }
-
-        /// <summary>
-        /// 会话服务-获取设备相关连会话集合
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public JT808HttpResponse GetRelevanceAll(JT808HttpRequest request)
-        {
-            var result = jT808SessionService.GetRelevanceAll();
+            var result = jT808SessionService.GetAll();
             return CreateJT808HttpResponse(result);
         }
 
@@ -134,36 +95,6 @@ namespace JT808.DotNetty
             return CreateJT808HttpResponse(result);
         }
 
-        /// <summary>
-        /// 会话服务-通过通道Id获取会话信息
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public JT808HttpResponse GetByChannelId(JT808HttpRequest request)
-        {
-            if (string.IsNullOrEmpty(request.Json))
-            {
-                return EmptyHttpResponse();
-            }
-            var result = jT808SessionService.GetByChannelId(request.Json);
-            return CreateJT808HttpResponse(result);
-        }
-
-        /// <summary>
-        /// 会话服务-通过设备终端号获取会话信息
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public JT808HttpResponse GetByTerminalPhoneNo(JT808HttpRequest request)
-        {
-            if (string.IsNullOrEmpty(request.Json))
-            {
-                return EmptyHttpResponse();
-            }
-            var result = jT808SessionService.GetByTerminalPhoneNo(request.Json);
-            return CreateJT808HttpResponse(result);
-        }
-
         private JT808HttpResponse CreateJT808HttpResponse(dynamic dynamicObject)
         {
             byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(dynamicObject));
diff --git a/src/JT808.DotNetty/Metadata/JT808Session.cs b/src/JT808.DotNetty/Metadata/JT808Session.cs
index 0c3af26..9d5e5a2 100644
--- a/src/JT808.DotNetty/Metadata/JT808Session.cs
+++ b/src/JT808.DotNetty/Metadata/JT808Session.cs
@@ -24,17 +24,19 @@ namespace JT808.DotNetty.Metadata
             SessionID = Channel.Id.AsShortText();
         }
 
+        public JT808Session() { }
+
         /// <summary>
         /// 终端手机号
         /// </summary>
         public string TerminalPhoneNo { get; set; }
 
-        public string SessionID { get; }
+        public string SessionID { get; set; }
 
-        public IChannel Channel { get; }
+        public IChannel Channel { get; set; }
 
         public DateTime LastActiveTime { get; set; }
 
-        public DateTime StartTime { get; }
+        public DateTime StartTime { get; set; }
     }
 }