@@ -12,7 +12,7 @@ jobs: | |||||
- name: Setup .NET Core | - name: Setup .NET Core | ||||
uses: actions/setup-dotnet@master | uses: actions/setup-dotnet@master | ||||
with: | with: | ||||
dotnet-version: 7.0.100 | |||||
dotnet-version: 7.0.203 | |||||
- name: dotnet info | - name: dotnet info | ||||
run: dotnet --info | run: dotnet --info | ||||
- name: dotnet JT808.Gateway restore | - name: dotnet JT808.Gateway restore | ||||
@@ -1,8 +1,6 @@ | |||||
# JT808Gateway | # JT808Gateway | ||||
基于Pipeline封装的JT808Pipeline支持TCP/UDP通用消息业务处理 | |||||
基于DotNetty封装的JT808DotNetty支持TCP/UDP通用消息业务处理 | |||||
JT808Pipeline支持TCP/UDP通用消息业务处理 | |||||
[了解JT808协议进这边](https://github.com/SmallChi/JT808) | [了解JT808协议进这边](https://github.com/SmallChi/JT808) | ||||
@@ -42,26 +40,13 @@ | |||||
> 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 | > 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 | ||||
## 基于网关的相关服务 | |||||
| 服务名称 | 服务说明 | 使用场景 | | |||||
| :-------------------------------- | :----------- | :----------------------------------------------------------------------------------------------------------------- | | |||||
| MsgIdHandler | 消息处理服务 | 从队列中消费设备上报数据,再结合自身的业务场景,将数据进行处理并入库 | | |||||
| MsgLogging | 消息日志服务 | 从队列中消费设备上报和平台应答数据,再将数据存入influxdb等数据库中,便于技术和技术支持排查设备与平台交互的原始数据 | | |||||
| ReplyMessage | 消息响应服务 | 用于响应设备上报消息,以及下发指令信息到设备 | | |||||
| SessionNotice | 会话管理服务 | 通知设备上线下线,对于udp设备来说,可以在设备上线时,将指令跟随消息下发到设备 | | |||||
| Traffic (v1.1.0新版pipeline已移出) | 流量统计服务 | 由于运营商sim卡查询流量滞后,通过流量统计服务可以实时准确的统计设备流量,可以最优配置设备的流量大小,以节省成本 | | |||||
| Transmit | 原包转发服务 | 该服务可以将设备上报原始数据转发到第三方,支持全部转发,指定终端号转发 | | |||||
## 基于WebApi的消息业务处理程序 | ## 基于WebApi的消息业务处理程序 | ||||
通过继承JT808.DotNetty.Core.Handlers.JT808MsgIdHttpHandlerBase去实现自定义的WebApi接口服务。 | |||||
通过继承JT808.Gateway.Handlers.JT808MsgIdDefaultWebApiHandler去实现自定义的WebApi接口服务。 | 通过继承JT808.Gateway.Handlers.JT808MsgIdDefaultWebApiHandler去实现自定义的WebApi接口服务。 | ||||
[接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api) | [接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api) | ||||
## 基于NET5.0 Pipeline | |||||
## 基于Pipeline | |||||
Pipeline分为两种方式使用,一种是使用队列的方式,一种是网关集成的方式。 | Pipeline分为两种方式使用,一种是使用队列的方式,一种是网关集成的方式。 | ||||
@@ -78,33 +63,7 @@ Pipeline分为两种方式使用,一种是使用队列的方式,一种是网 | |||||
| Install-Package JT808.Gateway |  |  |  | | | Install-Package JT808.Gateway |  |  |  | | ||||
| Install-Package JT808.Gateway.WebApiClientTool |  |  |  | | | Install-Package JT808.Gateway.WebApiClientTool |  |  |  | | ||||
| Install-Package JT808.Gateway.Client |  |  |  | | | Install-Package JT808.Gateway.Client |  |  |  | | ||||
| Install-Package JT808.Gateway.Kafka |  |  |  | | |||||
| Install-Package JT808.Gateway.Transmit |  |  |  | | |||||
| Install-Package JT808.Gateway.SessionNotice |  |  |  | | |||||
| Install-Package JT808.Gateway.ReplyMessage |  |  |  | | |||||
| Install-Package JT808.Gateway.MsgLogging |  |  |  | | |||||
| Install-Package JT808.Gateway.MsgIdHandler |  |  |  | | |||||
## 基于DotNetty | |||||
### DotNetty的NuGet安装 | |||||
| Package Name| Version |Preview Version | Downloads| | |||||
| --- | --- | ---| ---| | |||||
| Install-Package JT808.DotNetty.Abstractions | |  |  | | |||||
| Install-Package JT808.DotNetty.Core |  |  |  | | |||||
| Install-Package JT808.DotNetty.Tcp |  |  |  | | |||||
| Install-Package JT808.DotNetty.Udp |  |  |  | | |||||
| Install-Package JT808.DotNetty.WebApi |  |  |  | | |||||
| Install-Package JT808.DotNetty.WebApiClientTool |  |  |  | | |||||
| Install-Package JT808.DotNetty.Client |  |  |  | | |||||
| Install-Package JT808.DotNetty.Transmit |  |  |  | | |||||
| Install-Package JT808.DotNetty.Traffic |  |  |  | | |||||
| Install-Package JT808.DotNetty.SessionNotice | |  |  | | |||||
| Install-Package JT808.DotNetty.ReplyMessage |  |  |  | | |||||
| Install-Package JT808.DotNetty.MsgLogging |  |  |  ||  | |||||
| Install-Package JT808.DotNetty.MsgIdHandler |  |  |  | | |||||
| Install-Package JT808.DotNetty.Kafka |  |  |  |  | | |||||
| Install-Package JT808.Gateway.Kafka |  |  |  | | |||||
## 举个栗子 | ## 举个栗子 | ||||
@@ -139,17 +98,6 @@ Pipeline分为两种方式使用,一种是使用队列的方式,一种是网 | |||||
如图所示: | 如图所示: | ||||
 |  | ||||
### DotNetty | |||||
1.打开/simples/JT808.Simples.sln项目进行还原编译生成 | |||||
2.进入JT808.DotNetty.SimpleServer项目下的Debug目录运行服务端 | |||||
3.进入JT808.DotNetty.SimpleClient项目下的Debug目录运行客户端 | |||||
如图所示: | |||||
 | |||||
## 常见问题 | ## 常见问题 | ||||
- 多协议兼容实现思路[点我查看](https://github.com/SmallChi/JT808Gateway/issues/11#issuecomment-727687417) | - 多协议兼容实现思路[点我查看](https://github.com/SmallChi/JT808Gateway/issues/11#issuecomment-727687417) | ||||
@@ -1,5 +1,541 @@ | |||||
# JT808 WebApi 接口文档 | |||||
# 基于JT808Gateway WebApi 接口文档 | |||||
[基于JT808Gateway WebApi接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api/README_Pipeline.md) | |||||
基地址:127.0.0.1:828/jt808api/ | |||||
[基于JT808DotNetty WebApi接口文档](https://github.com/SmallChi/JT808Gateway/tree/master/api/README_DotNetty.md) | |||||
> 注意url格式 | |||||
数据格式:只支持Json格式 | |||||
默认端口:828 | |||||
## 1.统一下发设备消息服务 | |||||
[统一下发设备消息服务](#send) | |||||
## 2.管理会话服务 | |||||
[基于Tcp管理会话服务](#tcp_session) | |||||
[基于Udp管理会话服务](#udp_session) | |||||
## 3.SIM黑名单管理服务 | |||||
[SIM黑名单管理服务](#blacklist) | |||||
## 接口请求对照表 | |||||
### 公共接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| | |||||
### 基于Tcp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/SessionTcpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| | |||||
### 基于Udp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/SessionUdpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号查询对应会话| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| | |||||
### SIM黑名单管理接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Blacklist/Add| POST| SIM卡黑名单服务-将对应SIM号加入黑名单| | |||||
| 127.0.0.1:828/jt808api/Blacklist/Remove| POST| SIM卡黑名单服务-将对应SIM号移除黑名单| | |||||
| 127.0.0.1:828/jt808api/Blacklist/GetAll| Get| SIM卡黑名单服务-获取所有sim的黑名单列表| | |||||
### 统一对象返回 JT808ResultDto\<T> | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Message| string| 消息描述| | |||||
| Code| int| 状态码| | |||||
| Data| T(泛型)| 数据| | |||||
返回Code[状态码]说明: | |||||
|状态码|说明| | |||||
|:------:|:------:| | |||||
| 200 | 返回成功 | | |||||
| 201 | 内容为空 | | |||||
| 404 | 没有该服务 | | |||||
| 500 | 服务内部错误 | | |||||
### <span id="send">基于Tcp统一下发设备消息服务</span> | |||||
请求地址:/UnificationSend | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|------|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
| HexData| string| JT808 Hex String JT808数据包字符串| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
"HexData":"7E****7E" | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool| 是否成功| | |||||
返回结果: | |||||
``` result1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
### <span id="tcp_session">基于Tcp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808TcpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Tcp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808TcpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号查询对应会话 | |||||
请求地址:Tcp/Session/QuerySessionByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| JT808TcpSessionInfoDto对象 | 统一会话信息对象返回 | | |||||
返回结果: | |||||
``` session2 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data": { | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
} | |||||
``` | |||||
#### 3.通过设备终端号移除对应会话 | |||||
请求地址:Tcp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 4.获取会话分页集合 | |||||
请求地址:Tcp/Session/SessionTcpByPage | |||||
请求方式:GET | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| pageIndex| int| 当前页(默认0)| | |||||
| pageSize| int| 页容量(默认10)| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808TcpSessionInfoDto> | 实际会话信息集合 | | |||||
| PageIndex| int | 当前页(默认0) | | |||||
| PageSize| int | 页容量(默认10) | | |||||
| Total| int | 总数 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"message":null, | |||||
"code":200, | |||||
"data":{ | |||||
"pageIndex":0, | |||||
"pageSize":10, | |||||
"total":2, | |||||
"data":[ | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", | |||||
"startTime":"2022-09-03T19:34:07.8733615+08:00", | |||||
"terminalPhoneNo":"123456789012", | |||||
"remoteAddressIP":"127.0.0.1:9826" | |||||
}, | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:05.135997+08:00", | |||||
"startTime":"2022-09-03T19:34:05.136035+08:00", | |||||
"terminalPhoneNo":"123456789013", | |||||
"remoteAddressIP":"127.0.0.1:9825" | |||||
} | |||||
] | |||||
} | |||||
} | |||||
``` | |||||
### <span id="udp_session">基于Udp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808UdpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Udp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808UdpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号查询对应会话 | |||||
请求地址:Udp/Session/QuerySessionByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| JT808UdpSessionInfoDto对象 | 统一会话信息对象返回 | | |||||
返回结果: | |||||
``` session2 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
} | |||||
``` | |||||
#### 3.通过设备终端号移除对应会话 | |||||
请求地址:Udp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 4.获取会话分页集合 | |||||
请求地址:Udp/Session/SessionUdpByPage | |||||
请求方式:GET | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| pageIndex| int| 当前页(默认0)| | |||||
| pageSize| int| 页容量(默认10)| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808UdpSessionInfoDto> | 实际会话信息集合 | | |||||
| PageIndex| int | 当前页(默认0) | | |||||
| PageSize| int | 页容量(默认10) | | |||||
| Total| int | 总数 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"message":null, | |||||
"code":200, | |||||
"data":{ | |||||
"pageIndex":0, | |||||
"pageSize":10, | |||||
"total":2, | |||||
"data":[ | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", | |||||
"startTime":"2022-09-03T19:34:07.8733615+08:00", | |||||
"terminalPhoneNo":"123456789012", | |||||
"remoteAddressIP":"127.0.0.1:9826" | |||||
}, | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:05.135997+08:00", | |||||
"startTime":"2022-09-03T19:34:05.136035+08:00", | |||||
"terminalPhoneNo":"123456789013", | |||||
"remoteAddressIP":"127.0.0.1:9825" | |||||
} | |||||
] | |||||
} | |||||
} | |||||
``` | |||||
### <span id="blacklist">SIM黑名单管理服务</span> | |||||
#### 1.添加sim卡黑名单 | |||||
请求地址:Blacklist/Add | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 2.移除sim卡黑名单 | |||||
请求地址:Blacklist/Remove | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 3.获取sim卡黑名单 | |||||
请求地址:Blacklist/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| terminalPhoneNo| List\<string>| 设备终端号集合| | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
"12345678901", | |||||
"12345678902" | |||||
] | |||||
} | |||||
``` |
@@ -1,294 +0,0 @@ | |||||
# 基于JT808DotNetty WebApi 接口文档 | |||||
基地址:127.0.0.1:828/jt808api/ | |||||
> 注意url格式 | |||||
数据格式:只支持Json格式 | |||||
默认端口:828 | |||||
## 1.统一下发设备消息服务 | |||||
[统一下发设备消息服务](#send) | |||||
## 2.管理会话服务 | |||||
[基于Tcp管理会话服务](#tcp_session) | |||||
[基于Udp管理会话服务](#udp_session) | |||||
## 4.消息包计数服务 | |||||
[基于Tcp消息包计数服务](#tcp_counter) | |||||
[基于Udp消息包计数服务](#udp_counter) | |||||
## 接口请求对照表 | |||||
### 公共接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| | |||||
### 基于Tcp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/QueryTcpSessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| | |||||
| 127.0.0.1:828/jt808api/Tcp/GetAtomicCounter| GET| 基于Tcp消息包计数服务| | |||||
### 基于Udp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| | |||||
| 127.0.0.1:828/jt808api/Udp/GetAtomicCounter| GET| 基于Udp消息包计数服务| | |||||
### 统一对象返回 JT808ResultDto\<T> | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Message| string| 消息描述| | |||||
| Code| int| 状态码| | |||||
| Data| T(泛型)| 数据| | |||||
返回Code[状态码]说明: | |||||
|状态码|说明| | |||||
|:------:|:------:| | |||||
| 200 | 返回成功 | | |||||
| 201 | 内容为空 | | |||||
| 404 | 没有该服务 | | |||||
| 500 | 服务内部错误 | | |||||
### <span id="send">基于Tcp统一下发设备消息服务</span> | |||||
请求地址:/UnificationSend | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|------|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
| Data| byte[]| JT808 byte[]数组| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool| 是否成功| | |||||
返回结果: | |||||
``` result1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
### <span id="tcp_session">基于Tcp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808TcpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Tcp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808TcpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号移除对应会话 | |||||
请求地址:Tcp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| terminalPhoneNo| string| 设备终端号| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
### <span id="udp_session">基于Udp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808UdpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Udp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808UdpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号移除对应会话 | |||||
请求地址:Udp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| terminalPhoneNo| string| 设备终端号| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
### <span id="tcp_counter">基于Tcp消息包计数服务</span> | |||||
请求地址:Tcp/GetAtomicCounter | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|------|:------:|:------| | |||||
| MsgSuccessCount| long| 消息包成功数| | |||||
| MsgFailCount| long| 消息包失败数| | |||||
返回结果: | |||||
``` counter | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":{ | |||||
"MsgSuccessCount":10000, | |||||
"MsgFailCount":0 | |||||
} | |||||
} | |||||
``` | |||||
### <span id="udp_counter">基于Udp消息包计数服务</span> | |||||
请求地址:Udp/GetAtomicCounter | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|------|:------:|:------| | |||||
| MsgSuccessCount| long| 消息包成功数| | |||||
| MsgFailCount| long| 消息包失败数| | |||||
返回结果: | |||||
``` counter | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":{ | |||||
"MsgSuccessCount":1000, | |||||
"MsgFailCount":0 | |||||
} | |||||
} | |||||
``` |
@@ -1,541 +0,0 @@ | |||||
# 基于JT808Gateway WebApi 接口文档 | |||||
基地址:127.0.0.1:828/jt808api/ | |||||
> 注意url格式 | |||||
数据格式:只支持Json格式 | |||||
默认端口:828 | |||||
## 1.统一下发设备消息服务 | |||||
[统一下发设备消息服务](#send) | |||||
## 2.管理会话服务 | |||||
[基于Tcp管理会话服务](#tcp_session) | |||||
[基于Udp管理会话服务](#udp_session) | |||||
## 3.SIM黑名单管理服务 | |||||
[SIM黑名单管理服务](#blacklist) | |||||
## 接口请求对照表 | |||||
### 公共接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/UnificationSend| POST| 统一下发设备消息服务| | |||||
### 基于Tcp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/SessionTcpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话| | |||||
| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话| | |||||
### 基于Udp接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/SessionUdpByPage?pageIndex=0&pageSize10| GET| 基于Tcp管理会话服务-获取会话分页集合| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/QuerySessionByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号查询对应会话| | |||||
| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话| | |||||
### SIM黑名单管理接口请求 | |||||
|请求Url|请求方式|说明| | |||||
|:------|:------|:------| | |||||
| 127.0.0.1:828/jt808api/Blacklist/Add| POST| SIM卡黑名单服务-将对应SIM号加入黑名单| | |||||
| 127.0.0.1:828/jt808api/Blacklist/Remove| POST| SIM卡黑名单服务-将对应SIM号移除黑名单| | |||||
| 127.0.0.1:828/jt808api/Blacklist/GetAll| Get| SIM卡黑名单服务-获取所有sim的黑名单列表| | |||||
### 统一对象返回 JT808ResultDto\<T> | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Message| string| 消息描述| | |||||
| Code| int| 状态码| | |||||
| Data| T(泛型)| 数据| | |||||
返回Code[状态码]说明: | |||||
|状态码|说明| | |||||
|:------:|:------:| | |||||
| 200 | 返回成功 | | |||||
| 201 | 内容为空 | | |||||
| 404 | 没有该服务 | | |||||
| 500 | 服务内部错误 | | |||||
### <span id="send">基于Tcp统一下发设备消息服务</span> | |||||
请求地址:/UnificationSend | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|------|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
| HexData| string| JT808 Hex String JT808数据包字符串| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
"HexData":"7E****7E" | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool| 是否成功| | |||||
返回结果: | |||||
``` result1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
### <span id="tcp_session">基于Tcp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808TcpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Tcp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808TcpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号查询对应会话 | |||||
请求地址:Tcp/Session/QuerySessionByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| JT808TcpSessionInfoDto对象 | 统一会话信息对象返回 | | |||||
返回结果: | |||||
``` session2 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data": { | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
} | |||||
``` | |||||
#### 3.通过设备终端号移除对应会话 | |||||
请求地址:Tcp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 4.获取会话分页集合 | |||||
请求地址:Tcp/Session/SessionTcpByPage | |||||
请求方式:GET | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| pageIndex| int| 当前页(默认0)| | |||||
| pageSize| int| 页容量(默认10)| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808TcpSessionInfoDto> | 实际会话信息集合 | | |||||
| PageIndex| int | 当前页(默认0) | | |||||
| PageSize| int | 页容量(默认10) | | |||||
| Total| int | 总数 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"message":null, | |||||
"code":200, | |||||
"data":{ | |||||
"pageIndex":0, | |||||
"pageSize":10, | |||||
"total":2, | |||||
"data":[ | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", | |||||
"startTime":"2022-09-03T19:34:07.8733615+08:00", | |||||
"terminalPhoneNo":"123456789012", | |||||
"remoteAddressIP":"127.0.0.1:9826" | |||||
}, | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:05.135997+08:00", | |||||
"startTime":"2022-09-03T19:34:05.136035+08:00", | |||||
"terminalPhoneNo":"123456789013", | |||||
"remoteAddressIP":"127.0.0.1:9825" | |||||
} | |||||
] | |||||
} | |||||
} | |||||
``` | |||||
### <span id="udp_session">基于Udp管理会话服务</span> | |||||
#### 统一会话信息对象返回 JT808UdpSessionInfoDto | |||||
|属性|数据类型|参数说明| | |||||
|------|------|------| | |||||
| LastActiveTime| DateTime| 最后上线时间| | |||||
| StartTime| DateTime| 上线时间| | |||||
| TerminalPhoneNo|string| 终端手机号| | |||||
| RemoteAddressIP| string| 远程ip地址| | |||||
#### 1.获取会话集合 | |||||
请求地址:Udp/Session/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808UdpSessionInfoDto> | 实际会话信息集合 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
},{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789013", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
] | |||||
} | |||||
``` | |||||
#### 2.通过设备终端号查询对应会话 | |||||
请求地址:Udp/Session/QuerySessionByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| JT808UdpSessionInfoDto对象 | 统一会话信息对象返回 | | |||||
返回结果: | |||||
``` session2 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":{ | |||||
"LastActiveTime":"2018-11-27 20:00:00", | |||||
"StartTime":"2018-11-25 20:00:00", | |||||
"TerminalPhoneNo":"123456789012", | |||||
"RemoteAddressIP":"127.0.0.1:11808" | |||||
} | |||||
} | |||||
``` | |||||
#### 3.通过设备终端号移除对应会话 | |||||
请求地址:Udp/Session/RemoveByTerminalPhoneNo | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 4.获取会话分页集合 | |||||
请求地址:Udp/Session/SessionUdpByPage | |||||
请求方式:GET | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| pageIndex| int| 当前页(默认0)| | |||||
| pageSize| int| 页容量(默认10)| | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| List\<JT808UdpSessionInfoDto> | 实际会话信息集合 | | |||||
| PageIndex| int | 当前页(默认0) | | |||||
| PageSize| int | 页容量(默认10) | | |||||
| Total| int | 总数 | | |||||
返回结果: | |||||
``` session1 | |||||
{ | |||||
"message":null, | |||||
"code":200, | |||||
"data":{ | |||||
"pageIndex":0, | |||||
"pageSize":10, | |||||
"total":2, | |||||
"data":[ | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:07.8733605+08:00", | |||||
"startTime":"2022-09-03T19:34:07.8733615+08:00", | |||||
"terminalPhoneNo":"123456789012", | |||||
"remoteAddressIP":"127.0.0.1:9826" | |||||
}, | |||||
{ | |||||
"lastActiveTime":"2022-09-03T19:34:05.135997+08:00", | |||||
"startTime":"2022-09-03T19:34:05.136035+08:00", | |||||
"terminalPhoneNo":"123456789013", | |||||
"remoteAddressIP":"127.0.0.1:9825" | |||||
} | |||||
] | |||||
} | |||||
} | |||||
``` | |||||
### <span id="blacklist">SIM黑名单管理服务</span> | |||||
#### 1.添加sim卡黑名单 | |||||
请求地址:Blacklist/Add | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 2.移除sim卡黑名单 | |||||
请求地址:Blacklist/Remove | |||||
请求方式:POST | |||||
请求参数: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| TerminalPhoneNo| string| 设备终端号| | |||||
``` 1 | |||||
{ | |||||
"TerminalPhoneNo":"123456789012", | |||||
} | |||||
``` | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| Data| bool | 是否成功 | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":true | |||||
} | |||||
``` | |||||
#### 3.获取sim卡黑名单 | |||||
请求地址:Blacklist/GetAll | |||||
请求方式:GET | |||||
返回数据: | |||||
|属性|数据类型|参数说明| | |||||
|:------:|:------:|:------| | |||||
| terminalPhoneNo| List\<string>| 设备终端号集合| | |||||
返回结果: | |||||
``` session3 | |||||
{ | |||||
"Message":"", | |||||
"Code":200, | |||||
"Data":[ | |||||
"12345678901", | |||||
"12345678902" | |||||
] | |||||
} | |||||
``` |
@@ -374,19 +374,3 @@ net.ipv6.conf.default.disable_ipv6 = 1 | |||||
reboot | reboot | ||||
``` | ``` | ||||
## 基于DotNetty | |||||
[感谢泥水佬提供的压力测试工具](https://www.cnblogs.com/smark/p/4496660.html?utm_source=tuicool) | |||||
| 操作系统 | 配置 | 使用 | | |||||
|:-------:|:-------:|:-------:| | |||||
| win server 2016 | 4c8g | 压力测试客户端 | | |||||
| centos7 | 4c8g | JT808服务端 | | |||||
 | |||||
 | |||||
 | |||||
 |
@@ -0,0 +1,5 @@ | |||||
{ | |||||
"sdk": { | |||||
"version": "7.0.203" | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
dotnet pack .\src\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.WebApi\JT808.DotNetty.WebApi.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Core\JT808.DotNetty.Core.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Client\JT808.DotNetty.Client.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj -c Release --output nupkgs | |||||
echo 'push service pacakge...' | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.MsgIdHandler\JT808.DotNetty.MsgIdHandler.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.MsgLogging\JT808.DotNetty.MsgLogging.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.ReplyMessage\JT808.DotNetty.ReplyMessage.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.SessionNotice\JT808.DotNetty.SessionNotice.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.Traffic\JT808.DotNetty.Traffic.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.DotNetty.Services\JT808.DotNetty.Transmit\JT808.DotNetty.Transmit.csproj -c Release --output nupkgs | |||||
pause |
@@ -4,10 +4,4 @@ dotnet pack .\src\JT808.Gateway.Abstractions\JT808.Gateway.Abstractions.csproj - | |||||
dotnet pack .\src\JT808.Gateway.Client\JT808.Gateway.Client.csproj -c Release --output nupkgs | dotnet pack .\src\JT808.Gateway.Client\JT808.Gateway.Client.csproj -c Release --output nupkgs | ||||
dotnet pack .\src\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj -c Release --output nupkgs | dotnet pack .\src\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj -c Release --output nupkgs | ||||
echo 'push service pacakge...' | |||||
dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.MsgLogging\JT808.Gateway.MsgLogging.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.ReplyMessage\JT808.Gateway.ReplyMessage.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.SessionNotice\JT808.Gateway.SessionNotice.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.Transmit\JT808.Gateway.Transmit.csproj -c Release --output nupkgs | |||||
dotnet pack .\src\JT808.Gateway.Services\JT808.Gateway.MsgIdHandler\JT808.Gateway.MsgIdHandler.csproj -c Release --output nupkgs | |||||
pause | pause |
@@ -1,16 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>netcoreapp3.1</TargetFramework> | |||||
<LangVersion>7.3</LangVersion> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" /> | |||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" /> | |||||
</ItemGroup> | |||||
<Import Project="..\netty.props" /> | |||||
</Project> |
@@ -1,42 +0,0 @@ | |||||
using JT808.DotNetty.Client; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using JT808.Protocol; | |||||
using JT808.Protocol.MessageBody; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
using System.Threading; | |||||
using Microsoft.Extensions.Hosting; | |||||
using JT808.DotNetty.SimpleClient.Services; | |||||
namespace JT808.DotNetty.SimpleClient | |||||
{ | |||||
class Program | |||||
{ | |||||
static async Task Main(string[] args) | |||||
{ | |||||
var serverHostBuilder = new HostBuilder() | |||||
.ConfigureLogging((context, logging) => | |||||
{ | |||||
logging.AddConsole(); | |||||
logging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => | |||||
{ | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||||
services.AddLogging(options => { | |||||
options.AddConsole(); | |||||
options.SetMinimumLevel(LogLevel.Trace); | |||||
}); | |||||
services.AddJT808Configure() | |||||
.AddJT808Client(); | |||||
services.AddHostedService<Up2011Service>(); | |||||
services.AddHostedService<Up2013Service>(); | |||||
services.AddHostedService<Up2019Service>(); | |||||
}); | |||||
await serverHostBuilder.RunConsoleAsync(); | |||||
} | |||||
} | |||||
} |
@@ -1,72 +0,0 @@ | |||||
using JT808.DotNetty.Client; | |||||
using JT808.Protocol.MessageBody; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
using Microsoft.Extensions.Hosting; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleClient.Services | |||||
{ | |||||
public class Up2011Service : IHostedService | |||||
{ | |||||
private readonly IJT808TcpClientFactory jT808TcpClientFactory; | |||||
public Up2011Service(IJT808TcpClientFactory jT808TcpClientFactory) | |||||
{ | |||||
this.jT808TcpClientFactory = jT808TcpClientFactory; | |||||
} | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | |||||
string sim = "44444444444"; | |||||
JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2011)); | |||||
Thread.Sleep(5000); | |||||
//1.终端注册 | |||||
client1.Send(JT808MsgId.终端注册.Create(sim, new JT808_0x0100() | |||||
{ | |||||
PlateNo = "粤A12346", | |||||
PlateColor = 2, | |||||
AreaID = 0, | |||||
CityOrCountyId = 0, | |||||
MakerId = "Koike", | |||||
TerminalId = "Koike01", | |||||
TerminalModel = "Koike001" | |||||
})); | |||||
//2.终端鉴权 | |||||
client1.Send(JT808MsgId.终端鉴权.Create(sim, new JT808_0x0102() | |||||
{ | |||||
Code = "1234" | |||||
})); | |||||
Task.Run(() => { | |||||
while (true) | |||||
{ | |||||
var i = 0; | |||||
//3.每5秒发一次 | |||||
client1.Send(JT808MsgId.位置信息汇报.Create(sim, new JT808_0x0200() | |||||
{ | |||||
Lat = 110000 + i, | |||||
Lng = 100000 + i, | |||||
GPSTime = DateTime.Now, | |||||
Speed = 50, | |||||
Direction = 30, | |||||
AlarmFlag = 5, | |||||
Altitude = 50, | |||||
StatusFlag = 10 | |||||
})); | |||||
i++; | |||||
Thread.Sleep(5000); | |||||
} | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,100 +0,0 @@ | |||||
using JT808.DotNetty.Client; | |||||
using JT808.Protocol.MessageBody; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
using Microsoft.Extensions.Hosting; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleClient.Services | |||||
{ | |||||
public class Up2013Service : IHostedService | |||||
{ | |||||
private readonly IJT808TcpClientFactory jT808TcpClientFactory; | |||||
public Up2013Service(IJT808TcpClientFactory jT808TcpClientFactory) | |||||
{ | |||||
this.jT808TcpClientFactory = jT808TcpClientFactory; | |||||
} | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | |||||
string sim = "11111111111"; | |||||
JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2013)); | |||||
string sim2 = "33333333333"; | |||||
JT808TcpClient client2 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim2, "127.0.0.1", 808, JT808Version.JTT2013)); | |||||
Thread.Sleep(5000); | |||||
//1.终端注册 | |||||
client1.Send(JT808MsgId.终端注册.Create(sim, new JT808_0x0100() | |||||
{ | |||||
PlateNo = "粤A12345", | |||||
PlateColor = 2, | |||||
AreaID = 0, | |||||
CityOrCountyId = 0, | |||||
MakerId = "Koike", | |||||
TerminalId = "Koike01", | |||||
TerminalModel = "Koike001" | |||||
})); | |||||
client2.Send(JT808MsgId.终端注册.Create(sim2, new JT808_0x0100() | |||||
{ | |||||
PlateNo = "粤A12345", | |||||
PlateColor = 2, | |||||
AreaID = 0, | |||||
CityOrCountyId = 0, | |||||
MakerId = "Koike", | |||||
TerminalId = "Koike02", | |||||
TerminalModel = "Koike002" | |||||
})); | |||||
//2.终端鉴权 | |||||
client1.Send(JT808MsgId.终端鉴权.Create(sim, new JT808_0x0102() | |||||
{ | |||||
Code = "1234" | |||||
})); | |||||
//2.终端鉴权 | |||||
client2.Send(JT808MsgId.终端鉴权.Create(sim2, new JT808_0x0102() | |||||
{ | |||||
Code = "1234" | |||||
})); | |||||
Task.Run(() => { | |||||
while (true) | |||||
{ | |||||
var i = 0; | |||||
//3.每5秒发一次 | |||||
client1.Send(JT808MsgId.位置信息汇报.Create(sim, new JT808_0x0200() | |||||
{ | |||||
Lat = 110000 + i, | |||||
Lng = 100000 + i, | |||||
GPSTime = DateTime.Now, | |||||
Speed = 50, | |||||
Direction = 30, | |||||
AlarmFlag = 5, | |||||
Altitude = 50, | |||||
StatusFlag = 10 | |||||
})); | |||||
client2.Send(JT808MsgId.位置信息汇报.Create(sim2, new JT808_0x0200() | |||||
{ | |||||
Lat = 110000 + i, | |||||
Lng = 100000 + i, | |||||
GPSTime = DateTime.Now, | |||||
Speed = 50, | |||||
Direction = 30, | |||||
AlarmFlag = 5, | |||||
Altitude = 50, | |||||
StatusFlag = 10 | |||||
})); | |||||
i++; | |||||
Thread.Sleep(5000); | |||||
} | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,74 +0,0 @@ | |||||
using JT808.DotNetty.Client; | |||||
using JT808.Protocol.MessageBody; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
using Microsoft.Extensions.Hosting; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleClient.Services | |||||
{ | |||||
public class Up2019Service : IHostedService | |||||
{ | |||||
private readonly IJT808TcpClientFactory jT808TcpClientFactory; | |||||
public Up2019Service(IJT808TcpClientFactory jT808TcpClientFactory) | |||||
{ | |||||
this.jT808TcpClientFactory = jT808TcpClientFactory; | |||||
} | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | |||||
string sim = "22222222222"; | |||||
JT808TcpClient client1 = jT808TcpClientFactory.Create(new JT808DeviceConfig(sim, "127.0.0.1", 808, JT808Version.JTT2019)); | |||||
Thread.Sleep(5000); | |||||
//1.终端注册 | |||||
client1.Send(JT808MsgId.终端注册.Create2019(sim, new JT808_0x0100() | |||||
{ | |||||
PlateNo = "粤A12346", | |||||
PlateColor = 2, | |||||
AreaID = 0, | |||||
CityOrCountyId = 0, | |||||
MakerId = "Koike002", | |||||
TerminalId = "Koike002", | |||||
TerminalModel = "Koike002" | |||||
})); | |||||
//2.终端鉴权 | |||||
client1.Send(JT808MsgId.终端鉴权.Create2019(sim, new JT808_0x0102() | |||||
{ | |||||
Code = "6666", | |||||
IMEI="123456", | |||||
SoftwareVersion="v1.0.0" | |||||
})); | |||||
Task.Run(() => { | |||||
while (true) | |||||
{ | |||||
var i = 0; | |||||
//3.每5秒发一次 | |||||
client1.Send(JT808MsgId.位置信息汇报.Create2019(sim, new JT808_0x0200() | |||||
{ | |||||
Lat = 110000 + i, | |||||
Lng = 100000 + i, | |||||
GPSTime = DateTime.Now, | |||||
Speed = 50, | |||||
Direction = 30, | |||||
AlarmFlag = 5, | |||||
Altitude = 50, | |||||
StatusFlag = 10 | |||||
})); | |||||
i++; | |||||
Thread.Sleep(5000); | |||||
} | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,21 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>netcoreapp3.1</TargetFramework> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<None Update="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" /> | |||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" /> | |||||
</ItemGroup> | |||||
<Import Project="..\netty.props" /> | |||||
</Project> |
@@ -1,44 +0,0 @@ | |||||
using JT808.DotNetty.Core; | |||||
using JT808.DotNetty.Tcp; | |||||
using JT808.DotNetty.Kafka; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleQueueServer | |||||
{ | |||||
class Program | |||||
{ | |||||
static async Task Main(string[] args) | |||||
{ | |||||
var serverHostBuilder = new HostBuilder() | |||||
.ConfigureAppConfiguration((hostingContext, config) => | |||||
{ | |||||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||||
}) | |||||
.ConfigureLogging((context, logging) => | |||||
{ | |||||
logging.AddConsole(); | |||||
logging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => | |||||
{ | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||||
services.AddJT808Configure() | |||||
.AddJT808NettyCore(hostContext.Configuration) | |||||
.AddJT808TcpNettyHost() | |||||
.AddJT808ServerKafkaMsgProducer(hostContext.Configuration) | |||||
.AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) | |||||
.Builder(); | |||||
}); | |||||
await serverHostBuilder.RunConsoleAsync(); | |||||
} | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
} | |||||
}, | |||||
"JT808MsgProducerConfig": { | |||||
"TopicName": "JT808NettyMsg", | |||||
"BootstrapServers": "127.0.0.1:9092" | |||||
}, | |||||
"JT808MsgReplyConsumerConfig": { | |||||
"TopicName": "JT808NettyMsgReply", | |||||
"EnableAutoCommit": true, | |||||
"GroupId": "JT808.NettyMsgReply", | |||||
"BootstrapServers": "127.0.0.1:9092" | |||||
} | |||||
} |
@@ -1,41 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Kafka; | |||||
using JT808.DotNetty.ReplyMessage; | |||||
using JT808.Protocol; | |||||
using JT808.Protocol.Extensions; | |||||
using Microsoft.Extensions.Logging; | |||||
namespace JT808.DotNetty.SimpleQueueService.Impl | |||||
{ | |||||
public class JT808DotNettyReplyMessageServiceInherited : JT808DotNettyReplyMessageService | |||||
{ | |||||
public readonly ILogger<JT808DotNettyReplyMessageServiceInherited> logger; | |||||
public JT808DotNettyReplyMessageServiceInherited(IJT808Config jT808Config, | |||||
IJT808MsgReplyProducer jT808MsgReplyProducer, | |||||
ILoggerFactory loggerFactory) | |||||
: base(jT808Config, jT808MsgReplyProducer) | |||||
{ | |||||
logger = loggerFactory.CreateLogger<JT808DotNettyReplyMessageServiceInherited>(); | |||||
} | |||||
public override void Processor((string TerminalNo, byte[] Data) parameter) | |||||
{ | |||||
logger.LogDebug($"{parameter.TerminalNo}:{parameter.Data.ToHexString()}"); | |||||
base.Processor(parameter); | |||||
} | |||||
public override byte[] Msg0x0200(JT808HeaderPackage request) | |||||
{ | |||||
logger.LogWarning("==========================================="); | |||||
logger.LogWarning($"{request.Header.TerminalPhoneNo}---{request.OriginalData.ToHexString()}"); | |||||
logger.LogWarning("==========================================="); | |||||
return base.Msg0x0200(request); | |||||
} | |||||
} | |||||
} |
@@ -1,21 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>netcoreapp3.1</TargetFramework> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<None Update="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" /> | |||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" /> | |||||
</ItemGroup> | |||||
<Import Project="..\netty.props" /> | |||||
</Project> |
@@ -1,41 +0,0 @@ | |||||
using JT808.DotNetty.Kafka; | |||||
using JT808.DotNetty.ReplyMessage; | |||||
using JT808.DotNetty.SimpleQueueService.Impl; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleQueueService | |||||
{ | |||||
class Program | |||||
{ | |||||
static async Task Main(string[] args) | |||||
{ | |||||
var hostBuilder = new HostBuilder() | |||||
.ConfigureAppConfiguration((hostContext, config) => { | |||||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||||
}) | |||||
.ConfigureLogging((hostContext, configLogging) => { | |||||
configLogging.AddConsole(); | |||||
configLogging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => { | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||||
services.AddJT808Configure() | |||||
.AddJT808ClientKafka() | |||||
.AddMsgReplyProducer(hostContext.Configuration) | |||||
.AddMsgConsumer(hostContext.Configuration) | |||||
.AddInprocJT808ReplyMessage<JT808DotNettyReplyMessageServiceInherited>(); | |||||
; | |||||
}); | |||||
await hostBuilder.RunConsoleAsync(); | |||||
} | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
} | |||||
}, | |||||
"JT808MsgConsumerConfig": { | |||||
"TopicName": "JT808NettyMsg", | |||||
"EnableAutoCommit": true, | |||||
"GroupId": "JT808.NettyMsgHandler", | |||||
"BootstrapServers": "127.0.0.1:9092" | |||||
}, | |||||
"JT808MsgReplyProducerConfig": { | |||||
"TopicName": "JT808NettyMsgReply", | |||||
"BootstrapServers": "127.0.0.1:9092" | |||||
} | |||||
} |
@@ -1,21 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>netcoreapp3.1</TargetFramework> | |||||
<LangVersion>7.3</LangVersion> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" /> | |||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Update="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
<Import Project="..\netty.props" /> | |||||
</Project> |
@@ -1,44 +0,0 @@ | |||||
| |||||
using JT808.DotNetty.Core; | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Tcp; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.SimpleServer | |||||
{ | |||||
class Program | |||||
{ | |||||
static async Task Main(string[] args) | |||||
{ | |||||
var serverHostBuilder = new HostBuilder() | |||||
.ConfigureAppConfiguration((hostingContext, config) => | |||||
{ | |||||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||||
}) | |||||
.ConfigureLogging((context, logging) => | |||||
{ | |||||
logging.AddConsole(); | |||||
logging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => | |||||
{ | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||||
services.AddJT808Configure() | |||||
.AddJT808NettyCore(hostContext.Configuration) | |||||
.AddJT808TcpNettyHost() | |||||
.Builder(); | |||||
}); | |||||
await serverHostBuilder.RunConsoleAsync(); | |||||
} | |||||
} | |||||
} |
@@ -1,20 +0,0 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Trace" | |||||
} | |||||
} | |||||
}, | |||||
"JT808Configuration": { | |||||
"TcpPort": 808, | |||||
"UdpPort": 808, | |||||
"WebApiPort": 828 | |||||
} | |||||
} |
@@ -1,51 +0,0 @@ | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio Version 17 | |||||
VisualStudioVersion = 17.0.31903.59 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | |||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "simples", "simples", "{2459FB59-8A33-49A4-ADBC-A0B12C5886A6}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleClient", "JT808.DotNetty.SimpleClient\JT808.DotNetty.SimpleClient.csproj", "{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleServer", "JT808.DotNetty.SimpleServer\JT808.DotNetty.SimpleServer.csproj", "{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleQueueServer", "JT808.DotNetty.SimpleQueueServer\JT808.DotNetty.SimpleQueueServer.csproj", "{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT808.DotNetty.SimpleQueueService", "JT808.DotNetty.SimpleQueueService\JT808.DotNetty.SimpleQueueService.csproj", "{90E1F1C9-A953-4341-9792-9E2AF4471B68}" | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|Any CPU = Debug|Any CPU | |||||
Release|Any CPU = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{1DEAC7EA-D662-420B-A1A7-A6E840568F7B}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{90E1F1C9-A953-4341-9792-9E2AF4471B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{90E1F1C9-A953-4341-9792-9E2AF4471B68}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{90E1F1C9-A953-4341-9792-9E2AF4471B68}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{90E1F1C9-A953-4341-9792-9E2AF4471B68}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
GlobalSection(NestedProjects) = preSolution | |||||
{E6F61CE8-BFB4-4946-A0D3-AECCE77824E5} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} | |||||
{CCE6AEFB-1AB0-4BD9-8EA2-8B4CDD097E88} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} | |||||
{1DEAC7EA-D662-420B-A1A7-A6E840568F7B} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} | |||||
{90E1F1C9-A953-4341-9792-9E2AF4471B68} = {2459FB59-8A33-49A4-ADBC-A0B12C5886A6} | |||||
EndGlobalSection | |||||
GlobalSection(ExtensibilityGlobals) = postSolution | |||||
SolutionGuid = {FC0FFCEA-E1EF-4C97-A1C5-F89418B6834B} | |||||
EndGlobalSection | |||||
EndGlobal |
@@ -1,5 +1,4 @@ | |||||
using JT808.Gateway.Abstractions; | using JT808.Gateway.Abstractions; | ||||
using JT808.Gateway.MsgIdHandler; | |||||
using JT808.Gateway.SimpleQueueNotification.Hubs; | using JT808.Gateway.SimpleQueueNotification.Hubs; | ||||
using JT808.Protocol.Extensions; | using JT808.Protocol.Extensions; | ||||
using Microsoft.AspNetCore.SignalR; | using Microsoft.AspNetCore.SignalR; | ||||
@@ -14,8 +14,8 @@ using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
using JT808.Protocol; | using JT808.Protocol; | ||||
using JT808.Gateway.Kafka; | using JT808.Gateway.Kafka; | ||||
using JT808.Gateway.MsgIdHandler; | |||||
using JT808.Gateway.SimpleQueueNotification.Impl; | using JT808.Gateway.SimpleQueueNotification.Impl; | ||||
using JT808.Gateway.Extensions; | |||||
namespace JT808.Gateway.SimpleQueueNotification | namespace JT808.Gateway.SimpleQueueNotification | ||||
{ | { | ||||
@@ -1,4 +1,4 @@ | |||||
using JT808.Gateway.SessionNotice; | |||||
using JT808.Gateway.Services; | |||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
@@ -1,7 +1,5 @@ | |||||
using JT808.Protocol; | using JT808.Protocol; | ||||
using JT808.Gateway.Kafka; | using JT808.Gateway.Kafka; | ||||
using JT808.Gateway.ReplyMessage; | |||||
using JT808.Gateway.SessionNotice; | |||||
using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using Microsoft.Extensions.Hosting; | using Microsoft.Extensions.Hosting; | ||||
@@ -9,6 +7,7 @@ using Microsoft.Extensions.Logging; | |||||
using System; | using System; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using JT808.Gateway.SimpleQueueService.Impl; | using JT808.Gateway.SimpleQueueService.Impl; | ||||
using JT808.Gateway.Extensions; | |||||
namespace JT808.Gateway.SimpleQueueService | namespace JT808.Gateway.SimpleQueueService | ||||
{ | { | ||||
@@ -1,7 +1,7 @@ | |||||
using JT808.Gateway.Abstractions; | using JT808.Gateway.Abstractions; | ||||
using JT808.Gateway.Abstractions.Configurations; | using JT808.Gateway.Abstractions.Configurations; | ||||
using JT808.Gateway.MsgLogging; | |||||
using JT808.Gateway.Transmit; | |||||
using JT808.Gateway.Abstractions.Enums; | |||||
using JT808.Gateway.Services; | |||||
using JT808.Protocol; | using JT808.Protocol; | ||||
using JT808.Protocol.Extensions; | using JT808.Protocol.Extensions; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
@@ -67,7 +67,10 @@ namespace JT808.Gateway.SimpleServer.Impl | |||||
public override byte[] Msg0x0200(JT808HeaderPackage request) | public override byte[] Msg0x0200(JT808HeaderPackage request) | ||||
{ | { | ||||
//logger.LogDebug("重写自带Msg0x0200的消息"); | //logger.LogDebug("重写自带Msg0x0200的消息"); | ||||
logger.LogDebug($"重写自带Msg0x0200的消息{request.Header.TerminalPhoneNo}-{request.OriginalData.ToHexString()}"); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"重写自带Msg0x0200的消息{request.Header.TerminalPhoneNo}-{request.OriginalData.ToHexString()}"); | |||||
} | |||||
return base.Msg0x0200(request); | return base.Msg0x0200(request); | ||||
} | } | ||||
@@ -78,7 +81,10 @@ namespace JT808.Gateway.SimpleServer.Impl | |||||
/// <returns></returns> | /// <returns></returns> | ||||
public byte[] Msg0x9999(JT808HeaderPackage request) | public byte[] Msg0x9999(JT808HeaderPackage request) | ||||
{ | { | ||||
logger.LogDebug("自定义消息"); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug("自定义消息"); | |||||
} | |||||
return default; | return default; | ||||
} | } | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
using JT808.Gateway.MsgLogging; | |||||
using JT808.Gateway.Abstractions; | |||||
using JT808.Gateway.Abstractions.Enums; | |||||
using JT808.Protocol.Extensions; | using JT808.Protocol.Extensions; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
using System; | using System; | ||||
@@ -16,7 +17,10 @@ namespace JT808.Gateway.SimpleServer.Impl | |||||
} | } | ||||
public void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType) | public void Processor((string TerminalNo, byte[] Data) parameter, JT808MsgLoggingType jT808MsgLoggingType) | ||||
{ | { | ||||
Logger.LogDebug($"{jT808MsgLoggingType.ToString()}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); | |||||
if(Logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
Logger.LogDebug($"{jT808MsgLoggingType}-{parameter.TerminalNo}-{parameter.Data.ToHexString()}"); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -7,7 +7,7 @@ | |||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" /> | <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> | <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" /> | <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<Import Project="..\pipeline.props" /> | <Import Project="..\pipeline.props" /> | ||||
@@ -1,22 +1,19 @@ | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
using JT808.Gateway.Abstractions; | |||||
using JT808.Gateway.Abstractions.Configurations; | |||||
using JT808.Gateway.Abstractions.Enums; | |||||
using JT808.Gateway.MsgLogging; | |||||
using JT808.Gateway.ReplyMessage; | |||||
using JT808.Gateway.SessionNotice; | |||||
using JT808.Gateway.SimpleServer.Impl; | |||||
using JT808.Gateway.SimpleServer.Services; | |||||
using JT808.Gateway.Transmit; | |||||
using JT808.Gateway.Abstractions.Enums; | |||||
using JT808.Protocol; | using JT808.Protocol; | ||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using Microsoft.Extensions.DependencyInjection.Extensions; | using Microsoft.Extensions.DependencyInjection.Extensions; | ||||
using Microsoft.Extensions.Hosting; | using Microsoft.Extensions.Hosting; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
using System; | |||||
using System.Threading.Tasks; | |||||
using JT808.Gateway.SimpleServer.Impl; | |||||
using JT808.Gateway.SimpleServer.Services; | |||||
using JT808.Gateway.Abstractions; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using JT808.Gateway.Abstractions.Configurations; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using JT808.Gateway.Extensions; | |||||
namespace JT808.Gateway.SimpleServer | namespace JT808.Gateway.SimpleServer | ||||
{ | { | ||||
@@ -1,4 +1,3 @@ | |||||
dotnet build JT808.PipelineSimples.sln | dotnet build JT808.PipelineSimples.sln | ||||
dotnet build JT808.DotNettySimples.sln | |||||
pause | pause |
@@ -1,5 +0,0 @@ | |||||
{ | |||||
"sdk": { | |||||
"version": "7.0.100" | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
<Project> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Client\JT808.DotNetty.Client.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Core\JT808.DotNetty.Core.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.WebApi\JT808.DotNetty.WebApi.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.MsgIdHandler\JT808.DotNetty.MsgIdHandler.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.MsgLogging\JT808.DotNetty.MsgLogging.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.ReplyMessage\JT808.DotNetty.ReplyMessage.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.SessionNotice\JT808.DotNetty.SessionNotice.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.Traffic\JT808.DotNetty.Traffic.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.DotNetty.Services\JT808.DotNetty.Transmit\JT808.DotNetty.Transmit.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -9,10 +9,5 @@ | |||||
<ProjectReference Include="..\..\src\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj"/> | <ProjectReference Include="..\..\src\JT808.Gateway.Kafka\JT808.Gateway.Kafka.csproj"/> | ||||
<ProjectReference Include="..\..\src\JT808.Gateway.Client\JT808.Gateway.Client.csproj" /> | <ProjectReference Include="..\..\src\JT808.Gateway.Client\JT808.Gateway.Client.csproj" /> | ||||
<ProjectReference Include="..\..\src\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj" /> | <ProjectReference Include="..\..\src\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj" /> | ||||
<ProjectReference Include="..\..\src\JT808.Gateway.Services\JT808.Gateway.MsgIdHandler\JT808.Gateway.MsgIdHandler.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.Gateway.Services\JT808.Gateway.MsgLogging\JT808.Gateway.MsgLogging.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.Gateway.Services\JT808.Gateway.ReplyMessage\JT808.Gateway.ReplyMessage.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.Gateway.Services\JT808.Gateway.SessionNotice\JT808.Gateway.SessionNotice.csproj" /> | |||||
<ProjectReference Include="..\..\src\JT808.Gateway.Services\JT808.Gateway.Transmit\JT808.Gateway.Transmit.csproj" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |
@@ -1,12 +0,0 @@ | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
/// <summary> | |||||
/// 包计数器服务 | |||||
/// </summary> | |||||
public class JT808AtomicCounterDto | |||||
{ | |||||
public long MsgSuccessCount { get; set; } | |||||
public long MsgFailCount { get; set; } | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
public class JT808DefaultResultDto: JT808ResultDto<string> | |||||
{ | |||||
public JT808DefaultResultDto() | |||||
{ | |||||
Data = "Hello,JT808 WebAPI"; | |||||
Code = JT808ResultCode.Ok; | |||||
} | |||||
} | |||||
} |
@@ -1,37 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Net; | |||||
using System.Runtime.Serialization; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
public class JT808IPAddressDto | |||||
{ | |||||
public string Host { get; set; } | |||||
public int Port { get; set; } | |||||
public EndPoint endPoint; | |||||
public EndPoint EndPoint | |||||
{ | |||||
get | |||||
{ | |||||
if (endPoint == null) | |||||
{ | |||||
if (IPAddress.TryParse(Host, out IPAddress ip)) | |||||
{ | |||||
endPoint = new IPEndPoint(ip, Port); | |||||
} | |||||
else | |||||
{ | |||||
endPoint = new DnsEndPoint(Host, Port); | |||||
} | |||||
} | |||||
return endPoint; | |||||
} | |||||
set { } | |||||
} | |||||
} | |||||
} |
@@ -1,30 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
public class JT808ResultDto<T> | |||||
{ | |||||
public JT808ResultDto() | |||||
{ | |||||
Code = JT808ResultCode.Ok; | |||||
} | |||||
public string Message { get; set; } | |||||
public int Code { get; set; } | |||||
public T Data { get; set; } | |||||
} | |||||
public class JT808ResultCode | |||||
{ | |||||
public const int Ok = 200; | |||||
public const int Empty = 201; | |||||
public const int AuthFail = 401; | |||||
public const int NotFound = 404; | |||||
public const int Fail = 400; | |||||
public const int Error = 500; | |||||
} | |||||
} |
@@ -1,24 +0,0 @@ | |||||
using System; | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
public class JT808TcpSessionInfoDto | |||||
{ | |||||
/// <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 RemoteAddressIP { get; set; } | |||||
} | |||||
} |
@@ -1,24 +0,0 @@ | |||||
using System; | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
public class JT808UdpSessionInfoDto | |||||
{ | |||||
/// <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 RemoteAddressIP { get; set; } | |||||
} | |||||
} |
@@ -1,11 +0,0 @@ | |||||
namespace JT808.DotNetty.Abstractions.Dtos | |||||
{ | |||||
/// <summary> | |||||
/// 统一下发请求参数 | |||||
/// </summary> | |||||
public class JT808UnificationSendRequestDto | |||||
{ | |||||
public string TerminalPhoneNo { get; set; } | |||||
public byte[] Data { get; set; } | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions.Enums | |||||
{ | |||||
/// <summary> | |||||
/// 传输协议类型 | |||||
/// </summary> | |||||
public enum JT808TransportProtocolType | |||||
{ | |||||
tcp=1, | |||||
udp = 2 | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808ClientBuilder | |||||
{ | |||||
IJT808Builder JT808Builder { get; } | |||||
IJT808Builder Builder(); | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808MsgConsumer : IJT808PubSub, IDisposable | |||||
{ | |||||
void OnMessage(Action<(string TerminalNo, byte[] Data)> callback); | |||||
CancellationTokenSource Cts { get; } | |||||
void Subscribe(); | |||||
void Unsubscribe(); | |||||
} | |||||
} |
@@ -1,17 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808MsgProducer : IJT808PubSub, IDisposable | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="terminalNo">设备终端号</param> | |||||
/// <param name="data">808 hex data</param> | |||||
Task ProduceAsync(string terminalNo, byte[] data); | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808MsgReplyConsumer : IJT808PubSub, IDisposable | |||||
{ | |||||
void OnMessage(Action<(string TerminalNo, byte[] Data)> callback); | |||||
CancellationTokenSource Cts { get; } | |||||
void Subscribe(); | |||||
void Unsubscribe(); | |||||
} | |||||
} |
@@ -1,17 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808MsgReplyProducer : IJT808PubSub, IDisposable | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="terminalNo">设备终端号</param> | |||||
/// <param name="data">808 hex data</param> | |||||
Task ProduceAsync(string terminalNo, byte[] data); | |||||
} | |||||
} |
@@ -1,15 +0,0 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808NettyBuilder | |||||
{ | |||||
IJT808Builder JT808Builder { get; } | |||||
IJT808Builder Builder(); | |||||
} | |||||
} |
@@ -1,11 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public interface IJT808PubSub | |||||
{ | |||||
string TopicName { get; } | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
/// <summary> | |||||
/// 会话通知(在线/离线) | |||||
/// </summary> | |||||
public interface IJT808SessionConsumer : IJT808PubSub, IDisposable | |||||
{ | |||||
void OnMessage(Action<(string Notice, string TerminalNo)> callback); | |||||
CancellationTokenSource Cts { get; } | |||||
void Subscribe(); | |||||
void Unsubscribe(); | |||||
} | |||||
} |
@@ -1,13 +0,0 @@ | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
/// <summary> | |||||
/// 会话通知(在线/离线) | |||||
/// </summary> | |||||
public interface IJT808SessionProducer : IJT808PubSub, IDisposable | |||||
{ | |||||
Task ProduceAsync(string notice,string terminalNo); | |||||
} | |||||
} |
@@ -1,32 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<Import Project="..\Version.props" /> | |||||
<PropertyGroup> | |||||
<TargetFrameworks>netstandard2.0;net5;</TargetFrameworks> | |||||
<LangVersion>9.0</LangVersion> | |||||
<Copyright>Copyright 2018.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<RepositoryUrl>https://github.com/SmallChi/JT808Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT808Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<Version>$(JT808DotNettyPackageVersion)</Version> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<PackageId>JT808.DotNetty.Abstractions</PackageId> | |||||
<Product>JT808.DotNetty.Abstractions</Product> | |||||
<Description>基于DotNetty实现的JT808DotNetty的抽象库</Description> | |||||
<PackageReleaseNotes>基于DotNetty实现的JT808DotNetty的抽象库</PackageReleaseNotes> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="JT808" Version="2.4.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -1,52 +0,0 @@ | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
public static class JT808NettyConstants | |||||
{ | |||||
public const string SessionOnline= "JT808SessionOnline"; | |||||
public const string SessionOffline = "JT808SessionOffline"; | |||||
public const string SessionTopic = "jt808session"; | |||||
public const string MsgTopic = "jt808msgdefault"; | |||||
public const string MsgReplyTopic = "jt808msgreplydefault"; | |||||
public static class JT808WebApiRouteTable | |||||
{ | |||||
public const string RouteTablePrefix = "/jt808api"; | |||||
public const string SessionPrefix = "Session"; | |||||
public const string TcpPrefix = "Tcp"; | |||||
public const string UdpPrefix = "Udp"; | |||||
/// <summary> | |||||
/// 基于Tcp的包计数器 | |||||
/// </summary> | |||||
public static string GetTcpAtomicCounter = $"{RouteTablePrefix}/{TcpPrefix}/GetAtomicCounter"; | |||||
/// <summary> | |||||
/// 基于Tcp的会话服务集合 | |||||
/// </summary> | |||||
public static string SessionTcpGetAll = $"{RouteTablePrefix}/{TcpPrefix}/{SessionPrefix}/GetAll"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号移除对应会话 | |||||
/// </summary> | |||||
public static string SessionRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/RemoveByTerminalPhoneNo"; | |||||
/// <summary> | |||||
/// 会话服务-通过设备终端号查询对应会话 | |||||
/// </summary> | |||||
public static string QueryTcpSessionByTerminalPhoneNo = $"{RouteTablePrefix}/{SessionPrefix}/QueryTcpSessionByTerminalPhoneNo"; | |||||
/// <summary> | |||||
/// 统一下发信息 | |||||
/// </summary> | |||||
public static string UnificationSend = $"{RouteTablePrefix}/UnificationSend"; | |||||
/// <summary> | |||||
/// 获取Udp包计数器 | |||||
/// </summary> | |||||
public static string GetUdpAtomicCounter = $"{RouteTablePrefix}/{UdpPrefix}/GetAtomicCounter"; | |||||
/// <summary> | |||||
/// 基于Udp的会话服务集合 | |||||
/// </summary> | |||||
public static string SessionUdpGetAll = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/GetAll"; | |||||
} | |||||
} | |||||
} |
@@ -1,13 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<!-- | |||||
https://go.microsoft.com/fwlink/?LinkID=208121. | |||||
--> | |||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | |||||
<PublishProtocol>FileSystem</PublishProtocol> | |||||
<Configuration>Release</Configuration> | |||||
<Platform>Any CPU</Platform> | |||||
<TargetFramework>netstandard2.0</TargetFramework> | |||||
<PublishDir>..\..\nupkgs</PublishDir> | |||||
</PropertyGroup> | |||||
</Project> |
@@ -1,6 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<!-- | |||||
https://go.microsoft.com/fwlink/?LinkID=208121. | |||||
--> | |||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
</Project> |
@@ -1,24 +0,0 @@ | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.CleintBenchmark.Configs | |||||
{ | |||||
public class ClientBenchmarkOptions : IOptions<ClientBenchmarkOptions> | |||||
{ | |||||
public string IP { get; set; } | |||||
public int Port { get; set; } | |||||
public int DeviceCount { get; set; } = 10; | |||||
/// <summary> | |||||
/// 5000ms毫秒 | |||||
/// </summary> | |||||
public int Interval { get; set; } = 5000; | |||||
/// <summary> | |||||
/// 需要多台机器同时访问,那么可以根据这个避开重复终端号 | |||||
/// 100000-200000-300000 | |||||
/// </summary> | |||||
public int DeviceTemplate { get; set; } = 0; | |||||
public ClientBenchmarkOptions Value =>this; | |||||
} | |||||
} |
@@ -1,36 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8" ?> | |||||
<!-- | |||||
参考:http://www.cnblogs.com/fuchongjundream/p/3936431.html | |||||
autoReload:自动再配置 | |||||
internalLogFile:可以让NLog把内部的调试和异常信息都写入指定文件里程序没问题了,日志却出了问题。这个该怎么办,到底是哪里不正确了?假如日志本身除了bug该如何解决?这就需要日志排错。把日志的错误信息写入日志。 | |||||
<nlog throwExceptions="true" /> | |||||
<nlog internalLogFile="file.txt" />- 设置internalLogFile属性可以让NLog把内部的调试和异常信息都写入指定文件里。 | |||||
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 决定内部日志的级别,级别越高,输出的日志信息越简洁。 | |||||
<nlog internalLogToConsole="false|true" /> - 是否把内部日志输出到标准控制台。 | |||||
<nlog internalLogToConsoleError="false|true" /> - 是否把内部日志输出到标准错误控制台 (stderr)。 | |||||
设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。 | |||||
--> | |||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd" | |||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
autoReload="true" | |||||
internalLogFile="/data/logs/JT808.DotNetty.Hosting/internalLog.txt" | |||||
internalLogLevel="Debug" > | |||||
<variable name="Directory" value="/data/logs/JT808.DotNetty.Hosting"/> | |||||
<targets> | |||||
<target name="all" xsi:type="File" | |||||
fileName="${Directory}/all/${shortdate}.log" | |||||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level}:${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"/> | |||||
<target name="console" xsi:type="ColoredConsole" | |||||
useDefaultRowHighlightingRules="false" | |||||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"> | |||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" /> | |||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" /> | |||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" /> | |||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" /> | |||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" /> | |||||
</target> | |||||
</targets> | |||||
<rules> | |||||
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/> | |||||
</rules> | |||||
</nlog> |
@@ -1,35 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8" ?> | |||||
<!-- | |||||
参考:http://www.cnblogs.com/fuchongjundream/p/3936431.html | |||||
autoReload:自动再配置 | |||||
internalLogFile:可以让NLog把内部的调试和异常信息都写入指定文件里程序没问题了,日志却出了问题。这个该怎么办,到底是哪里不正确了?假如日志本身除了bug该如何解决?这就需要日志排错。把日志的错误信息写入日志。 | |||||
<nlog throwExceptions="true" /> | |||||
<nlog internalLogFile="file.txt" />- 设置internalLogFile属性可以让NLog把内部的调试和异常信息都写入指定文件里。 | |||||
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" /> - 决定内部日志的级别,级别越高,输出的日志信息越简洁。 | |||||
<nlog internalLogToConsole="false|true" /> - 是否把内部日志输出到标准控制台。 | |||||
<nlog internalLogToConsoleError="false|true" /> - 是否把内部日志输出到标准错误控制台 (stderr)。 | |||||
设置throwExceptions属性为“true”可以让NLog不再阻挡这类异常,而是把它们抛给调用者。在部署是这样做可以帮我们快速定位问题。一旦应用程序已经正确配置了,我们建议把throwExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。 | |||||
--> | |||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd" | |||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
autoReload="true" | |||||
internalLogFile="${basedir}/wwwroot/logs/internalLog.txt" | |||||
internalLogLevel="Debug" > | |||||
<targets> | |||||
<target name="all" xsi:type="File" | |||||
fileName="${basedir}/wwwroot/logs/all/${shortdate}.log" | |||||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level}:${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"/> | |||||
<target name="console" xsi:type="ColoredConsole" | |||||
useDefaultRowHighlightingRules="false" | |||||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"> | |||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" /> | |||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" /> | |||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" /> | |||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" /> | |||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" /> | |||||
</target> | |||||
</targets> | |||||
<rules> | |||||
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/> | |||||
</rules> | |||||
</nlog> |
@@ -1,63 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.ComponentModel.DataAnnotations; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
using JT808.DotNetty.Client; | |||||
using JT808.DotNetty.Client.Metadata; | |||||
using JT808.DotNetty.Client.Services; | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Cors; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.Extensions.Caching.Memory; | |||||
using Microsoft.Extensions.Primitives; | |||||
namespace JT808.DotNetty.CleintBenchmark | |||||
{ | |||||
/// <summary> | |||||
/// 车辆控制器 | |||||
/// </summary> | |||||
[Route("JT808WebApi")] | |||||
[ApiController] | |||||
[EnableCors("Domain")] | |||||
public class ReportController : ControllerBase | |||||
{ | |||||
private readonly IJT808TcpClientFactory clientFactory; | |||||
private readonly JT808ReceiveAtomicCounterService ReceiveAtomicCounterService; | |||||
private readonly JT808SendAtomicCounterService SendAtomicCounterService; | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
public ReportController( | |||||
IJT808TcpClientFactory factory, | |||||
JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService, | |||||
JT808SendAtomicCounterService jT808SendAtomicCounterService) | |||||
{ | |||||
clientFactory = factory; | |||||
ReceiveAtomicCounterService = jT808ReceiveAtomicCounterService; | |||||
SendAtomicCounterService = jT808SendAtomicCounterService; | |||||
} | |||||
[HttpPost] | |||||
[HttpGet] | |||||
[Route("QueryReport")] | |||||
public ActionResult<JT808Report> QueryReport() | |||||
{ | |||||
var clients = clientFactory.GetAll(); | |||||
JT808Report report = new JT808Report() | |||||
{ | |||||
SendTotalCount = SendAtomicCounterService.MsgSuccessCount, | |||||
ReceiveTotalCount = ReceiveAtomicCounterService.MsgSuccessCount, | |||||
CurrentDate = DateTime.Now, | |||||
Connections = clients.Count, | |||||
OnlineConnections = clients.Where(w => w.IsOpen).Count(), | |||||
OfflineConnections = clients.Where(w => !w.IsOpen).Count(), | |||||
}; | |||||
return report; | |||||
} | |||||
} | |||||
} |
@@ -1,59 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>net5</TargetFramework> | |||||
<LangVersion>9.0</LangVersion> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Content Remove="wwwroot\echarts.min.js" /> | |||||
<Content Remove="wwwroot\index.html" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.3" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\JT808.DotNetty.Client\JT808.DotNetty.Client.csproj" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="wwwroot\echarts.min.js"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
<None Include="wwwroot\index.html"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Update="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</Content> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Update="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
<None Update="Configs\nlog.unix.config"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
<None Update="Configs\nlog.win.config"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
<None Update="Configs\NLog.xsd"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
<SubType>Designer</SubType> | |||||
</None> | |||||
</ItemGroup> | |||||
<ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions> | |||||
</Project> |
@@ -1,77 +0,0 @@ | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using NLog.Extensions.Logging; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
using JT808.Protocol; | |||||
using JT808.DotNetty.Client; | |||||
using JT808.DotNetty.CleintBenchmark.Configs; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using JT808.DotNetty.CleintBenchmark.Services; | |||||
namespace JT808.DotNetty.CleintBenchmark | |||||
{ | |||||
class Program | |||||
{ | |||||
static async Task Main(string[] args) | |||||
{ | |||||
var serverHostBuilder = new HostBuilder() | |||||
.ConfigureAppConfiguration((hostingContext, config) => | |||||
{ | |||||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||||
}) | |||||
.ConfigureWebHostDefaults(webBuilder => | |||||
{ | |||||
webBuilder.Configure(app => | |||||
{ | |||||
app.UseRouting(); | |||||
app.UseCors("Domain"); | |||||
app.UseStaticFiles(); | |||||
app.UseDefaultFiles("/index.html"); | |||||
app.UseEndpoints(endpoints => | |||||
{ | |||||
endpoints.MapControllers(); | |||||
}); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => | |||||
{ | |||||
services.AddControllers(); | |||||
services.AddCors(options => | |||||
options.AddPolicy("Domain", builder => | |||||
builder.AllowAnyOrigin() | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.AllowAnyOrigin())); | |||||
}); | |||||
}) | |||||
.ConfigureLogging((context, logging) => | |||||
{ | |||||
if (Environment.OSVersion.Platform == PlatformID.Unix) | |||||
{ | |||||
NLog.LogManager.LoadConfiguration("Configs/nlog.unix.config"); | |||||
} | |||||
else | |||||
{ | |||||
NLog.LogManager.LoadConfiguration("Configs/nlog.win.config"); | |||||
} | |||||
logging.AddNLog(); | |||||
logging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices((hostContext, services) => | |||||
{ | |||||
services.Configure<ClientBenchmarkOptions>(hostContext.Configuration.GetSection("ClientBenchmarkOptions")); | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||||
services.AddJT808Configure() | |||||
.AddJT808Client(); | |||||
services.AddHostedService<CleintBenchmarkHostedService>(); | |||||
}); | |||||
await serverHostBuilder.RunConsoleAsync(); | |||||
} | |||||
} | |||||
} |
@@ -1,90 +0,0 @@ | |||||
using JT808.DotNetty.CleintBenchmark.Configs; | |||||
using JT808.DotNetty.Client; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
using JT808.Protocol.MessageBody; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.CleintBenchmark.Services | |||||
{ | |||||
public class CleintBenchmarkHostedService : IHostedService | |||||
{ | |||||
private readonly ClientBenchmarkOptions clientBenchmarkOptions; | |||||
private readonly ILogger logger; | |||||
private readonly IJT808TcpClientFactory jT808TcpClientFactory; | |||||
public CleintBenchmarkHostedService( | |||||
ILoggerFactory loggerFactory, | |||||
IJT808TcpClientFactory jT808TcpClientFactory, | |||||
IOptions<ClientBenchmarkOptions> clientBenchmarkOptionsAccessor) | |||||
{ | |||||
this.jT808TcpClientFactory = jT808TcpClientFactory; | |||||
clientBenchmarkOptions = clientBenchmarkOptionsAccessor.Value; | |||||
logger = loggerFactory.CreateLogger("CleintBenchmarkHostedService"); | |||||
} | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | |||||
logger.LogInformation("StartAsync..."); | |||||
ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads); | |||||
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads); | |||||
logger.LogInformation($"GetMinThreads:{minWorkerThreads}-{minCompletionPortThreads}"); | |||||
logger.LogInformation($"GetMaxThreads:{maxWorkerThreads}-{maxCompletionPortThreads}"); | |||||
//先建立连接 | |||||
for (int i=0;i< clientBenchmarkOptions.DeviceCount; i++) | |||||
{ | |||||
var client = jT808TcpClientFactory.Create(new JT808DeviceConfig((i+1+ clientBenchmarkOptions.DeviceTemplate).ToString(), | |||||
clientBenchmarkOptions.IP, | |||||
clientBenchmarkOptions.Port)); | |||||
} | |||||
ThreadPool.QueueUserWorkItem((state) => | |||||
{ | |||||
while (!cancellationToken.IsCancellationRequested) | |||||
{ | |||||
Parallel.ForEach(jT808TcpClientFactory.GetAll(), new ParallelOptions { MaxDegreeOfParallelism = 100 }, (item) => | |||||
{ | |||||
try | |||||
{ | |||||
int lat = new Random(1000).Next(100000, 180000); | |||||
int Lng = new Random(1000).Next(100000, 180000); | |||||
item.Send(JT808MsgId.位置信息汇报.Create(item.DeviceConfig.TerminalPhoneNo, new JT808_0x0200() | |||||
{ | |||||
Lat = lat, | |||||
Lng = Lng, | |||||
GPSTime = DateTime.Now, | |||||
Speed = 50, | |||||
Direction = 30, | |||||
AlarmFlag = 5, | |||||
Altitude = 50, | |||||
StatusFlag = 10 | |||||
})); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex.Message); | |||||
} | |||||
}); | |||||
Thread.Sleep(clientBenchmarkOptions.Interval); | |||||
} | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
jT808TcpClientFactory.Dispose(); | |||||
logger.LogInformation("StopAsync..."); | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,24 +0,0 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Error" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Error" | |||||
} | |||||
} | |||||
}, | |||||
"AllowedHosts": "*", | |||||
//"urls": "http://*:15004;", | |||||
"ClientBenchmarkOptions": { | |||||
"IP": "127.0.0.1", | |||||
"Port": 808, | |||||
"DeviceCount": 100, | |||||
"Interval": 1000, | |||||
"DeviceTemplate": 100000 //需要多台机器同时访问,那么可以根据这个避开重复终端号 100000-200000-300000 | |||||
} | |||||
} |
@@ -1,153 +0,0 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<head> | |||||
<meta charset="utf-8" /> | |||||
<title>收发查看</title> | |||||
<script src="https://unpkg.com/dayjs"></script> | |||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> | |||||
<script src="/echarts.min.js"></script> | |||||
</head> | |||||
<body> | |||||
<div id="tcpContainer" style="text-align:center;margin:20px auto;width:80%;height: 300px;"></div> | |||||
<div id="connContainer" style="text-align:center;margin:20px auto;width:80%;height: 300px;"></div> | |||||
<script type="text/javascript"> | |||||
var tcpDom = document.getElementById("tcpContainer"); | |||||
var connDom = document.getElementById("connContainer"); | |||||
var tcpChart = echarts.init(tcpDom); | |||||
var connChart = echarts.init(connDom); | |||||
var sendData=[]; | |||||
var receiveData=[]; | |||||
var onlineData=[]; | |||||
var offlineData=[]; | |||||
var timeData=[]; | |||||
var tcpOption = { | |||||
title: { | |||||
text: 'TCP收发数' | |||||
}, | |||||
tooltip: { | |||||
trigger: 'axis', | |||||
axisPointer: { | |||||
animation: true | |||||
} | |||||
}, | |||||
legend: { | |||||
data:['发送总次数','接收总次数'] | |||||
}, | |||||
xAxis: { | |||||
type: 'category', | |||||
boundaryGap: false, | |||||
data: timeData | |||||
}, | |||||
yAxis: { | |||||
type: 'value', | |||||
boundaryGap: [0, '100%'], | |||||
splitLine: { | |||||
show: true | |||||
} | |||||
}, | |||||
series: [{ | |||||
name: '发送总次数', | |||||
type: 'line', | |||||
color: "blue", | |||||
data: sendData | |||||
},{ | |||||
name: '接收总次数', | |||||
type: 'line', | |||||
color: "red", | |||||
data: receiveData | |||||
}] | |||||
}; | |||||
var connOption = { | |||||
title: { | |||||
text: 'TCP连接数' | |||||
}, | |||||
tooltip: { | |||||
trigger: 'axis', | |||||
axisPointer: { | |||||
animation: true | |||||
} | |||||
}, | |||||
legend: { | |||||
data:['tcp在线数','tcp离线数'] | |||||
}, | |||||
xAxis: { | |||||
type: 'category', | |||||
boundaryGap: false, | |||||
data: timeData | |||||
}, | |||||
yAxis: { | |||||
type: 'value', | |||||
boundaryGap: [0, '100%'], | |||||
splitLine: { | |||||
show: true | |||||
} | |||||
}, | |||||
series: [{ | |||||
name: 'tcp在线数', | |||||
type: 'line', | |||||
color: "blue", | |||||
data: onlineData | |||||
},{ | |||||
name: 'tcp离线数', | |||||
type: 'line', | |||||
color: "red", | |||||
data: offlineData | |||||
}] | |||||
}; | |||||
setInterval(function () { | |||||
axios.post('http://localhost:5000/JT808WebApi/QueryReport') | |||||
.then((response) => { | |||||
if (response.data) { | |||||
if(sendData.length>16){ | |||||
sendData.shift(); | |||||
receiveData.shift(); | |||||
onlineData.shift(); | |||||
offlineData.shift(); | |||||
timeData.shift(); | |||||
} | |||||
//console.log(response.data); | |||||
timeData.push(dayjs(response.data.currentDate).format('HH:mm:ss')); | |||||
sendData.push(response.data.sendTotalCount); | |||||
receiveData.push(response.data.receiveTotalCount); | |||||
onlineData.push(response.data.onlineConnections); | |||||
offlineData.push(response.data.offlineConnections); | |||||
tcpChart.setOption({ | |||||
series: [{ | |||||
data: sendData | |||||
},{ | |||||
data: receiveData | |||||
}], | |||||
xAxis:[{ | |||||
data: timeData | |||||
}] | |||||
}); | |||||
connChart.setOption({ | |||||
series: [{ | |||||
data: onlineData | |||||
},{ | |||||
data: offlineData | |||||
}], | |||||
xAxis:[{ | |||||
data: timeData | |||||
}] | |||||
}); | |||||
} else { | |||||
alert("没有数据"); | |||||
} | |||||
}) | |||||
.catch((error) => { | |||||
console.log(error); | |||||
}); | |||||
}, 1000); | |||||
if (tcpOption && typeof tcpOption === "object") { | |||||
tcpChart.setOption(tcpOption, true); | |||||
} | |||||
if (connOption && typeof connOption === "object") { | |||||
connChart.setOption(connOption, true); | |||||
} | |||||
</script> | |||||
</body> | |||||
</html> |
@@ -1,20 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using System.Collections.Generic; | |||||
using JT808.Protocol; | |||||
using DotNetty.Transport.Channels; | |||||
namespace JT808.DotNetty.Client.Codecs | |||||
{ | |||||
public class JT808ClientTcpDecoder : ByteToMessageDecoder | |||||
{ | |||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> 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); | |||||
} | |||||
} | |||||
} |
@@ -1,54 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using JT808.Protocol; | |||||
using DotNetty.Transport.Channels; | |||||
using Microsoft.Extensions.Logging; | |||||
using JT808.DotNetty.Client.Metadata; | |||||
using JT808.DotNetty.Client.Services; | |||||
using System; | |||||
using JT808.Protocol.Exceptions; | |||||
namespace JT808.DotNetty.Client.Codecs | |||||
{ | |||||
public class JT808ClientTcpEncoder : MessageToByteEncoder<JT808ClientRequest> | |||||
{ | |||||
private readonly ILogger<JT808ClientTcpEncoder> logger; | |||||
private readonly JT808SendAtomicCounterService jT808SendAtomicCounterService; | |||||
private readonly JT808Serializer JT808Serializer; | |||||
public JT808ClientTcpEncoder( | |||||
IJT808Config jT808Config, | |||||
JT808SendAtomicCounterService jT808SendAtomicCounterService,ILoggerFactory loggerFactory) | |||||
{ | |||||
logger=loggerFactory.CreateLogger<JT808ClientTcpEncoder>(); | |||||
this.jT808SendAtomicCounterService = jT808SendAtomicCounterService; | |||||
JT808Serializer = jT808Config.GetSerializer(); | |||||
} | |||||
protected override void Encode(IChannelHandlerContext context, JT808ClientRequest message, IByteBuffer output) | |||||
{ | |||||
if (message.Package != null) | |||||
{ | |||||
try | |||||
{ | |||||
var sendData = JT808Serializer.Serialize(message.Package,version: message.Version, minBufferSize:message.MinBufferSize); | |||||
output.WriteBytes(sendData); | |||||
jT808SendAtomicCounterService.MsgSuccessIncrement(); | |||||
} | |||||
catch (JT808Exception ex) | |||||
{ | |||||
logger.LogError(ex, context.Channel.Id.AsShortText()); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex,$" context.Channel.Id.AsShortText()"); | |||||
} | |||||
} | |||||
else if (message.HexData != null) | |||||
{ | |||||
output.WriteBytes(message.HexData); | |||||
jT808SendAtomicCounterService.MsgSuccessIncrement(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,103 +0,0 @@ | |||||
using DotNetty.Handlers.Timeout; | |||||
using DotNetty.Transport.Channels; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
using JT808.Protocol.MessageBody; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Client.Handlers | |||||
{ | |||||
/// <summary> | |||||
/// JT808客户端连接通道处理程序 | |||||
/// </summary> | |||||
public class JT808TcpClientConnectionHandler : ChannelHandlerAdapter | |||||
{ | |||||
private readonly ILogger logger; | |||||
private readonly JT808TcpClient jT808TcpClient; | |||||
public JT808TcpClientConnectionHandler( | |||||
JT808TcpClient jT808TcpClient) | |||||
{ | |||||
logger = jT808TcpClient.LoggerFactory.CreateLogger<JT808TcpClientConnectionHandler>(); | |||||
this.jT808TcpClient = jT808TcpClient; | |||||
} | |||||
/// <summary> | |||||
/// 通道激活 | |||||
/// </summary> | |||||
/// <param name="context"></param> | |||||
public override void ChannelActive(IChannelHandlerContext context) | |||||
{ | |||||
string channelId = context.Channel.Id.AsShortText(); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
logger.LogDebug($"<<<{ channelId } Successful client connection to server."); | |||||
base.ChannelActive(context); | |||||
} | |||||
/// <summary> | |||||
/// 设备主动断开 | |||||
/// </summary> | |||||
/// <param name="context"></param> | |||||
public override void ChannelInactive(IChannelHandlerContext context) | |||||
{ | |||||
string channelId = context.Channel.Id.AsShortText(); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
logger.LogDebug($">>>{ channelId } The client disconnects from the server."); | |||||
base.ChannelInactive(context); | |||||
} | |||||
/// <summary> | |||||
/// 服务器主动断开 | |||||
/// </summary> | |||||
/// <param name="context"></param> | |||||
/// <returns></returns> | |||||
public override Task CloseAsync(IChannelHandlerContext context) | |||||
{ | |||||
string channelId = context.Channel.Id.AsShortText(); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
logger.LogDebug($"<<<{ channelId } The server disconnects from the client."); | |||||
return base.CloseAsync(context); | |||||
} | |||||
public override void ChannelReadComplete(IChannelHandlerContext context)=> context.Flush(); | |||||
/// <summary> | |||||
/// 超时策略 | |||||
/// </summary> | |||||
/// <param name="context"></param> | |||||
/// <param name="evt"></param> | |||||
public override void UserEventTriggered(IChannelHandlerContext context, object evt) | |||||
{ | |||||
IdleStateEvent idleStateEvent = evt as IdleStateEvent; | |||||
if (idleStateEvent != null) | |||||
{ | |||||
if(idleStateEvent.State== IdleState.WriterIdle) | |||||
{ | |||||
string channelId = context.Channel.Id.AsShortText(); | |||||
logger.LogInformation($"{idleStateEvent.State.ToString()}>>>{channelId}"); | |||||
if(jT808TcpClient.DeviceConfig.Version== JT808Version.JTT2019) | |||||
{ | |||||
jT808TcpClient.Send(JT808MsgId.终端心跳.Create2019(jT808TcpClient.DeviceConfig.TerminalPhoneNo,new JT808_0x0002())); | |||||
} | |||||
else | |||||
{ | |||||
jT808TcpClient.Send(JT808MsgId.终端心跳.Create(jT808TcpClient.DeviceConfig.TerminalPhoneNo, new JT808_0x0002())); | |||||
} | |||||
} | |||||
} | |||||
base.UserEventTriggered(context, evt); | |||||
} | |||||
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) | |||||
{ | |||||
string channelId = context.Channel.Id.AsShortText(); | |||||
logger.LogError(exception,$"{channelId} {exception.Message}" ); | |||||
context.CloseAsync(); | |||||
} | |||||
} | |||||
} | |||||
@@ -1,30 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Transport.Channels; | |||||
using System; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using JT808.DotNetty.Client.Services; | |||||
namespace JT808.DotNetty.Client.Handlers | |||||
{ | |||||
/// <summary> | |||||
/// JT808客户端处理程序 | |||||
/// </summary> | |||||
internal class JT808TcpClientHandler : SimpleChannelInboundHandler<byte[]> | |||||
{ | |||||
private readonly ILogger<JT808TcpClientHandler> logger; | |||||
private readonly JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService; | |||||
public JT808TcpClientHandler(JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService,JT808TcpClient jT808TcpClient) | |||||
{ | |||||
logger = jT808TcpClient.LoggerFactory.CreateLogger<JT808TcpClientHandler>(); | |||||
this.jT808ReceiveAtomicCounterService= jT808ReceiveAtomicCounterService; | |||||
} | |||||
protected override void ChannelRead0(IChannelHandlerContext ctx, byte[] msg) | |||||
{ | |||||
if(logger.IsEnabled(LogLevel.Trace)) | |||||
logger.LogTrace("accept msg<<<" + ByteBufferUtil.HexDump(msg)); | |||||
jT808ReceiveAtomicCounterService.MsgSuccessIncrement(); | |||||
} | |||||
} | |||||
} |
@@ -1,37 +0,0 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<Import Project="..\Version.props" /> | |||||
<PropertyGroup> | |||||
<TargetFrameworks>netstandard2.0;net5;</TargetFrameworks> | |||||
<LangVersion>9.0</LangVersion> | |||||
<Copyright>Copyright 2018.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<RepositoryUrl>https://github.com/SmallChi/JT808Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT808Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT808Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<Version>$(JT808DotNettyPackageVersion)</Version> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<PackageId>JT808.DotNetty.Client</PackageId> | |||||
<Product>JT808.DotNetty.Client</Product> | |||||
<Description>基于DotNetty实现的JT808DotNetty的客户端工具</Description> | |||||
<PackageReleaseNotes>基于DotNetty实现的JT808DotNetty的客户端工具</PackageReleaseNotes> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="DotNetty.Handlers" Version="0.7.0" /> | |||||
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.7.0" /> | |||||
<PackageReference Include="DotNetty.Codecs" Version="0.7.0" /> | |||||
<PackageReference Include="JT808" Version="2.4.4" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" /> | |||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -1,42 +0,0 @@ | |||||
using JT808.DotNetty.Client.Services; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using JT808.Protocol; | |||||
using Microsoft.Extensions.Configuration; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public static class JT808ClientDotnettyExtensions | |||||
{ | |||||
public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder) | |||||
{ | |||||
jT808Builder.Services.AddSingleton<JT808SendAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<JT808ReceiveAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<IJT808TcpClientFactory, JT808TcpClientFactory>(); | |||||
jT808Builder.Services.Configure<JT808ReportOptions>((options)=> { }); | |||||
jT808Builder.Services.AddHostedService<JT808ReportHostedService>(); | |||||
return jT808Builder; | |||||
} | |||||
public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder, IConfiguration Configuration) | |||||
{ | |||||
jT808Builder.Services.AddSingleton<JT808SendAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<JT808ReceiveAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<IJT808TcpClientFactory, JT808TcpClientFactory>(); | |||||
jT808Builder.Services.Configure<JT808ReportOptions>(Configuration.GetSection("JT808ReportOptions")); | |||||
jT808Builder.Services.AddHostedService<JT808ReportHostedService>(); | |||||
return jT808Builder; | |||||
} | |||||
public static IJT808Builder AddJT808Client(this IJT808Builder jT808Builder, Action<JT808ReportOptions> reportAction) | |||||
{ | |||||
jT808Builder.Services.AddSingleton<JT808SendAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<JT808ReceiveAtomicCounterService>(); | |||||
jT808Builder.Services.AddSingleton<IJT808TcpClientFactory, JT808TcpClientFactory>(); | |||||
jT808Builder.Services.Configure(reportAction); | |||||
jT808Builder.Services.AddHostedService<JT808ReportHostedService>(); | |||||
return jT808Builder; | |||||
} | |||||
} | |||||
} |
@@ -1,30 +0,0 @@ | |||||
using JT808.Protocol; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Interfaces; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public class JT808DeviceConfig | |||||
{ | |||||
public JT808DeviceConfig(string terminalPhoneNo, string tcpHost,int tcpPort, JT808Version version= JT808Version.JTT2013) | |||||
{ | |||||
TerminalPhoneNo = terminalPhoneNo; | |||||
TcpHost = tcpHost; | |||||
TcpPort = tcpPort; | |||||
Version = version; | |||||
} | |||||
public JT808Version Version { get; private set; } | |||||
public string TerminalPhoneNo { get; private set; } | |||||
public string TcpHost { get; private set; } | |||||
public int TcpPort { get; private set; } | |||||
/// <summary> | |||||
/// 心跳时间(秒) | |||||
/// </summary> | |||||
public int Heartbeat { get; set; } = 30; | |||||
public IJT808MsgSNDistributed MsgSNDistributed { get; } | |||||
} | |||||
} |
@@ -1,25 +0,0 @@ | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public class JT808ReportOptions:IOptions<JT808ReportOptions> | |||||
{ | |||||
public string FileName { get; set; } = $"JT808Report.{DateTime.Now.ToString("yyyyMMddHHssmm")}.txt"; | |||||
public string FilePath { get; set; } = AppDomain.CurrentDomain.BaseDirectory; | |||||
public string FileFullPath { get { return Path.Combine(FilePath, FileName); } } | |||||
public int Interval { get; set; } = 3; | |||||
public JT808ReportOptions Value => this; | |||||
public void FileExistsAndCreate() | |||||
{ | |||||
if(!File.Exists(FileFullPath)) | |||||
{ | |||||
File.Create(FileFullPath).Close(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,112 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using DotNetty.Handlers.Timeout; | |||||
using DotNetty.Transport.Bootstrapping; | |||||
using DotNetty.Transport.Channels; | |||||
using DotNetty.Transport.Channels.Sockets; | |||||
using JT808.DotNetty.Client.Handlers; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Runtime.InteropServices; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System.Net; | |||||
using JT808.DotNetty.Client.Metadata; | |||||
using JT808.DotNetty.Client.Codecs; | |||||
using JT808.DotNetty.Client.Services; | |||||
using JT808.Protocol; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public sealed class JT808TcpClient : IDisposable | |||||
{ | |||||
private MultithreadEventLoopGroup group; | |||||
private IChannel clientChannel; | |||||
private bool disposed = false; | |||||
public JT808DeviceConfig DeviceConfig { get; private set; } | |||||
public ILoggerFactory LoggerFactory { get; private set; } | |||||
public JT808TcpClient(JT808DeviceConfig deviceConfig, IServiceProvider serviceProvider) | |||||
{ | |||||
DeviceConfig = deviceConfig; | |||||
LoggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); | |||||
JT808SendAtomicCounterService jT808SendAtomicCounterService = serviceProvider.GetRequiredService<JT808SendAtomicCounterService>(); | |||||
JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService = serviceProvider.GetRequiredService<JT808ReceiveAtomicCounterService>(); | |||||
IJT808Config jT808Config = serviceProvider.GetRequiredService<IJT808Config>(); | |||||
group = new MultithreadEventLoopGroup(1); | |||||
Bootstrap bootstrap = new Bootstrap(); | |||||
bootstrap.Group(group); | |||||
bootstrap.Channel<TcpSocketChannel>(); | |||||
bootstrap | |||||
.Option(ChannelOption.Allocator, new UnpooledByteBufferAllocator()) | |||||
.Handler(new ActionChannelInitializer<IChannel>(channel => | |||||
{ | |||||
channel.Pipeline.AddLast("jt808TcpBuffer", new DelimiterBasedFrameDecoder(65535, | |||||
Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }), | |||||
Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag }))); | |||||
channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(60, deviceConfig.Heartbeat, 3600)); | |||||
channel.Pipeline.AddLast("jt808TcpDecode", new JT808ClientTcpDecoder()); | |||||
channel.Pipeline.AddLast("jt808TcpEncode", new JT808ClientTcpEncoder(jT808Config,jT808SendAtomicCounterService, LoggerFactory)); | |||||
channel.Pipeline.AddLast("jt808TcpClientConnection", new JT808TcpClientConnectionHandler(this)); | |||||
channel.Pipeline.AddLast("jt808TcpService", new JT808TcpClientHandler(jT808ReceiveAtomicCounterService,this)); | |||||
})); | |||||
Task.Run(async () => | |||||
{ | |||||
clientChannel = await bootstrap.ConnectAsync(IPAddress.Parse(DeviceConfig.TcpHost), DeviceConfig.TcpPort); | |||||
}); | |||||
} | |||||
public void Send(JT808ClientRequest request) | |||||
{ | |||||
if (disposed) return; | |||||
if (clientChannel == null) throw new NullReferenceException("Channel is empty."); | |||||
if (request == null) throw new ArgumentNullException("JT808ClientRequest Parameter is empty."); | |||||
if (clientChannel.Active && clientChannel.Open) | |||||
{ | |||||
clientChannel.WriteAndFlushAsync(request); | |||||
} | |||||
} | |||||
public bool IsOpen | |||||
{ | |||||
get | |||||
{ | |||||
if (clientChannel == null) return false; | |||||
return clientChannel.Active && clientChannel.Open; | |||||
} | |||||
} | |||||
private void Dispose(bool disposing) | |||||
{ | |||||
if (disposed) | |||||
{ | |||||
return; | |||||
} | |||||
if (disposing) | |||||
{ | |||||
// 清理托管资源 | |||||
group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)); | |||||
} | |||||
disposed = true; | |||||
} | |||||
~JT808TcpClient() | |||||
{ | |||||
//必须为false | |||||
//这表明,隐式清理时,只要处理非托管资源就可以了。 | |||||
Dispose(false); | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
//必须为true | |||||
Dispose(true); | |||||
//通知垃圾回收机制不再调用终结器(析构器) | |||||
GC.SuppressFinalize(this); | |||||
} | |||||
} | |||||
} |
@@ -1,22 +0,0 @@ | |||||
using JT808.DotNetty.Client.Metadata; | |||||
using JT808.Protocol; | |||||
using JT808.Protocol.MessageBody; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using JT808.Protocol.Enums; | |||||
using JT808.Protocol.Extensions; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public static class JT808TcpClientExtensions | |||||
{ | |||||
public static void Send(this JT808TcpClient client, JT808Package package, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096) | |||||
{ | |||||
package.Header.TerminalPhoneNo = client.DeviceConfig.TerminalPhoneNo; | |||||
JT808ClientRequest request = new JT808ClientRequest(package, version, minBufferSize); | |||||
client.Send(request); | |||||
} | |||||
} | |||||
} |
@@ -1,62 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Concurrent; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JT808.DotNetty.Client | |||||
{ | |||||
public interface IJT808TcpClientFactory : IDisposable | |||||
{ | |||||
JT808TcpClient Create(JT808DeviceConfig deviceConfig); | |||||
List<JT808TcpClient> GetAll(); | |||||
} | |||||
public class JT808TcpClientFactory: IJT808TcpClientFactory | |||||
{ | |||||
private readonly ConcurrentDictionary<string, JT808TcpClient> dict; | |||||
private readonly IServiceProvider serviceProvider; | |||||
public JT808TcpClientFactory(IServiceProvider serviceProvider) | |||||
{ | |||||
dict = new ConcurrentDictionary<string, JT808TcpClient>(StringComparer.OrdinalIgnoreCase); | |||||
this.serviceProvider = serviceProvider; | |||||
} | |||||
public JT808TcpClient Create(JT808DeviceConfig deviceConfig) | |||||
{ | |||||
if(dict.TryGetValue(deviceConfig.TerminalPhoneNo,out var client)) | |||||
{ | |||||
return client; | |||||
} | |||||
else | |||||
{ | |||||
JT808TcpClient jT808TcpClient = new JT808TcpClient(deviceConfig, serviceProvider); | |||||
dict.TryAdd(deviceConfig.TerminalPhoneNo, jT808TcpClient); | |||||
return jT808TcpClient; | |||||
} | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
foreach(var client in dict) | |||||
{ | |||||
try | |||||
{ | |||||
client.Value.Dispose(); | |||||
} | |||||
catch | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
public List<JT808TcpClient> GetAll() | |||||
{ | |||||
return dict.Values.ToList(); | |||||
} | |||||
} | |||||
} |
@@ -1,49 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading; | |||||
namespace JT808.DotNetty.Client.Metadata | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// <see cref="Grpc.Core.Internal"/> | |||||
/// </summary> | |||||
internal class JT808AtomicCounter | |||||
{ | |||||
long counter = 0; | |||||
public JT808AtomicCounter(long initialCount = 0) | |||||
{ | |||||
this.counter = initialCount; | |||||
} | |||||
public void Reset() | |||||
{ | |||||
Interlocked.Exchange(ref counter, 0); | |||||
} | |||||
public long Increment() | |||||
{ | |||||
return Interlocked.Increment(ref counter); | |||||
} | |||||
public long Add(long len) | |||||
{ | |||||
return Interlocked.Add(ref counter,len); | |||||
} | |||||
public long Decrement() | |||||
{ | |||||
return Interlocked.Decrement(ref counter); | |||||
} | |||||
public long Count | |||||
{ | |||||
get | |||||
{ | |||||
return Interlocked.Read(ref counter); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,34 +0,0 @@ | |||||
using JT808.Protocol; | |||||
using JT808.Protocol.Enums; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Reflection; | |||||
namespace JT808.DotNetty.Client.Metadata | |||||
{ | |||||
public class JT808ClientRequest | |||||
{ | |||||
public JT808Package Package { get; } | |||||
public byte[] HexData { get; } | |||||
public JT808Version Version { get; } | |||||
/// <summary> | |||||
/// 根据实际情况适当调整包的大小 | |||||
/// </summary> | |||||
public int MinBufferSize { get;} | |||||
public JT808ClientRequest(JT808Package package, JT808Version version= JT808Version.JTT2013, int minBufferSize=1024) | |||||
{ | |||||
Package = package; | |||||
MinBufferSize = minBufferSize; | |||||
Version = version; | |||||
} | |||||
public JT808ClientRequest(byte[] hexData) | |||||
{ | |||||
HexData = hexData; | |||||
} | |||||
} | |||||
} |
@@ -1,16 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Client.Metadata | |||||
{ | |||||
public class JT808Report | |||||
{ | |||||
public long SendTotalCount { get; set; } | |||||
public long ReceiveTotalCount { get; set; } | |||||
public DateTime CurrentDate { get; set; } | |||||
public int Connections { get; set; } | |||||
public int OnlineConnections { get; set; } | |||||
public int OfflineConnections { get; set; } | |||||
} | |||||
} |
@@ -1,35 +0,0 @@ | |||||
using JT808.DotNetty.Client.Metadata; | |||||
namespace JT808.DotNetty.Client.Services | |||||
{ | |||||
/// <summary> | |||||
/// 接收计数包服务 | |||||
/// </summary> | |||||
public class JT808ReceiveAtomicCounterService | |||||
{ | |||||
private readonly JT808AtomicCounter MsgSuccessCounter; | |||||
public JT808ReceiveAtomicCounterService() | |||||
{ | |||||
MsgSuccessCounter=new JT808AtomicCounter(); | |||||
} | |||||
public void Reset() | |||||
{ | |||||
MsgSuccessCounter.Reset(); | |||||
} | |||||
public long MsgSuccessIncrement() | |||||
{ | |||||
return MsgSuccessCounter.Increment(); | |||||
} | |||||
public long MsgSuccessCount | |||||
{ | |||||
get | |||||
{ | |||||
return MsgSuccessCounter.Count; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,67 +0,0 @@ | |||||
using JT808.DotNetty.Client.Metadata; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Client.Services | |||||
{ | |||||
public class JT808ReportHostedService : BackgroundService | |||||
{ | |||||
private readonly IOptionsMonitor<JT808ReportOptions> jT808ReportOptions; | |||||
private readonly JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService; | |||||
private readonly JT808SendAtomicCounterService jT808SendAtomicCounterService; | |||||
private readonly IJT808TcpClientFactory jT808TcpClientFactory; | |||||
private readonly ILogger logger; | |||||
public JT808ReportHostedService( | |||||
ILoggerFactory loggerFactory, | |||||
IOptionsMonitor<JT808ReportOptions> jT808ReportOptionsAccessor, | |||||
JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService, | |||||
JT808SendAtomicCounterService jT808SendAtomicCounterService, | |||||
IJT808TcpClientFactory jT808TcpClientFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger("JT808ReportHostedService"); | |||||
jT808ReportOptions = jT808ReportOptionsAccessor; | |||||
jT808ReportOptions.CurrentValue.FileExistsAndCreate(); | |||||
this.jT808ReceiveAtomicCounterService = jT808ReceiveAtomicCounterService; | |||||
this.jT808SendAtomicCounterService = jT808SendAtomicCounterService; | |||||
this.jT808TcpClientFactory = jT808TcpClientFactory; | |||||
jT808ReportOptions.OnChange((options) => { options.FileExistsAndCreate(); }); | |||||
} | |||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) | |||||
{ | |||||
while (!stoppingToken.IsCancellationRequested) | |||||
{ | |||||
var clients = jT808TcpClientFactory.GetAll(); | |||||
JT808Report report = new JT808Report() | |||||
{ | |||||
SendTotalCount = jT808SendAtomicCounterService.MsgSuccessCount, | |||||
ReceiveTotalCount = jT808ReceiveAtomicCounterService.MsgSuccessCount, | |||||
CurrentDate = DateTime.Now, | |||||
Connections = clients.Count, | |||||
OnlineConnections = clients.Where(w => w.IsOpen).Count(), | |||||
OfflineConnections = clients.Where(w => !w.IsOpen).Count(), | |||||
}; | |||||
string json = JsonConvert.SerializeObject(report); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug(json); | |||||
} | |||||
using (var sw=new StreamWriter(jT808ReportOptions.CurrentValue.FileFullPath,true)) | |||||
{ | |||||
sw.WriteLine(json); | |||||
} | |||||
await Task.Delay(TimeSpan.FromSeconds(jT808ReportOptions.CurrentValue.Interval), stoppingToken); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,35 +0,0 @@ | |||||
using JT808.DotNetty.Client.Metadata; | |||||
namespace JT808.DotNetty.Client.Services | |||||
{ | |||||
/// <summary> | |||||
/// 发送计数包服务 | |||||
/// </summary> | |||||
public class JT808SendAtomicCounterService | |||||
{ | |||||
private readonly JT808AtomicCounter MsgSuccessCounter; | |||||
public JT808SendAtomicCounterService() | |||||
{ | |||||
MsgSuccessCounter=new JT808AtomicCounter(); | |||||
} | |||||
public void Reset() | |||||
{ | |||||
MsgSuccessCounter.Reset(); | |||||
} | |||||
public long MsgSuccessIncrement() | |||||
{ | |||||
return MsgSuccessCounter.Increment(); | |||||
} | |||||
public long MsgSuccessCount | |||||
{ | |||||
get | |||||
{ | |||||
return MsgSuccessCounter.Count; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,32 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using System.Collections.Generic; | |||||
using JT808.Protocol; | |||||
using DotNetty.Transport.Channels; | |||||
namespace JT808.DotNetty.Core.Codecs | |||||
{ | |||||
public class JT808TcpDecoder : ByteToMessageDecoder | |||||
{ | |||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output) | |||||
{ | |||||
//过滤掉不是808标准包 | |||||
//不包括头尾标识 | |||||
//(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1 | |||||
if (input.Capacity < 12) | |||||
{ | |||||
byte[] buffer = new byte[input.Capacity]; | |||||
input.ReadBytes(buffer, 0, input.Capacity); | |||||
return; | |||||
} | |||||
else | |||||
{ | |||||
byte[] buffer = new byte[input.Capacity + 2]; | |||||
input.ReadBytes(buffer, 1, input.Capacity); | |||||
buffer[0] = JT808Package.BeginFlag; | |||||
buffer[input.Capacity + 1] = JT808Package.EndFlag; | |||||
output.Add(buffer); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,52 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using JT808.Protocol; | |||||
using DotNetty.Transport.Channels; | |||||
using JT808.DotNetty.Core.Interfaces; | |||||
using Microsoft.Extensions.Logging; | |||||
using JT808.Protocol.Interfaces; | |||||
namespace JT808.DotNetty.Core.Codecs | |||||
{ | |||||
/// <summary> | |||||
/// tcp统一下发出口 | |||||
/// </summary> | |||||
public class JT808TcpEncoder : MessageToByteEncoder<IJT808Reply> | |||||
{ | |||||
private readonly ILogger<JT808TcpEncoder> logger; | |||||
private readonly JT808Serializer JT808Serializer; | |||||
public JT808TcpEncoder( | |||||
IJT808Config jT808Config, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger<JT808TcpEncoder>(); | |||||
this.JT808Serializer = jT808Config.GetSerializer(); | |||||
} | |||||
protected override void Encode(IChannelHandlerContext context, IJT808Reply message, IByteBuffer output) | |||||
{ | |||||
if (message.Package != null) | |||||
{ | |||||
try | |||||
{ | |||||
var sendData = JT808Serializer.Serialize(message.Package, minBufferSize: message.MinBufferSize); | |||||
output.WriteBytes(Unpooled.WrappedBuffer(sendData)); | |||||
} | |||||
catch (JT808.Protocol.Exceptions.JT808Exception ex) | |||||
{ | |||||
logger.LogError(ex, context.Channel.Id.AsShortText()); | |||||
} | |||||
catch (System.Exception ex) | |||||
{ | |||||
logger.LogError(ex, context.Channel.Id.AsShortText()); | |||||
} | |||||
} | |||||
else if (message.HexData != null) | |||||
{ | |||||
output.WriteBytes(Unpooled.WrappedBuffer(message.HexData)); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,33 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs; | |||||
using DotNetty.Transport.Channels; | |||||
using System.Collections.Generic; | |||||
using DotNetty.Transport.Channels.Sockets; | |||||
using JT808.DotNetty.Core.Metadata; | |||||
namespace JT808.DotNetty.Core.Codecs | |||||
{ | |||||
public class JT808UdpDecoder : MessageToMessageDecoder<DatagramPacket> | |||||
{ | |||||
protected override void Decode(IChannelHandlerContext context, DatagramPacket message, List<object> output) | |||||
{ | |||||
if (!message.Content.IsReadable()) return; | |||||
IByteBuffer byteBuffer = message.Content; | |||||
//过滤掉非808标准包 | |||||
//不包括头尾标识 | |||||
//(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1 | |||||
if (byteBuffer.ReadableBytes < 12) | |||||
{ | |||||
byte[] buffer = new byte[byteBuffer.ReadableBytes]; | |||||
byteBuffer.ReadBytes(buffer, 0, byteBuffer.ReadableBytes); | |||||
return; | |||||
} | |||||
else | |||||
{ | |||||
byte[] buffer = new byte[byteBuffer.ReadableBytes]; | |||||
byteBuffer.ReadBytes(buffer); | |||||
output.Add(new JT808UdpPackage(buffer, message.Sender)); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,52 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Core.Configurations | |||||
{ | |||||
public class JT808Configuration | |||||
{ | |||||
public int TcpPort { get; set; } = 808; | |||||
public int UdpPort { get; set; } = 808; | |||||
public int QuietPeriodSeconds { get; set; } = 1; | |||||
public TimeSpan QuietPeriodTimeSpan => TimeSpan.FromSeconds(QuietPeriodSeconds); | |||||
public int ShutdownTimeoutSeconds { get; set; } = 3; | |||||
public TimeSpan ShutdownTimeoutTimeSpan => TimeSpan.FromSeconds(ShutdownTimeoutSeconds); | |||||
public int SoBacklog { get; set; } = 8192; | |||||
public int EventLoopCount { get; set; } = Environment.ProcessorCount; | |||||
public int ReaderIdleTimeSeconds { get; set; } = 3600; | |||||
public int WriterIdleTimeSeconds { get; set; } = 3600; | |||||
public int AllIdleTimeSeconds { get; set; } = 3600; | |||||
/// <summary> | |||||
/// WebApi服务 | |||||
/// 默认828端口 | |||||
/// </summary> | |||||
public int WebApiPort { get; set; } = 828; | |||||
/// <summary> | |||||
/// WebApi 默认token 123456 | |||||
/// </summary> | |||||
public string WebApiToken { get; set; } = "123456"; | |||||
/// <summary> | |||||
/// 转发远程地址 (可选项)知道转发的地址有利于提升性能 | |||||
/// 按照808的消息,有些请求必须要应答,但是转发可以不需要有应答可以节省部分资源包括: | |||||
// 1.消息的序列化 | |||||
// 2.消息的下发 | |||||
// 都有一定的性能损耗,那么不需要判断写超时 IdleState.WriterIdle | |||||
// 就跟神兽貔貅一样。。。 | |||||
/// </summary> | |||||
public List<string> ForwardingRemoteIPAddress { get; set; } | |||||
} | |||||
} |
@@ -1,35 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Text.Json; | |||||
using System.Text.Json.Serialization; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Core.JsonConvert | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// ref:https://github.com/dotnet/corefx/blob/release/3.0/src/System.Text.Json/tests/Serialization/CustomConverterTests.Array.cs | |||||
/// </summary> | |||||
public class ByteArrayHexTextJsonConverter : JsonConverter<byte[]> | |||||
{ | |||||
public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |||||
{ | |||||
//string hexJson = reader.get(); | |||||
var hexJson = reader.GetString(); | |||||
var list = new List<byte>(); | |||||
foreach (string str in hexJson.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries)) | |||||
{ | |||||
list.Add(Convert.ToByte(str, 16)); | |||||
} | |||||
return list.ToArray(); | |||||
} | |||||
public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options) | |||||
{ | |||||
var hexString = string.Join(" ", (value).Select(p => p.ToString("X2"))); | |||||
writer.WriteStringValue(hexString); | |||||
} | |||||
} | |||||
} |
@@ -1,29 +0,0 @@ | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Core.Converters | |||||
{ | |||||
class ByteArrayHexConverter : JsonConverter | |||||
{ | |||||
public override bool CanConvert(Type objectType) => objectType == typeof(byte[]); | |||||
public override bool CanRead => false; | |||||
public override bool CanWrite => true; | |||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException(); | |||||
private readonly string _separator; | |||||
public ByteArrayHexConverter(string separator = " ") => _separator = separator; | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
{ | |||||
var hexString = string.Join(_separator, ((byte[])value).Select(p => p.ToString("X2"))); | |||||
writer.WriteValue(hexString); | |||||
} | |||||
} | |||||
} |
@@ -1,26 +0,0 @@ | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Net; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Core.Converters | |||||
{ | |||||
public class JsonIPAddressConverter : JsonConverter | |||||
{ | |||||
public override bool CanConvert(Type objectType) | |||||
{ | |||||
return (objectType == typeof(IPAddress)); | |||||
} | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
{ | |||||
writer.WriteValue(value.ToString()); | |||||
} | |||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |||||
{ | |||||
return IPAddress.Parse((string)reader.Value); | |||||
} | |||||
} | |||||
} |
@@ -1,32 +0,0 @@ | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json.Linq; | |||||
using System; | |||||
using System.Net; | |||||
namespace JT808.DotNetty.Core.Converters | |||||
{ | |||||
public class JsonIPEndPointConverter: JsonConverter | |||||
{ | |||||
public override bool CanConvert(Type objectType) | |||||
{ | |||||
return (objectType == typeof(IPEndPoint)); | |||||
} | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
{ | |||||
IPEndPoint ep = (IPEndPoint)value; | |||||
JObject jo = new JObject(); | |||||
jo.Add("Host", JToken.FromObject(ep.Address, serializer)); | |||||
jo.Add("Port", ep.Port); | |||||
jo.WriteTo(writer); | |||||
} | |||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |||||
{ | |||||
JObject jo = JObject.Load(reader); | |||||
IPAddress address = jo["Host"].ToObject<IPAddress>(serializer); | |||||
int port = (int)jo["Port"]; | |||||
return new IPEndPoint(address, port); | |||||
} | |||||
} | |||||
} |
@@ -1,102 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Text.Json; | |||||
using JT808.DotNetty.Abstractions.Dtos; | |||||
using JT808.DotNetty.Core.Metadata; | |||||
namespace JT808.DotNetty.Core.Handlers | |||||
{ | |||||
/// <summary> | |||||
/// 基于webapi http模式抽象消息处理业务 | |||||
/// 自定义消息处理业务 | |||||
/// 注意: | |||||
/// 1.ConfigureServices: | |||||
/// services.Replace(new ServiceDescriptor(typeof(JT808MsgIdHttpHandlerBase),typeof(JT808MsgIdCustomHttpHandlerImpl),ServiceLifetime.Singleton)); | |||||
/// 2.解析具体的消息体,具体消息调用具体的JT808Serializer.Deserialize<T> | |||||
/// </summary> | |||||
public abstract class JT808MsgIdHttpHandlerBase | |||||
{ | |||||
/// <summary> | |||||
/// 初始化消息处理业务 | |||||
/// </summary> | |||||
protected JT808MsgIdHttpHandlerBase() | |||||
{ | |||||
HandlerDict = new Dictionary<string, Func<JT808HttpRequest, JT808HttpResponse>>(); | |||||
} | |||||
protected void CreateRoute(string url, Func<JT808HttpRequest, JT808HttpResponse> func) | |||||
{ | |||||
if (!HandlerDict.ContainsKey(url)) | |||||
{ | |||||
HandlerDict.Add(url, func); | |||||
} | |||||
else | |||||
{ | |||||
// 替换 | |||||
HandlerDict[url] = func; | |||||
} | |||||
} | |||||
public Dictionary<string, Func<JT808HttpRequest, JT808HttpResponse>> HandlerDict { get; } | |||||
protected JT808HttpResponse CreateJT808HttpResponse(dynamic dynamicObject) | |||||
{ | |||||
byte[] data = JsonSerializer.SerializeToUtf8Bytes(dynamicObject); | |||||
return new JT808HttpResponse() | |||||
{ | |||||
Data = data | |||||
}; | |||||
} | |||||
public JT808HttpResponse DefaultHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808DefaultResultDto()); | |||||
return new JT808HttpResponse(json); | |||||
} | |||||
public JT808HttpResponse EmptyHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.Empty, | |||||
Message = "内容为空", | |||||
Data = "Content Empty" | |||||
}); | |||||
return new JT808HttpResponse(json); | |||||
} | |||||
public JT808HttpResponse NotFoundHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.NotFound, | |||||
Message = "没有该服务", | |||||
Data = "没有该服务" | |||||
}); | |||||
return new JT808HttpResponse(json); | |||||
} | |||||
public JT808HttpResponse AuthFailHttpResponse() | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.AuthFail, | |||||
Message = "token认证失败", | |||||
Data = "token认证失败" | |||||
}); | |||||
return new JT808HttpResponse(json); | |||||
} | |||||
public JT808HttpResponse ErrorHttpResponse(Exception ex) | |||||
{ | |||||
byte[] json = JsonSerializer.SerializeToUtf8Bytes(new JT808ResultDto<string>() | |||||
{ | |||||
Code = JT808ResultCode.Error, | |||||
Message = ex.StackTrace, | |||||
Data = ex.Message | |||||
}); | |||||
return new JT808HttpResponse(json); | |||||
} | |||||
} | |||||
} |
@@ -1,21 +0,0 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Transport.Channels.Sockets; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Abstractions.Enums; | |||||
using JT808.DotNetty.Core.Interfaces; | |||||
using JT808.DotNetty.Core.Services; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Net; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Core.Impls | |||||
{ | |||||
class JT808DatagramPacketImpl : IJT808DatagramPacket | |||||
{ | |||||
public DatagramPacket Create(byte[] message, EndPoint recipient) | |||||
{ | |||||
return new DatagramPacket(Unpooled.WrappedBuffer(message), recipient); | |||||
} | |||||
} | |||||
} |