@@ -35,14 +35,13 @@ | |||||
|接口名称|接口说明|使用场景| | |接口名称|接口说明|使用场景| | ||||
|:------:|:------|:------| | |:------:|:------|:------| | ||||
| IJT808SessionPublishing| 会话通知(在线/离线)| 有些超长待机的设备,不会实时保持连接,那么通过平台下发的命令是无法到达的,这时候就需要设备一上线,就即时通知服务去处理,然后在即时的下发消息到设备。| | |||||
| IJT808SessionProducer| 会话通知(在线/离线)数据生产接口| 有些超长待机的设备,不会实时保持连接,那么通过平台下发的命令是无法到达的,这时候就需要设备一上线,就即时通知服务去处理,然后在即时的下发消息到设备。| | |||||
| IJT808SessionConsumer| 会话通知(在线/离线)数据消费接口| -| | |||||
| IJT808MsgProducer| 数据生产接口| 网关将接收到的数据发送到队列| | | IJT808MsgProducer| 数据生产接口| 网关将接收到的数据发送到队列| | ||||
| IJT808MsgConsumer| 数据消费接口| 将数据进行对应的消息业务处理(例:设备流量统计、第三方平台数据转发、消息日志等) | | | IJT808MsgConsumer| 数据消费接口| 将数据进行对应的消息业务处理(例:设备流量统计、第三方平台数据转发、消息日志等) | | ||||
| IJT808MsgReplyProducer| 应答数据生产接口|将生产的数据解析为对应的消息Id应答发送到队列 | | | IJT808MsgReplyProducer| 应答数据生产接口|将生产的数据解析为对应的消息Id应答发送到队列 | | ||||
| IJT808MsgReplyConsumer| 应答数据消费接口| 将接收到的应答数据下发给设备| | | IJT808MsgReplyConsumer| 应答数据消费接口| 将接收到的应答数据下发给设备| | ||||
> 只要实现IJT808SessionPublishing接口的任意一款MQ都能实现该功能。 | |||||
> 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 | > 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 | ||||
## NuGet安装 | ## NuGet安装 | ||||
@@ -81,21 +80,26 @@ static async Task Main(string[] args) | |||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | ||||
services.AddJT808Configure() | services.AddJT808Configure() | ||||
.AddJT808NettyCore(hostContext.Configuration) | .AddJT808NettyCore(hostContext.Configuration) | ||||
//自定义会话通知(在线/离线)使用异步方式 | |||||
//.ReplaceSessionPublishing<CustomJT808SessionPublishing>() | |||||
.AddJT808TcpNettyHost() | .AddJT808TcpNettyHost() | ||||
.AddJT808UdpNettyHost() | .AddJT808UdpNettyHost() | ||||
.AddJT808WebApiNettyHost() | .AddJT808WebApiNettyHost() | ||||
//扩展webapi JT808MsgIdHttpHandlerBase | |||||
//.ReplaceMsgIdHandler<JT808MsgIdHttpCustomHandler>() | |||||
.Builder(); | .Builder(); | ||||
//webapi客户端调用 | |||||
services.AddHttpApi<IJT808DotNettyWebApi>().ConfigureHttpApiConfig((c, p) => | |||||
{ | |||||
c.HttpHost = new Uri("http://localhost:828/jt808api/"); | |||||
c.FormatOptions.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; | |||||
c.LoggerFactory = p.GetRequiredService<ILoggerFactory>(); | |||||
}); | |||||
var client = services.BuildServiceProvider().GetRequiredService<IJT808DotNettyWebApi>(); | |||||
var result = client.GetTcpAtomicCounter().InvokeAsync().Result; | |||||
//添加kafka插件 | |||||
//.AddJT808ServerKafkaMsgProducer(hostContext.Configuration) | |||||
//.AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) | |||||
//.AddJT808ServerKafkaSessionProducer(hostContext.Configuration) | |||||
//.Builder(); | |||||
//webapi客户端调用 | |||||
//services.AddHttpApi<IJT808DotNettyWebApi>().ConfigureHttpApiConfig((c, p) => | |||||
//{ | |||||
// c.HttpHost = new Uri("http://localhost:828/jt808api/"); | |||||
// c.FormatOptions.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; | |||||
// c.LoggerFactory = p.GetRequiredService<ILoggerFactory>(); | |||||
//}); | |||||
//var client = services.BuildServiceProvider().GetRequiredService<IJT808DotNettyWebApi>(); | |||||
//var result = client.GetTcpAtomicCounter().InvokeAsync().Result; | |||||
}); | }); | ||||
await serverHostBuilder.RunConsoleAsync(); | await serverHostBuilder.RunConsoleAsync(); | ||||
@@ -5,13 +5,11 @@ using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
namespace JT808.DotNetty.Core.Interfaces | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | { | ||||
public interface IJT808NettyBuilder | public interface IJT808NettyBuilder | ||||
{ | { | ||||
IJT808Builder JT808Builder { get; } | IJT808Builder JT808Builder { get; } | ||||
IJT808NettyBuilder ReplaceSessionPublishing<T>() where T : IJT808SessionPublishing; | |||||
IJT808NettyBuilder ReplaceMsgProducer<T>() where T : IJT808MsgProducer; | |||||
IJT808Builder Builder(); | IJT808Builder Builder(); | ||||
} | } | ||||
} | } |
@@ -0,0 +1,18 @@ | |||||
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(); | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
/// <summary> | |||||
/// 会话通知(在线/离线) | |||||
/// </summary> | |||||
public interface IJT808SessionProducer : IJT808PubSub, IDisposable | |||||
{ | |||||
Task ProduceAsync(string notice,string terminalNo); | |||||
} | |||||
} |
@@ -1,12 +0,0 @@ | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Abstractions | |||||
{ | |||||
/// <summary> | |||||
/// 会话通知(在线/离线) | |||||
/// </summary> | |||||
public interface IJT808SessionPublishing | |||||
{ | |||||
Task PublishAsync(string topicName, string value); | |||||
} | |||||
} |
@@ -6,5 +6,7 @@ | |||||
<Description>基于DotNetty实现的JT808DotNetty的抽象库</Description> | <Description>基于DotNetty实现的JT808DotNetty的抽象库</Description> | ||||
<PackageReleaseNotes>基于DotNetty实现的JT808DotNetty的抽象库</PackageReleaseNotes> | <PackageReleaseNotes>基于DotNetty实现的JT808DotNetty的抽象库</PackageReleaseNotes> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<PackageReference Include="JT808" Version="2.1.3" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -5,7 +5,7 @@ | |||||
public const string SessionOnline= "JT808SessionOnline"; | public const string SessionOnline= "JT808SessionOnline"; | ||||
public const string SessionOffline = "JT808SessionOffline"; | public const string SessionOffline = "JT808SessionOffline"; | ||||
public const string SessionTopic = "jt808session"; | |||||
public const string MsgTopic = "jt808msgdefault"; | public const string MsgTopic = "jt808msgdefault"; | ||||
public const string MsgReplyTopic = "jt808msgreplydefault"; | public const string MsgReplyTopic = "jt808msgreplydefault"; | ||||
@@ -23,22 +23,10 @@ namespace JT808.DotNetty.Core.Impls | |||||
return JT808Builder; | return JT808Builder; | ||||
} | } | ||||
public IJT808NettyBuilder ReplaceSessionPublishing<T>() where T : IJT808SessionPublishing | |||||
{ | |||||
JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808SessionPublishing), typeof(T), ServiceLifetime.Singleton)); | |||||
return this; | |||||
} | |||||
public IJT808NettyBuilder ReplaceMsgProducer<T>() where T : IJT808MsgProducer | |||||
{ | |||||
JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgProducer), typeof(T), ServiceLifetime.Singleton)); | |||||
return this; | |||||
} | |||||
public IJT808NettyBuilder ReplaceMsgReplyConsumer<T>() where T : IJT808MsgReplyConsumer | |||||
{ | |||||
JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(T), ServiceLifetime.Singleton)); | |||||
return this; | |||||
} | |||||
//public IJT808NettyBuilder ReplaceSessionPublishing<T>() where T : IJT808SessionPublishing | |||||
//{ | |||||
// JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808SessionPublishing), typeof(T), ServiceLifetime.Singleton)); | |||||
// return this; | |||||
//} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,31 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Logging; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Core | |||||
{ | |||||
internal class JT808SessionProducerDefaultImpl : IJT808SessionProducer | |||||
{ | |||||
private readonly ILogger<JT808SessionProducerDefaultImpl> logger; | |||||
public JT808SessionProducerDefaultImpl(ILoggerFactory loggerFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger<JT808SessionProducerDefaultImpl>(); | |||||
} | |||||
public string TopicName => JT808NettyConstants.SessionTopic; | |||||
public void Dispose() | |||||
{ | |||||
} | |||||
public Task ProduceAsync(string terminalNo, string notice) | |||||
{ | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"{terminalNo}-{notice}"); | |||||
} | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,23 +0,0 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Logging; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Core | |||||
{ | |||||
internal class JT808SessionPublishingEmptyImpl : IJT808SessionPublishing | |||||
{ | |||||
private readonly ILogger<JT808SessionPublishingEmptyImpl> logger; | |||||
public JT808SessionPublishingEmptyImpl(ILoggerFactory loggerFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger<JT808SessionPublishingEmptyImpl>(); | |||||
} | |||||
public Task PublishAsync(string topicName, string value) | |||||
{ | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"{topicName}-{value}"); | |||||
} | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -1,4 +1,5 @@ | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
@@ -11,7 +11,6 @@ | |||||
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | <PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | ||||
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" /> | <PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" /> | ||||
<PackageReference Include="DotNetty.Codecs" Version="0.6.0" /> | <PackageReference Include="DotNetty.Codecs" Version="0.6.0" /> | ||||
<PackageReference Include="JT808" Version="2.1.3" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | ||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> | <PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> | ||||
@@ -65,7 +65,7 @@ namespace JT808.DotNetty.Core | |||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionService, JT808SessionService>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionService, JT808SessionService>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyConsumer, JT808MsgReplyConsumerDefaultImpl>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyConsumer, JT808MsgReplyConsumerDefaultImpl>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionPublishing, JT808SessionPublishingEmptyImpl>(); | |||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionProducer, JT808SessionProducerDefaultImpl>(); | |||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808MsgService>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808MsgService>(); | ||||
nettyBuilder.JT808Builder.Services.AddHostedService<JT808MsgReplyHostedService>(); | nettyBuilder.JT808Builder.Services.AddHostedService<JT808MsgReplyHostedService>(); | ||||
return nettyBuilder; | return nettyBuilder; | ||||
@@ -93,7 +93,7 @@ namespace JT808.DotNetty.Core | |||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyConsumer, JT808MsgReplyConsumerDefaultImpl>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyConsumer, JT808MsgReplyConsumerDefaultImpl>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808MsgService>(); | nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808MsgService>(); | ||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionPublishing, JT808SessionPublishingEmptyImpl>(); | |||||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionProducer, JT808SessionProducerDefaultImpl>(); | |||||
nettyBuilder.JT808Builder.Services.AddHostedService<JT808MsgReplyHostedService>(); | nettyBuilder.JT808Builder.Services.AddHostedService<JT808MsgReplyHostedService>(); | ||||
return nettyBuilder; | return nettyBuilder; | ||||
} | } | ||||
@@ -18,27 +18,27 @@ namespace JT808.DotNetty.Core.Session | |||||
private readonly ILogger<JT808SessionManager> logger; | private readonly ILogger<JT808SessionManager> logger; | ||||
private readonly IJT808DatagramPacket jT808DatagramPacket; | private readonly IJT808DatagramPacket jT808DatagramPacket; | ||||
public IJT808SessionPublishing JT808SessionPublishing { get; } | |||||
public IJT808SessionProducer JT808SessionProducer { get; } | |||||
public ConcurrentDictionary<string, IJT808Session> Sessions { get; } | public ConcurrentDictionary<string, IJT808Session> Sessions { get; } | ||||
public JT808SessionManager( | public JT808SessionManager( | ||||
IJT808SessionPublishing jT808SessionPublishing, | |||||
IJT808SessionProducer jT808SessionProducer, | |||||
ILoggerFactory loggerFactory | ILoggerFactory loggerFactory | ||||
) | ) | ||||
{ | { | ||||
Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | ||||
JT808SessionPublishing = jT808SessionPublishing; | |||||
JT808SessionProducer = jT808SessionProducer; | |||||
logger = loggerFactory.CreateLogger<JT808SessionManager>(); | logger = loggerFactory.CreateLogger<JT808SessionManager>(); | ||||
} | } | ||||
public JT808SessionManager( | public JT808SessionManager( | ||||
IJT808SessionPublishing jT808SessionPublishing, | |||||
IJT808SessionProducer jT808SessionProducer, | |||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
IJT808DatagramPacket jT808DatagramPacket) | IJT808DatagramPacket jT808DatagramPacket) | ||||
{ | { | ||||
Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | ||||
JT808SessionPublishing = jT808SessionPublishing; | |||||
JT808SessionProducer = jT808SessionProducer; | |||||
logger = loggerFactory.CreateLogger<JT808SessionManager>(); | logger = loggerFactory.CreateLogger<JT808SessionManager>(); | ||||
this.jT808DatagramPacket = jT808DatagramPacket; | this.jT808DatagramPacket = jT808DatagramPacket; | ||||
} | } | ||||
@@ -200,7 +200,7 @@ namespace JT808.DotNetty.Core.Session | |||||
//部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, | //部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, | ||||
//这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 | //这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 | ||||
//有设备关联上来可以进行通知 例如:使用Redis发布订阅 | //有设备关联上来可以进行通知 例如:使用Redis发布订阅 | ||||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOnline, jT808TcpSession.TerminalPhoneNo); | |||||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,jT808TcpSession.TerminalPhoneNo); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -230,7 +230,7 @@ namespace JT808.DotNetty.Core.Session | |||||
//移动很多卡,存储的那个socket地址端口,有效期非常短 | //移动很多卡,存储的那个socket地址端口,有效期非常短 | ||||
//不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了 | //不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了 | ||||
//所以此处采用跟随设备消息下发指令 | //所以此处采用跟随设备消息下发指令 | ||||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOnline, terminalPhoneNo); | |||||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,terminalPhoneNo); | |||||
} | } | ||||
public IJT808Session RemoveSession(string terminalPhoneNo) | public IJT808Session RemoveSession(string terminalPhoneNo) | ||||
{ | { | ||||
@@ -254,7 +254,7 @@ namespace JT808.DotNetty.Core.Session | |||||
} | } | ||||
string nos = string.Join(",", terminalPhoneNos); | string nos = string.Join(",", terminalPhoneNos); | ||||
logger.LogInformation($">>>{terminalPhoneNo}-{nos} 1-n Session Remove."); | logger.LogInformation($">>>{terminalPhoneNo}-{nos} 1-n Session Remove."); | ||||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, nos); | |||||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); | |||||
return jT808Session; | return jT808Session; | ||||
} | } | ||||
else | else | ||||
@@ -262,7 +262,7 @@ namespace JT808.DotNetty.Core.Session | |||||
if (Sessions.TryRemove(terminalPhoneNo, out IJT808Session jT808SessionRemove)) | if (Sessions.TryRemove(terminalPhoneNo, out IJT808Session jT808SessionRemove)) | ||||
{ | { | ||||
logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); | logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); | ||||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, terminalPhoneNo); | |||||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, terminalPhoneNo); | |||||
return jT808SessionRemove; | return jT808SessionRemove; | ||||
} | } | ||||
else | else | ||||
@@ -284,7 +284,7 @@ namespace JT808.DotNetty.Core.Session | |||||
} | } | ||||
string nos = string.Join(",", terminalPhoneNos); | string nos = string.Join(",", terminalPhoneNos); | ||||
logger.LogInformation($">>>{nos} Channel Remove."); | logger.LogInformation($">>>{nos} Channel Remove."); | ||||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, nos); | |||||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); | |||||
} | } | ||||
} | } | ||||
public IEnumerable<IJT808Session> GetAll() | public IEnumerable<IJT808Session> GetAll() | ||||
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808MsgConsumerConfig : JT808ConsumerConfig, IOptions<JT808MsgConsumerConfig> | |||||
{ | |||||
JT808MsgConsumerConfig IOptions<JT808MsgConsumerConfig>.Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808MsgProducerConfig : JT808ProducerConfig, IOptions<JT808MsgProducerConfig> | |||||
{ | |||||
JT808MsgProducerConfig IOptions<JT808MsgProducerConfig>.Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808MsgReplyConsumerConfig : JT808ConsumerConfig, IOptions<JT808MsgReplyConsumerConfig> | |||||
{ | |||||
JT808MsgReplyConsumerConfig IOptions<JT808MsgReplyConsumerConfig>.Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808MsgReplyProducerConfig : JT808ProducerConfig, IOptions<JT808MsgReplyProducerConfig> | |||||
{ | |||||
JT808MsgReplyProducerConfig IOptions<JT808MsgReplyProducerConfig>.Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808SessionConsumerConfig : JT808ConsumerConfig, IOptions<JT808SessionConsumerConfig> | |||||
{ | |||||
JT808SessionConsumerConfig IOptions<JT808SessionConsumerConfig>.Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808SessionProducerConfig : JT808ProducerConfig, IOptions<JT808SessionProducerConfig> | |||||
{ | |||||
JT808SessionProducerConfig IOptions<JT808SessionProducerConfig>.Value => this; | |||||
} | |||||
} |
@@ -8,8 +8,11 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Confluent.Kafka" Version="1.1.0" /> | <PackageReference Include="Confluent.Kafka" Version="1.1.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Options" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Options" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj" /> | <ProjectReference Include="..\JT808.DotNetty.Abstractions\JT808.DotNetty.Abstractions.csproj" /> | ||||
@@ -0,0 +1,47 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public static class JT808ClientKafkaExtensions | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="serviceDescriptors"></param> | |||||
/// <param name="configuration">GetSection("JT808MsgConsumerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IServiceCollection AddJT808ClientKafkaMsgConsumer(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.Configure<JT808MsgConsumerConfig>(configuration.GetSection("JT808MsgConsumerConfig")); | |||||
serviceDescriptors.TryAddSingleton<IJT808MsgConsumer, JT808MsgConsumer>(); | |||||
return serviceDescriptors; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="serviceDescriptors"></param> | |||||
/// <param name="configuration">GetSection("JT808MsgReplyProducerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IServiceCollection AddJT808ClientKafkaMsgReplyProducer(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.Configure<JT808MsgReplyProducerConfig>(configuration.GetSection("JT808MsgReplyProducerConfig")); | |||||
serviceDescriptors.TryAddSingleton<IJT808MsgReplyProducer, JT808MsgReplyProducer>(); | |||||
return serviceDescriptors; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="serviceDescriptors"></param> | |||||
/// <param name="configuration">GetSection("JT808SessionConsumerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IServiceCollection AddJT808ClientKafkaSessionConsumer(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.Configure<JT808SessionConsumerConfig>(configuration.GetSection("JT808SessionConsumerConfig")); | |||||
serviceDescriptors.TryAddSingleton<IJT808SessionConsumer, JT808SessionConsumer>(); | |||||
return serviceDescriptors; | |||||
} | |||||
} | |||||
} |
@@ -21,7 +21,7 @@ namespace JT808.DotNetty.Kafka | |||||
public string TopicName { get; } | public string TopicName { get; } | ||||
public JT808MsgConsumer( | public JT808MsgConsumer( | ||||
IOptions<JT808ConsumerConfig> consumerConfigAccessor, | |||||
IOptions<JT808MsgConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | ILoggerFactory loggerFactory) | ||||
{ | { | ||||
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | ||||
@@ -14,7 +14,7 @@ namespace JT808.DotNetty.Kafka | |||||
private readonly IProducer<string, byte[]> producer; | private readonly IProducer<string, byte[]> producer; | ||||
public JT808MsgProducer( | public JT808MsgProducer( | ||||
IOptions<JT808ProducerConfig> producerConfigAccessor) | |||||
IOptions<JT808MsgProducerConfig> producerConfigAccessor) | |||||
{ | { | ||||
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | ||||
TopicName = producerConfigAccessor.Value.TopicName; | TopicName = producerConfigAccessor.Value.TopicName; | ||||
@@ -10,7 +10,7 @@ using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Kafka | namespace JT808.DotNetty.Kafka | ||||
{ | { | ||||
public class JT808MsgReplyConsumer : IJT808MsgConsumer | |||||
public class JT808MsgReplyConsumer : IJT808MsgReplyConsumer | |||||
{ | { | ||||
public CancellationTokenSource Cts => new CancellationTokenSource(); | public CancellationTokenSource Cts => new CancellationTokenSource(); | ||||
@@ -21,7 +21,7 @@ namespace JT808.DotNetty.Kafka | |||||
public string TopicName { get; } | public string TopicName { get; } | ||||
public JT808MsgReplyConsumer( | public JT808MsgReplyConsumer( | ||||
IOptions<JT808ConsumerConfig> consumerConfigAccessor, | |||||
IOptions<JT808MsgReplyConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | ILoggerFactory loggerFactory) | ||||
{ | { | ||||
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | ||||
@@ -8,13 +8,13 @@ using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Kafka | namespace JT808.DotNetty.Kafka | ||||
{ | { | ||||
public class JT808MsgReplyProducer : IJT808MsgProducer | |||||
public class JT808MsgReplyProducer : IJT808MsgReplyProducer | |||||
{ | { | ||||
public string TopicName { get;} | public string TopicName { get;} | ||||
private IProducer<string, byte[]> producer; | private IProducer<string, byte[]> producer; | ||||
public JT808MsgReplyProducer( | public JT808MsgReplyProducer( | ||||
IOptions<JT808ProducerConfig> producerConfigAccessor) | |||||
IOptions<JT808MsgReplyProducerConfig> producerConfigAccessor) | |||||
{ | { | ||||
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | ||||
TopicName = producerConfigAccessor.Value.TopicName; | TopicName = producerConfigAccessor.Value.TopicName; | ||||
@@ -0,0 +1,47 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public static class JT808ServerKafkaExtensions | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="jT808NettyBuilder"></param> | |||||
/// <param name="configuration">GetSection("JT808MsgProducerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IJT808NettyBuilder AddJT808ServerKafkaMsgProducer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) | |||||
{ | |||||
jT808NettyBuilder.JT808Builder.Services.Configure<JT808MsgProducerConfig>(configuration.GetSection("JT808MsgProducerConfig")); | |||||
jT808NettyBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgProducer), typeof(JT808MsgProducer), ServiceLifetime.Singleton)); | |||||
return jT808NettyBuilder; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="jT808NettyBuilder"></param> | |||||
/// <param name="configuration">GetSection("JT808MsgReplyConsumerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IJT808NettyBuilder AddJT808ServerKafkaMsgReplyConsumer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) | |||||
{ | |||||
jT808NettyBuilder.JT808Builder.Services.Configure<JT808MsgReplyConsumerConfig>(configuration.GetSection("JT808MsgReplyConsumerConfig")); | |||||
jT808NettyBuilder.JT808Builder.Services.Replace(new ServiceDescriptor(typeof(IJT808MsgReplyConsumer), typeof(JT808MsgReplyConsumer), ServiceLifetime.Singleton)); | |||||
return jT808NettyBuilder; | |||||
} | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <param name="jT808NettyBuilder"></param> | |||||
/// <param name="configuration">GetSection("JT808SessionProducerConfig")</param> | |||||
/// <returns></returns> | |||||
public static IJT808NettyBuilder AddJT808ServerKafkaSessionProducer(this IJT808NettyBuilder jT808NettyBuilder, IConfiguration configuration) | |||||
{ | |||||
jT808NettyBuilder.JT808Builder.Services.Configure<JT808SessionProducerConfig>(configuration.GetSection("JT808SessionProducerConfig")); | |||||
jT808NettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionProducer, JT808SessionProducer>(); | |||||
return jT808NettyBuilder; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,84 @@ | |||||
using Confluent.Kafka; | |||||
using JT808.DotNetty.Abstractions; | |||||
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.Kafka | |||||
{ | |||||
public class JT808SessionConsumer : IJT808SessionConsumer | |||||
{ | |||||
public CancellationTokenSource Cts => new CancellationTokenSource(); | |||||
private readonly IConsumer<string, string> consumer; | |||||
private readonly ILogger logger; | |||||
public string TopicName { get; } | |||||
public JT808SessionConsumer( | |||||
IOptions<JT808SessionConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
consumer = new ConsumerBuilder<string, string>(consumerConfigAccessor.Value).Build(); | |||||
TopicName = consumerConfigAccessor.Value.TopicName; | |||||
logger = loggerFactory.CreateLogger("JT808SessionConsumer"); | |||||
} | |||||
public void OnMessage(Action<(string Notice, string TerminalNo)> callback) | |||||
{ | |||||
Task.Run(() => | |||||
{ | |||||
while (!Cts.IsCancellationRequested) | |||||
{ | |||||
try | |||||
{ | |||||
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据 | |||||
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据 | |||||
var data = consumer.Consume(Cts.Token); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"Topic: {data.Topic} Key: {data.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}"); | |||||
} | |||||
callback((data.Key, data.Value)); | |||||
} | |||||
catch (ConsumeException ex) | |||||
{ | |||||
logger.LogError(ex, TopicName); | |||||
Thread.Sleep(1000); | |||||
} | |||||
catch (OperationCanceledException ex) | |||||
{ | |||||
logger.LogError(ex, TopicName); | |||||
Thread.Sleep(1000); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex, TopicName); | |||||
Thread.Sleep(1000); | |||||
} | |||||
} | |||||
}, Cts.Token); | |||||
} | |||||
public void Subscribe() | |||||
{ | |||||
consumer.Subscribe(TopicName); | |||||
} | |||||
public void Unsubscribe() | |||||
{ | |||||
consumer.Unsubscribe(); | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
consumer.Close(); | |||||
consumer.Dispose(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
using Confluent.Kafka; | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace JT808.DotNetty.Kafka | |||||
{ | |||||
public class JT808SessionProducer : IJT808SessionProducer | |||||
{ | |||||
public string TopicName { get; } | |||||
private readonly IProducer<string, string> producer; | |||||
public JT808SessionProducer( | |||||
IOptions<JT808SessionProducerConfig> producerConfigAccessor) | |||||
{ | |||||
producer = new ProducerBuilder<string, string>(producerConfigAccessor.Value).Build(); | |||||
TopicName = producerConfigAccessor.Value.TopicName; | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
producer.Dispose(); | |||||
} | |||||
public async Task ProduceAsync(string notice,string terminalNo) | |||||
{ | |||||
await producer.ProduceAsync(TopicName, new Message<string, string> | |||||
{ | |||||
Key = notice, | |||||
Value = terminalNo | |||||
}); | |||||
} | |||||
} | |||||
} |
@@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | using Microsoft.Extensions.DependencyInjection.Extensions; | ||||
using System.Runtime.CompilerServices; | using System.Runtime.CompilerServices; | ||||
using JT808.DotNetty.Core.Interfaces; | using JT808.DotNetty.Core.Interfaces; | ||||
using JT808.DotNetty.Abstractions; | |||||
[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] | [assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] | ||||
@@ -13,7 +13,7 @@ namespace JT808.DotNetty.Core.Test | |||||
public class SeedTcpSession | public class SeedTcpSession | ||||
{ | { | ||||
public JT808SessionManager jT80TcpSessionManager = new JT808SessionManager( | public JT808SessionManager jT80TcpSessionManager = new JT808SessionManager( | ||||
new JT808SessionPublishingEmptyImpl(new LoggerFactory()), | |||||
new JT808SessionProducerDefaultImpl(new LoggerFactory()), | |||||
new LoggerFactory()); | new LoggerFactory()); | ||||
public SeedTcpSession() | public SeedTcpSession() | ||||
@@ -18,6 +18,7 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\..\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | |||||
<ProjectReference Include="..\..\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj" /> | <ProjectReference Include="..\..\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj" /> | ||||
<ProjectReference Include="..\..\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj" /> | <ProjectReference Include="..\..\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj" /> | ||||
<ProjectReference Include="..\..\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj" /> | <ProjectReference Include="..\..\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj" /> | ||||
@@ -19,6 +19,7 @@ using System.Collections.Generic; | |||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using WebApiClient.Extensions.DependencyInjection; | using WebApiClient.Extensions.DependencyInjection; | ||||
using JT808.DotNetty.Kafka; | |||||
namespace JT808.DotNetty.Hosting | namespace JT808.DotNetty.Hosting | ||||
{ | { | ||||
@@ -55,7 +56,14 @@ namespace JT808.DotNetty.Hosting | |||||
.AddJT808TcpNettyHost() | .AddJT808TcpNettyHost() | ||||
.AddJT808UdpNettyHost() | .AddJT808UdpNettyHost() | ||||
.AddJT808WebApiNettyHost() | .AddJT808WebApiNettyHost() | ||||
//扩展webapi JT808MsgIdHttpHandlerBase | |||||
//.ReplaceMsgIdHandler<JT808MsgIdHttpCustomHandler>() | |||||
.Builder(); | .Builder(); | ||||
//添加kafka插件 | |||||
//.AddJT808ServerKafkaMsgProducer(hostContext.Configuration) | |||||
//.AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) | |||||
//.AddJT808ServerKafkaSessionProducer(hostContext.Configuration) | |||||
//.Builder(); | |||||
//webapi客户端调用 | //webapi客户端调用 | ||||
//services.AddHttpApi<IJT808DotNettyWebApi>().ConfigureHttpApiConfig((c, p) => | //services.AddHttpApi<IJT808DotNettyWebApi>().ConfigureHttpApiConfig((c, p) => | ||||
//{ | //{ | ||||
@@ -7,7 +7,11 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | |||||
<PackageReference Include="xunit" Version="2.4.1" /> | <PackageReference Include="xunit" Version="2.4.1" /> | ||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | ||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
@@ -19,4 +23,10 @@ | |||||
<ProjectReference Include="..\..\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | <ProjectReference Include="..\..\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<None Update="JT808Config.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -0,0 +1,13 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808BaseTest | |||||
{ | |||||
public const string BootstrapServers = "172.16.19.120:9092"; | |||||
//public const string BootstrapServers = "192.168.3.11:9092"; | |||||
} | |||||
} |
@@ -0,0 +1,54 @@ | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Xunit; | |||||
using Microsoft.Extensions.FileProviders; | |||||
using Microsoft.Extensions.Options; | |||||
using System.IO; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808ConfigTest | |||||
{ | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
var configurationBuilder = new ConfigurationBuilder(); | |||||
configurationBuilder.SetBasePath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory)); | |||||
configurationBuilder.AddJsonFile("JT808Config.json"); | |||||
IConfigurationRoot configurationRoot = configurationBuilder.Build(); | |||||
IServiceCollection serviceDescriptors = new ServiceCollection(); | |||||
serviceDescriptors.Configure<JT808MsgProducerConfig>(configurationRoot.GetSection("JT808MsgProducerConfig")); | |||||
serviceDescriptors.Configure<JT808MsgConsumerConfig>(configurationRoot.GetSection("JT808MsgConsumerConfig")); | |||||
serviceDescriptors.Configure<JT808MsgReplyProducerConfig>(configurationRoot.GetSection("JT808MsgReplyProducerConfig")); | |||||
serviceDescriptors.Configure<JT808MsgReplyConsumerConfig>(configurationRoot.GetSection("JT808MsgReplyConsumerConfig")); | |||||
serviceDescriptors.Configure<JT808SessionProducerConfig>(configurationRoot.GetSection("JT808SessionProducerConfig")); | |||||
serviceDescriptors.Configure<JT808SessionConsumerConfig>(configurationRoot.GetSection("JT808SessionConsumerConfig")); | |||||
var serviceProvider = serviceDescriptors.BuildServiceProvider(); | |||||
var jT808MsgProducerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808MsgProducerConfig>>(); | |||||
Assert.Equal("JT808Msg", jT808MsgProducerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9092", jT808MsgProducerConfigAccessor.Value.BootstrapServers); | |||||
var jT808MsgConsumerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808MsgConsumerConfig>>(); | |||||
Assert.Equal("JT808Msg", jT808MsgConsumerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9092", jT808MsgConsumerConfigAccessor.Value.BootstrapServers); | |||||
Assert.Equal("msg-group", jT808MsgConsumerConfigAccessor.Value.GroupId); | |||||
var jT808MsgReplyProducerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808MsgReplyProducerConfig>>(); | |||||
Assert.Equal("JT808MsgReply", jT808MsgReplyProducerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9093", jT808MsgReplyProducerConfigAccessor.Value.BootstrapServers); | |||||
var jT808MsgReplyConsumerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808MsgReplyConsumerConfig>>(); | |||||
Assert.Equal("JT808MsgReply", jT808MsgReplyConsumerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9093", jT808MsgReplyConsumerConfigAccessor.Value.BootstrapServers); | |||||
Assert.Equal("msgreply-group", jT808MsgReplyConsumerConfigAccessor.Value.GroupId); | |||||
var jT808SessionProducerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808SessionProducerConfig>>(); | |||||
Assert.Equal("JT808Session", jT808SessionProducerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9094", jT808SessionProducerConfigAccessor.Value.BootstrapServers); | |||||
var jT808SessionConsumerConfigAccessor = serviceProvider.GetRequiredService<IOptions<JT808SessionConsumerConfig>>(); | |||||
Assert.Equal("JT808Session", jT808SessionConsumerConfigAccessor.Value.TopicName); | |||||
Assert.Equal("127.0.0.1:9094", jT808SessionConsumerConfigAccessor.Value.BootstrapServers); | |||||
Assert.Equal("session-group", jT808SessionConsumerConfigAccessor.Value.GroupId); | |||||
} | |||||
} | |||||
} |
@@ -9,16 +9,12 @@ using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | namespace JT808.DotNetty.Kafka.Test | ||||
{ | { | ||||
public class JT808MsgConsumerTest | |||||
public class JT808MsgConsumerTest: JT808BaseTest | |||||
{ | { | ||||
public const string BootstrapServers = "172.16.19.120:9092"; | |||||
//public const string BootstrapServers = "192.168.3.11:9092"; | |||||
public JT808ConsumerConfig JT808ConsumerConfig = new JT808ConsumerConfig | |||||
public JT808MsgConsumerConfig JT808ConsumerConfig = new JT808MsgConsumerConfig | |||||
{ | { | ||||
GroupId="jt808.gps.test", | |||||
TopicName = "jt808test", | |||||
GroupId= "JT808Msg.test", | |||||
TopicName = "JT808Msg", | |||||
BootstrapServers = BootstrapServers | BootstrapServers = BootstrapServers | ||||
}; | }; | ||||
[Fact] | [Fact] | ||||
@@ -9,15 +9,12 @@ using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | namespace JT808.DotNetty.Kafka.Test | ||||
{ | { | ||||
public class JT808MsgProducerTest | |||||
public class JT808MsgProducerTest: JT808BaseTest | |||||
{ | { | ||||
public const string BootstrapServers = "172.16.19.120:9092"; | |||||
//public const string BootstrapServers = "192.168.3.11:9092"; | |||||
public JT808ProducerConfig JT808ProducerConfig = new JT808ProducerConfig | |||||
public JT808MsgProducerConfig JT808ProducerConfig = new JT808MsgProducerConfig | |||||
{ | { | ||||
TopicName = "jt808test", | |||||
TopicName = "JT808Msg", | |||||
BootstrapServers = BootstrapServers | BootstrapServers = BootstrapServers | ||||
}; | }; | ||||
@@ -29,6 +26,10 @@ namespace JT808.DotNetty.Kafka.Test | |||||
{ | { | ||||
adminClient.DeleteTopicsAsync(new List<string>() { JT808ProducerConfig.TopicName }).Wait(); | adminClient.DeleteTopicsAsync(new List<string>() { JT808ProducerConfig.TopicName }).Wait(); | ||||
} | } | ||||
catch (AggregateException e) | |||||
{ | |||||
//Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | |||||
} | |||||
catch (CreateTopicsException e) | catch (CreateTopicsException e) | ||||
{ | { | ||||
Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | ||||
@@ -0,0 +1,36 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808MsgReplyConsumerTest: JT808BaseTest | |||||
{ | |||||
public JT808MsgReplyConsumerConfig JT808ConsumerConfig = new JT808MsgReplyConsumerConfig | |||||
{ | |||||
GroupId= "jt808.MsgReply.test", | |||||
TopicName = "JT808MsgReply", | |||||
BootstrapServers = BootstrapServers | |||||
}; | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
using (IJT808MsgReplyConsumer JT808MsgConsumer = new JT808MsgReplyConsumer(JT808ConsumerConfig, new LoggerFactory())) | |||||
{ | |||||
JT808MsgConsumer.Subscribe(); | |||||
JT808MsgConsumer.OnMessage(item => | |||||
{ | |||||
Debug.WriteLine($"{item.TerminalNo}-{item.Data.Length}"); | |||||
}); | |||||
Thread.Sleep(30000); | |||||
JT808MsgConsumer.Unsubscribe(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,59 @@ | |||||
using Confluent.Kafka; | |||||
using Confluent.Kafka.Admin; | |||||
using JT808.DotNetty.Abstractions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
using System.Text; | |||||
using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808MsgReplyProducerTest: JT808BaseTest | |||||
{ | |||||
public JT808MsgReplyProducerConfig JT808ProducerConfig = new JT808MsgReplyProducerConfig | |||||
{ | |||||
TopicName = "JT808MsgReply", | |||||
BootstrapServers = BootstrapServers | |||||
}; | |||||
public JT808MsgReplyProducerTest() | |||||
{ | |||||
using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = BootstrapServers }).Build()) | |||||
{ | |||||
try | |||||
{ | |||||
adminClient.DeleteTopicsAsync(new List<string>() { JT808ProducerConfig.TopicName }).Wait(); | |||||
} | |||||
catch(AggregateException e) | |||||
{ | |||||
//Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | |||||
} | |||||
catch (CreateTopicsException e) | |||||
{ | |||||
Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | |||||
} | |||||
} | |||||
} | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
using (IJT808MsgReplyProducer jT808MsgProducer = new JT808MsgReplyProducer(JT808ProducerConfig)) | |||||
{ | |||||
jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); | |||||
} | |||||
} | |||||
[Fact] | |||||
public void Test2() | |||||
{ | |||||
using (IJT808MsgReplyProducer jT808MsgProducer = new JT808MsgReplyProducer(JT808ProducerConfig)) | |||||
{ | |||||
jT808MsgProducer.ProduceAsync("123457", new byte[] { 0x7E, 0, 0x7E }).Wait(); | |||||
jT808MsgProducer.ProduceAsync("123456", new byte[] { 0x7E, 0, 0x7E }).Wait(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
using JT808.DotNetty.Abstractions; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808SessionConsumerTest : JT808BaseTest | |||||
{ | |||||
public JT808SessionConsumerConfig JT808ConsumerConfig = new JT808SessionConsumerConfig | |||||
{ | |||||
GroupId= "JT808Session.test", | |||||
TopicName = "JT808Session", | |||||
BootstrapServers = BootstrapServers | |||||
}; | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
using (IJT808SessionConsumer JT808MsgConsumer = new JT808SessionConsumer(JT808ConsumerConfig, new LoggerFactory())) | |||||
{ | |||||
JT808MsgConsumer.Subscribe(); | |||||
JT808MsgConsumer.OnMessage(item => | |||||
{ | |||||
Debug.WriteLine($"{item.TerminalNo}-{item.Notice}"); | |||||
}); | |||||
Thread.Sleep(30000); | |||||
JT808MsgConsumer.Unsubscribe(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,49 @@ | |||||
using Confluent.Kafka; | |||||
using Confluent.Kafka.Admin; | |||||
using JT808.DotNetty.Abstractions; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
using System.Text; | |||||
using Xunit; | |||||
namespace JT808.DotNetty.Kafka.Test | |||||
{ | |||||
public class JT808SessionProducerTest: JT808BaseTest | |||||
{ | |||||
public JT808SessionProducerConfig JT808ProducerConfig = new JT808SessionProducerConfig | |||||
{ | |||||
TopicName = "JT808Session", | |||||
BootstrapServers = BootstrapServers | |||||
}; | |||||
public JT808SessionProducerTest() | |||||
{ | |||||
using (var adminClient = new AdminClientBuilder(new AdminClientConfig { BootstrapServers = BootstrapServers }).Build()) | |||||
{ | |||||
try | |||||
{ | |||||
adminClient.DeleteTopicsAsync(new List<string>() { JT808ProducerConfig.TopicName }).Wait(); | |||||
} | |||||
catch (AggregateException e) | |||||
{ | |||||
//Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | |||||
} | |||||
catch (CreateTopicsException e) | |||||
{ | |||||
Debug.WriteLine($"An error occured creating topic {e.Results[0].Topic}: {e.Results[0].Error.Reason}"); | |||||
} | |||||
} | |||||
} | |||||
[Fact] | |||||
public void Test1() | |||||
{ | |||||
using (IJT808SessionProducer jT808MsgProducer = new JT808SessionProducer(JT808ProducerConfig)) | |||||
{ | |||||
jT808MsgProducer.ProduceAsync("online","123456").Wait(); | |||||
jT808MsgProducer.ProduceAsync("offline", "123457").Wait(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,4 +1,5 @@ | |||||
using JT808.DotNetty.Core.Codecs; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Core.Codecs; | |||||
using JT808.DotNetty.Core.Impls; | using JT808.DotNetty.Core.Impls; | ||||
using JT808.DotNetty.Core.Interfaces; | using JT808.DotNetty.Core.Interfaces; | ||||
using JT808.DotNetty.Udp.Handlers; | using JT808.DotNetty.Udp.Handlers; | ||||
@@ -1,4 +1,5 @@ | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Core.Interfaces; | using JT808.DotNetty.Core.Interfaces; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using Microsoft.Extensions.DependencyInjection.Extensions; | using Microsoft.Extensions.DependencyInjection.Extensions; | ||||
@@ -1,4 +1,5 @@ | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Abstractions; | |||||
using JT808.DotNetty.Core.Handlers; | |||||
using JT808.DotNetty.Core.Interfaces; | using JT808.DotNetty.Core.Interfaces; | ||||
using JT808.DotNetty.WebApi.Handlers; | using JT808.DotNetty.WebApi.Handlers; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||