@@ -22,12 +22,18 @@ | |||
[基于Tcp转发地址过滤服务](#tcp_transmit) | |||
## 4.消息包计数服务 | |||
## 4.消息包计数服务(次日清零) | |||
[基于Tcp消息包计数服务](#tcp_counter) | |||
[基于Udp消息包计数服务](#udp_counter) | |||
## 5.流量统计服务(次日清零) | |||
[基于Tcp流量统计服务](#tcp_traffic) | |||
[基于Udp流量统计服务](#udp_traffic) | |||
### 统一对象返回 JT808ResultDto\<T> | |||
|属性|数据类型|参数说明| | |||
@@ -385,3 +391,55 @@ | |||
} | |||
} | |||
``` | |||
### <span id="tcp_traffic">基于Tcp流量统计服务</span> | |||
请求地址:Tcp/Traffic/Get | |||
请求方式:GET | |||
返回数据: | |||
|属性|数据类型|参数说明| | |||
|------|:------:|:------| | |||
| TotalReceiveSize| double| 总接收大小(单位KB)| | |||
| TotalSendSize| double| 总发送大小(单位KB)| | |||
返回结果: | |||
``` traffic1 | |||
{ | |||
"Message":"", | |||
"Code":200, | |||
"Data":{ | |||
"TotalReceiveSize":0.0478515625, | |||
"TotalSendSize":0.01953125 | |||
} | |||
} | |||
``` | |||
### <span id="udp_traffic">基于Udp流量统计服务</span> | |||
请求地址:Udp/Traffic/Get | |||
请求方式:GET | |||
返回数据: | |||
|属性|数据类型|参数说明| | |||
|------|:------:|:------| | |||
| TotalReceiveSize| double| 总接收大小(单位KB)| | |||
| TotalSendSize| double| 总发送大小(单位KB)| | |||
返回结果: | |||
``` traffic2 | |||
{ | |||
"Message":"", | |||
"Code":200, | |||
"Data":{ | |||
"TotalReceiveSize":0.0478515625, | |||
"TotalSendSize":0.01953125 | |||
} | |||
} | |||
``` |
@@ -0,0 +1,20 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT808.DotNetty.Abstractions.Dtos | |||
{ | |||
public class JT808TrafficInfoDto | |||
{ | |||
/// <summary> | |||
/// 总接收大小 | |||
/// 单位KB | |||
/// </summary> | |||
public double TotalReceiveSize { get; set; } | |||
/// <summary> | |||
/// 总发送大小 | |||
/// 单位KB | |||
/// </summary> | |||
public double TotalSendSize { get; set; } | |||
} | |||
} |
@@ -14,24 +14,26 @@ | |||
public const string TransmitPrefix = "Transmit"; | |||
public const string TrafficPrefix = "Traffic"; | |||
public const string TcpPrefix = "Tcp"; | |||
public const string UdpPrefix = "Udp"; | |||
/// <summary> | |||
/// 添加转发过滤地址 | |||
///基于Tcp的添加转发过滤地址 | |||
/// </summary> | |||
public static string TransmitAdd = $"{RouteTablePrefix}/{TcpPrefix}/{TransmitPrefix}/Add"; | |||
/// <summary> | |||
/// 删除转发过滤地址(不能删除在网关服务器配置文件配的地址) | |||
/// 基于Tcp的删除转发过滤地址(不能删除在网关服务器配置文件配的地址) | |||
/// </summary> | |||
public static string TransmitRemove = $"{RouteTablePrefix}/{TcpPrefix}/{TransmitPrefix}/Remove"; | |||
/// <summary> | |||
/// 获取转发过滤地址信息集合 | |||
///基于Tcp的获取转发过滤地址信息集合 | |||
/// </summary> | |||
public static string TransmitGetAll = $"{RouteTablePrefix}/{TcpPrefix}/{TransmitPrefix}/GetAll"; | |||
/// <summary> | |||
/// 获取Tcp包计数器 | |||
/// 基于Tcp的包计数器 | |||
/// </summary> | |||
public static string GetTcpAtomicCounter = $"{RouteTablePrefix}/{TcpPrefix}/GetAtomicCounter"; | |||
/// <summary> | |||
@@ -46,6 +48,11 @@ | |||
/// 基于Tcp的统一下发信息 | |||
/// </summary> | |||
public static string UnificationTcpSend = $"{RouteTablePrefix}/{TcpPrefix}/UnificationSend"; | |||
/// <summary> | |||
/// 基于Tcp的流量服务获取 | |||
/// </summary> | |||
public static string TrafficTcpGet = $"{RouteTablePrefix}/{TcpPrefix}/{TrafficPrefix}/Get"; | |||
/// <summary> | |||
/// 获取Udp包计数器 | |||
/// </summary> | |||
@@ -62,7 +69,10 @@ | |||
/// 基于Udp的会话服务-通过设备终端号移除对应会话 | |||
/// </summary> | |||
public static string SessionUdpRemoveByTerminalPhoneNo = $"{RouteTablePrefix}/{UdpPrefix}/{SessionPrefix}/RemoveByTerminalPhoneNo"; | |||
/// <summary> | |||
/// 基于Udp的流量服务获取 | |||
/// </summary | |||
public static string TrafficUdpGet = $"{RouteTablePrefix}/{UdpPrefix}/{TrafficPrefix}/Get"; | |||
} | |||
} | |||
} |
@@ -22,7 +22,7 @@ namespace JT808.DotNetty.Core | |||
{ | |||
DateTime current = DateTime.Now; | |||
#if DEBUG | |||
DateTime tmp = current.AddSeconds(10); | |||
DateTime tmp = current.AddMinutes(1); | |||
#else | |||
DateTime tmp = current.Date.AddDays(1).AddMilliseconds(-1); | |||
#endif | |||
@@ -21,6 +21,16 @@ namespace JT808.DotNetty.Core.Services | |||
sendCounter.Add(size); | |||
} | |||
public long TotalReceiveSize | |||
{ | |||
get { return receiveCounter.Count; } | |||
} | |||
public long TotalSendSize | |||
{ | |||
get { return sendCounter.Count; } | |||
} | |||
public void ResetSize() | |||
{ | |||
receiveCounter.Reset(); | |||
@@ -16,6 +16,16 @@ namespace JT808.DotNetty.Core.Services | |||
receiveCounter.Add(size); | |||
} | |||
public long TotalReceiveSize | |||
{ | |||
get { return receiveCounter.Count; } | |||
} | |||
public long TotalSendSize | |||
{ | |||
get { return sendCounter.Count; } | |||
} | |||
public void SendSize(long size) | |||
{ | |||
sendCounter.Add(size); | |||
@@ -4,6 +4,7 @@ using JT808.DotNetty.Core; | |||
using JT808.DotNetty.Core.Interfaces; | |||
using JT808.DotNetty.Core.Services; | |||
using System; | |||
using System.Linq; | |||
namespace JT808.DotNetty.Internal | |||
{ | |||
@@ -29,10 +30,20 @@ namespace JT808.DotNetty.Internal | |||
var session = jT808SessionManager.GetSession(terminalPhoneNo); | |||
if (session != null) | |||
{ | |||
jT808TcpTrafficService.SendSize(data.Length); | |||
session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); | |||
resultDto.Code = JT808ResultCode.Ok; | |||
resultDto.Data = true; | |||
//判断转发数据是下发不了消息的 | |||
if (jT808SessionManager.GetAll().Count(c => c.Channel.Id == session.Channel.Id) > 1) | |||
{ | |||
resultDto.Code = JT808ResultCode.Ok; | |||
resultDto.Data = false; | |||
resultDto.Message = "not support transmit data send."; | |||
} | |||
else | |||
{ | |||
jT808TcpTrafficService.SendSize(data.Length); | |||
session.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(data)); | |||
resultDto.Code = JT808ResultCode.Ok; | |||
resultDto.Data = true; | |||
} | |||
} | |||
else | |||
{ | |||
@@ -73,15 +73,15 @@ namespace JT808.DotNetty.Core | |||
//使用场景: | |||
//部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, | |||
//这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 | |||
//todo: 有设备关联上来可以进行通知 例如:使用Redis发布订阅 | |||
//有设备关联上来可以进行通知 例如:使用Redis发布订阅 | |||
jT808SessionPublishing.PublishAsync(JT808Constants.SessionOnline, appSession.TerminalPhoneNo); | |||
} | |||
} | |||
public JT808TcpSession RemoveSession(string terminalPhoneNo) | |||
{ | |||
//todo: 设备离线可以进行通知 | |||
//todo: 使用Redis 发布订阅 | |||
//设备离线可以进行通知 | |||
//使用Redis 发布订阅 | |||
if (string.IsNullOrEmpty(terminalPhoneNo)) return default; | |||
if (!SessionIdDict.TryGetValue(terminalPhoneNo, out JT808TcpSession jT808Session)) | |||
{ | |||
@@ -120,8 +120,8 @@ namespace JT808.DotNetty.Core | |||
public void RemoveSessionByChannel(IChannel channel) | |||
{ | |||
//todo: 设备离线可以进行通知 | |||
//todo: 使用Redis 发布订阅 | |||
//设备离线可以进行通知 | |||
//使用Redis 发布订阅 | |||
var terminalPhoneNos = SessionIdDict.Where(w => w.Value.Channel.Id == channel.Id).Select(s => s.Key).ToList(); | |||
if (terminalPhoneNos.Count > 0) | |||
{ | |||
@@ -11,7 +11,7 @@ namespace JT808.DotNetty.Core | |||
{ | |||
/// <summary> | |||
/// JT808 udp会话管理 | |||
/// todo:估计要轮询下 | |||
/// 估计要轮询下 | |||
/// </summary> | |||
public class JT808UdpSessionManager | |||
{ | |||
@@ -81,7 +81,7 @@ namespace JT808.DotNetty.Core | |||
//使用场景: | |||
//部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, | |||
//这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 | |||
//todo: 有设备关联上来可以进行通知 例如:使用Redis发布订阅 | |||
//有设备关联上来可以进行通知 例如:使用Redis发布订阅 | |||
jT808SessionPublishing.PublishAsync(JT808Constants.SessionOnline, appSession.TerminalPhoneNo); | |||
} | |||
} | |||
@@ -99,8 +99,8 @@ namespace JT808.DotNetty.Core | |||
public JT808UdpSession RemoveSession(string terminalPhoneNo) | |||
{ | |||
//todo: 设备离线可以进行通知 | |||
//todo: 使用Redis 发布订阅 | |||
//设备离线可以进行通知 | |||
//使用Redis 发布订阅 | |||
if (string.IsNullOrEmpty(terminalPhoneNo)) return default; | |||
if (!SessionIdDict.TryGetValue(terminalPhoneNo, out JT808UdpSession jT808Session)) | |||
{ | |||
@@ -120,8 +120,8 @@ namespace JT808.DotNetty.Core | |||
public void RemoveSessionByChannel(IChannel channel) | |||
{ | |||
//todo: 设备离线可以进行通知 | |||
//todo: 使用Redis 发布订阅 | |||
//设备离线可以进行通知 | |||
//使用Redis 发布订阅 | |||
var terminalPhoneNos = SessionIdDict.Where(w => w.Value.Channel.Id == channel.Id).Select(s => s.Key).ToList(); | |||
if (terminalPhoneNos.Count > 0) | |||
{ | |||
@@ -21,6 +21,7 @@ namespace JT808.DotNetty.Hosting | |||
{ | |||
static async Task Main(string[] args) | |||
{ | |||
//7E020000220138123456780085000000010000000101EA2A3F08717931000C015400201901032000020104000000E6F87E | |||
var serverHostBuilder = new HostBuilder() | |||
.ConfigureAppConfiguration((hostingContext, config) => | |||
{ | |||
@@ -27,17 +27,23 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
private readonly IJT808UnificationUdpSendService jT808UnificationUdpSendService; | |||
private readonly JT808TcpTrafficService jT808TcpTrafficService; | |||
private readonly JT808UdpTrafficService jT808UdpTrafficService; | |||
/// <summary> | |||
/// TCP一套注入 | |||
/// </summary> | |||
/// <param name="jT808TcpAtomicCounterService"></param> | |||
public JT808MsgIdDefaultWebApiHandler( | |||
JT808TcpTrafficService jT808TcpTrafficService, | |||
IJT808UnificationTcpSendService jT808UnificationTcpSendService, | |||
IJT808TcpSessionService jT808TcpSessionService, | |||
JT808TransmitAddressFilterService jT808TransmitAddressFilterService, | |||
JT808TcpAtomicCounterService jT808TcpAtomicCounterService | |||
) | |||
{ | |||
this.jT808TcpTrafficService = jT808TcpTrafficService; | |||
this.jT808UnificationTcpSendService = jT808UnificationTcpSendService; | |||
this.jT808TcpSessionService = jT808TcpSessionService; | |||
this.jT808TransmitAddressFilterService = jT808TransmitAddressFilterService; | |||
@@ -50,11 +56,13 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
/// </summary> | |||
/// <param name="jT808UdpAtomicCounterService"></param> | |||
public JT808MsgIdDefaultWebApiHandler( | |||
JT808UdpTrafficService jT808UdpTrafficService, | |||
IJT808UdpSessionService jT808UdpSessionService, | |||
IJT808UnificationUdpSendService jT808UnificationUdpSendService, | |||
JT808UdpAtomicCounterService jT808UdpAtomicCounterService | |||
) | |||
{ | |||
this.jT808UdpTrafficService = jT808UdpTrafficService; | |||
this.jT808UdpSessionService = jT808UdpSessionService; | |||
this.jT808UnificationUdpSendService = jT808UnificationUdpSendService; | |||
this.jT808UdpAtomicCounterService = jT808UdpAtomicCounterService; | |||
@@ -67,6 +75,8 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
/// <param name="jT808TcpAtomicCounterService"></param> | |||
/// <param name="jT808UdpAtomicCounterService"></param> | |||
public JT808MsgIdDefaultWebApiHandler( | |||
JT808TcpTrafficService jT808TcpTrafficService, | |||
JT808UdpTrafficService jT808UdpTrafficService, | |||
IJT808UnificationTcpSendService jT808UnificationTcpSendService, | |||
IJT808UnificationUdpSendService jT808UnificationUdpSendService, | |||
IJT808TcpSessionService jT808TcpSessionService, | |||
@@ -76,6 +86,8 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
JT808UdpAtomicCounterService jT808UdpAtomicCounterService | |||
) | |||
{ | |||
this.jT808TcpTrafficService = jT808TcpTrafficService; | |||
this.jT808UdpTrafficService = jT808UdpTrafficService; | |||
this.jT808UdpSessionService = jT808UdpSessionService; | |||
this.jT808UnificationTcpSendService = jT808UnificationTcpSendService; | |||
this.jT808UnificationUdpSendService = jT808UnificationUdpSendService; | |||
@@ -245,6 +257,32 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
return CreateJT808HttpResponse(result); | |||
} | |||
/// <summary> | |||
/// 基于Tcp的流量获取 | |||
/// </summary> | |||
/// <param name="request"></param> | |||
/// <returns></returns> | |||
public JT808HttpResponse TrafficTcpGet(JT808HttpRequest request) | |||
{ | |||
JT808TrafficInfoDto jT808TrafficInfoDto = new JT808TrafficInfoDto(); | |||
jT808TrafficInfoDto.TotalReceiveSize = (jT808TcpTrafficService.TotalReceiveSize * 1.0) / 1024; | |||
jT808TrafficInfoDto.TotalSendSize = (jT808TcpTrafficService.TotalSendSize * 1.0) / 1024; | |||
return CreateJT808HttpResponse(jT808TrafficInfoDto); | |||
} | |||
/// <summary> | |||
/// 基于Udp的流量获取 | |||
/// </summary> | |||
/// <param name="request"></param> | |||
/// <returns></returns> | |||
public JT808HttpResponse TrafficUdpGet(JT808HttpRequest request) | |||
{ | |||
JT808TrafficInfoDto jT808TrafficInfoDto = new JT808TrafficInfoDto(); | |||
jT808TrafficInfoDto.TotalReceiveSize = (jT808UdpTrafficService.TotalReceiveSize * 1.0) / 1024; | |||
jT808TrafficInfoDto.TotalSendSize = (jT808UdpTrafficService.TotalSendSize * 1.0) / 1024; | |||
return CreateJT808HttpResponse(jT808TrafficInfoDto); | |||
} | |||
protected virtual void InitTcpRoute() | |||
{ | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.TransmitAdd, AddTransmitAddress); | |||
@@ -254,6 +292,7 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionTcpGetAll, GetTcpSessionAll); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionTcpRemoveByTerminalPhoneNo, RemoveTcpSessionByTerminalPhoneNo); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.UnificationTcpSend, UnificationTcpSend); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.TrafficTcpGet, TrafficTcpGet); | |||
} | |||
protected virtual void InitUdpRoute() | |||
@@ -262,6 +301,7 @@ namespace JT808.DotNetty.WebApi.Handlers | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.UnificationUdpSend, UnificationUdpSend); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionUdpGetAll, GetUdpSessionAll); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.SessionUdpRemoveByTerminalPhoneNo, RemoveUdpSessionByTerminalPhoneNo); | |||
CreateRoute(JT808Constants.JT808WebApiRouteTable.TrafficUdpGet, TrafficUdpGet); | |||
} | |||
} | |||
} |