@@ -35,14 +35,13 @@ | |||
|接口名称|接口说明|使用场景| | |||
|:------:|:------|:------| | |||
| IJT808SessionPublishing| 会话通知(在线/离线)| 有些超长待机的设备,不会实时保持连接,那么通过平台下发的命令是无法到达的,这时候就需要设备一上线,就即时通知服务去处理,然后在即时的下发消息到设备。| | |||
| IJT808SessionProducer| 会话通知(在线/离线)数据生产接口| 有些超长待机的设备,不会实时保持连接,那么通过平台下发的命令是无法到达的,这时候就需要设备一上线,就即时通知服务去处理,然后在即时的下发消息到设备。| | |||
| IJT808SessionConsumer| 会话通知(在线/离线)数据消费接口| -| | |||
| IJT808MsgProducer| 数据生产接口| 网关将接收到的数据发送到队列| | |||
| IJT808MsgConsumer| 数据消费接口| 将数据进行对应的消息业务处理(例:设备流量统计、第三方平台数据转发、消息日志等) | | |||
| IJT808MsgReplyProducer| 应答数据生产接口|将生产的数据解析为对应的消息Id应答发送到队列 | | |||
| IJT808MsgReplyConsumer| 应答数据消费接口| 将接收到的应答数据下发给设备| | |||
> 只要实现IJT808SessionPublishing接口的任意一款MQ都能实现该功能。 | |||
> 使用物联网卡通过udp下发指令时,存储的那个socket地址端口,有效期非常短,不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了,所以此处采用跟随设备消息下发指令。 | |||
## NuGet安装 | |||
@@ -81,21 +80,26 @@ static async Task Main(string[] args) | |||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||
services.AddJT808Configure() | |||
.AddJT808NettyCore(hostContext.Configuration) | |||
//自定义会话通知(在线/离线)使用异步方式 | |||
//.ReplaceSessionPublishing<CustomJT808SessionPublishing>() | |||
.AddJT808TcpNettyHost() | |||
.AddJT808UdpNettyHost() | |||
.AddJT808WebApiNettyHost() | |||
//扩展webapi JT808MsgIdHttpHandlerBase | |||
//.ReplaceMsgIdHandler<JT808MsgIdHttpCustomHandler>() | |||
.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(); | |||
@@ -5,13 +5,11 @@ using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT808.DotNetty.Core.Interfaces | |||
namespace JT808.DotNetty.Abstractions | |||
{ | |||
public interface IJT808NettyBuilder | |||
{ | |||
IJT808Builder JT808Builder { get; } | |||
IJT808NettyBuilder ReplaceSessionPublishing<T>() where T : IJT808SessionPublishing; | |||
IJT808NettyBuilder ReplaceMsgProducer<T>() where T : IJT808MsgProducer; | |||
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> | |||
<PackageReleaseNotes>基于DotNetty实现的JT808DotNetty的抽象库</PackageReleaseNotes> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="JT808" Version="2.1.3" /> | |||
</ItemGroup> | |||
</Project> |
@@ -5,7 +5,7 @@ | |||
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"; | |||
@@ -23,22 +23,10 @@ namespace JT808.DotNetty.Core.Impls | |||
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.Collections.Generic; | |||
using System.Text; | |||
@@ -11,7 +11,6 @@ | |||
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | |||
<PackageReference Include="DotNetty.Transport.Libuv" 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.Options.ConfigurationExtensions" Version="2.2.0" /> | |||
<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<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | |||
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.AddHostedService<JT808MsgReplyHostedService>(); | |||
return nettyBuilder; | |||
@@ -93,7 +93,7 @@ namespace JT808.DotNetty.Core | |||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgProducer, JT808MsgProducerDefaultImpl>(); | |||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808MsgReplyConsumer, JT808MsgReplyConsumerDefaultImpl>(); | |||
nettyBuilder.JT808Builder.Services.TryAddSingleton<JT808MsgService>(); | |||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionPublishing, JT808SessionPublishingEmptyImpl>(); | |||
nettyBuilder.JT808Builder.Services.TryAddSingleton<IJT808SessionProducer, JT808SessionProducerDefaultImpl>(); | |||
nettyBuilder.JT808Builder.Services.AddHostedService<JT808MsgReplyHostedService>(); | |||
return nettyBuilder; | |||
} | |||
@@ -18,27 +18,27 @@ namespace JT808.DotNetty.Core.Session | |||
private readonly ILogger<JT808SessionManager> logger; | |||
private readonly IJT808DatagramPacket jT808DatagramPacket; | |||
public IJT808SessionPublishing JT808SessionPublishing { get; } | |||
public IJT808SessionProducer JT808SessionProducer { get; } | |||
public ConcurrentDictionary<string, IJT808Session> Sessions { get; } | |||
public JT808SessionManager( | |||
IJT808SessionPublishing jT808SessionPublishing, | |||
IJT808SessionProducer jT808SessionProducer, | |||
ILoggerFactory loggerFactory | |||
) | |||
{ | |||
Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | |||
JT808SessionPublishing = jT808SessionPublishing; | |||
JT808SessionProducer = jT808SessionProducer; | |||
logger = loggerFactory.CreateLogger<JT808SessionManager>(); | |||
} | |||
public JT808SessionManager( | |||
IJT808SessionPublishing jT808SessionPublishing, | |||
IJT808SessionProducer jT808SessionProducer, | |||
ILoggerFactory loggerFactory, | |||
IJT808DatagramPacket jT808DatagramPacket) | |||
{ | |||
Sessions = new ConcurrentDictionary<string, IJT808Session>(StringComparer.OrdinalIgnoreCase); | |||
JT808SessionPublishing = jT808SessionPublishing; | |||
JT808SessionProducer = jT808SessionProducer; | |||
logger = loggerFactory.CreateLogger<JT808SessionManager>(); | |||
this.jT808DatagramPacket = jT808DatagramPacket; | |||
} | |||
@@ -200,7 +200,7 @@ namespace JT808.DotNetty.Core.Session | |||
//部标的超长待机设备,不会像正常的设备一样一直连着,可能10几分钟连上了,然后发完就关闭连接, | |||
//这时候想下发数据需要知道设备什么时候上线,在这边做通知最好不过了。 | |||
//有设备关联上来可以进行通知 例如:使用Redis发布订阅 | |||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOnline, jT808TcpSession.TerminalPhoneNo); | |||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,jT808TcpSession.TerminalPhoneNo); | |||
} | |||
} | |||
} | |||
@@ -230,7 +230,7 @@ namespace JT808.DotNetty.Core.Session | |||
//移动很多卡,存储的那个socket地址端口,有效期非常短 | |||
//不速度快点下发,那个socket地址端口就可能映射到别的对应卡去了 | |||
//所以此处采用跟随设备消息下发指令 | |||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOnline, terminalPhoneNo); | |||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOnline,terminalPhoneNo); | |||
} | |||
public IJT808Session RemoveSession(string terminalPhoneNo) | |||
{ | |||
@@ -254,7 +254,7 @@ namespace JT808.DotNetty.Core.Session | |||
} | |||
string nos = string.Join(",", terminalPhoneNos); | |||
logger.LogInformation($">>>{terminalPhoneNo}-{nos} 1-n Session Remove."); | |||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, nos); | |||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); | |||
return jT808Session; | |||
} | |||
else | |||
@@ -262,7 +262,7 @@ namespace JT808.DotNetty.Core.Session | |||
if (Sessions.TryRemove(terminalPhoneNo, out IJT808Session jT808SessionRemove)) | |||
{ | |||
logger.LogInformation($">>>{terminalPhoneNo} Session Remove."); | |||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, terminalPhoneNo); | |||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, terminalPhoneNo); | |||
return jT808SessionRemove; | |||
} | |||
else | |||
@@ -284,7 +284,7 @@ namespace JT808.DotNetty.Core.Session | |||
} | |||
string nos = string.Join(",", terminalPhoneNos); | |||
logger.LogInformation($">>>{nos} Channel Remove."); | |||
JT808SessionPublishing.PublishAsync(JT808NettyConstants.SessionOffline, nos); | |||
JT808SessionProducer.ProduceAsync(JT808NettyConstants.SessionOffline, nos); | |||
} | |||
} | |||
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> | |||
<ItemGroup> | |||
<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.Options" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<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 JT808MsgConsumer( | |||
IOptions<JT808ConsumerConfig> consumerConfigAccessor, | |||
IOptions<JT808MsgConsumerConfig> consumerConfigAccessor, | |||
ILoggerFactory loggerFactory) | |||
{ | |||
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | |||
@@ -14,7 +14,7 @@ namespace JT808.DotNetty.Kafka | |||
private readonly IProducer<string, byte[]> producer; | |||
public JT808MsgProducer( | |||
IOptions<JT808ProducerConfig> producerConfigAccessor) | |||
IOptions<JT808MsgProducerConfig> producerConfigAccessor) | |||
{ | |||
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | |||
TopicName = producerConfigAccessor.Value.TopicName; | |||
@@ -10,7 +10,7 @@ using System.Threading.Tasks; | |||
namespace JT808.DotNetty.Kafka | |||
{ | |||
public class JT808MsgReplyConsumer : IJT808MsgConsumer | |||
public class JT808MsgReplyConsumer : IJT808MsgReplyConsumer | |||
{ | |||
public CancellationTokenSource Cts => new CancellationTokenSource(); | |||
@@ -21,7 +21,7 @@ namespace JT808.DotNetty.Kafka | |||
public string TopicName { get; } | |||
public JT808MsgReplyConsumer( | |||
IOptions<JT808ConsumerConfig> consumerConfigAccessor, | |||
IOptions<JT808MsgReplyConsumerConfig> consumerConfigAccessor, | |||
ILoggerFactory loggerFactory) | |||
{ | |||
consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build(); | |||
@@ -8,13 +8,13 @@ using System.Threading.Tasks; | |||
namespace JT808.DotNetty.Kafka | |||
{ | |||
public class JT808MsgReplyProducer : IJT808MsgProducer | |||
public class JT808MsgReplyProducer : IJT808MsgReplyProducer | |||
{ | |||
public string TopicName { get;} | |||
private IProducer<string, byte[]> producer; | |||
public JT808MsgReplyProducer( | |||
IOptions<JT808ProducerConfig> producerConfigAccessor) | |||
IOptions<JT808MsgReplyProducerConfig> producerConfigAccessor) | |||
{ | |||
producer = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value).Build(); | |||
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 System.Runtime.CompilerServices; | |||
using JT808.DotNetty.Core.Interfaces; | |||
using JT808.DotNetty.Abstractions; | |||
[assembly: InternalsVisibleTo("JT808.DotNetty.Tcp.Test")] | |||
@@ -13,7 +13,7 @@ namespace JT808.DotNetty.Core.Test | |||
public class SeedTcpSession | |||
{ | |||
public JT808SessionManager jT80TcpSessionManager = new JT808SessionManager( | |||
new JT808SessionPublishingEmptyImpl(new LoggerFactory()), | |||
new JT808SessionProducerDefaultImpl(new LoggerFactory()), | |||
new LoggerFactory()); | |||
public SeedTcpSession() | |||
@@ -18,6 +18,7 @@ | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | |||
<ProjectReference Include="..\..\JT808.DotNetty.Tcp\JT808.DotNetty.Tcp.csproj" /> | |||
<ProjectReference Include="..\..\JT808.DotNetty.Udp\JT808.DotNetty.Udp.csproj" /> | |||
<ProjectReference Include="..\..\JT808.DotNetty.WebApiClientTool\JT808.DotNetty.WebApiClientTool.csproj" /> | |||
@@ -19,6 +19,7 @@ using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.Threading.Tasks; | |||
using WebApiClient.Extensions.DependencyInjection; | |||
using JT808.DotNetty.Kafka; | |||
namespace JT808.DotNetty.Hosting | |||
{ | |||
@@ -55,7 +56,14 @@ namespace JT808.DotNetty.Hosting | |||
.AddJT808TcpNettyHost() | |||
.AddJT808UdpNettyHost() | |||
.AddJT808WebApiNettyHost() | |||
//扩展webapi JT808MsgIdHttpHandlerBase | |||
//.ReplaceMsgIdHandler<JT808MsgIdHttpCustomHandler>() | |||
.Builder(); | |||
//添加kafka插件 | |||
//.AddJT808ServerKafkaMsgProducer(hostContext.Configuration) | |||
//.AddJT808ServerKafkaMsgReplyConsumer(hostContext.Configuration) | |||
//.AddJT808ServerKafkaSessionProducer(hostContext.Configuration) | |||
//.Builder(); | |||
//webapi客户端调用 | |||
//services.AddHttpApi<IJT808DotNettyWebApi>().ConfigureHttpApiConfig((c, p) => | |||
//{ | |||
@@ -7,7 +7,11 @@ | |||
</PropertyGroup> | |||
<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.Options.ConfigurationExtensions" Version="2.2.0" /> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
@@ -19,4 +23,10 @@ | |||
<ProjectReference Include="..\..\JT808.DotNetty.Kafka\JT808.DotNetty.Kafka.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="JT808Config.json"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</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 | |||
{ | |||
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 | |||
}; | |||
[Fact] | |||
@@ -9,15 +9,12 @@ using Xunit; | |||
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 | |||
}; | |||
@@ -29,6 +26,10 @@ namespace JT808.DotNetty.Kafka.Test | |||
{ | |||
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}"); | |||
@@ -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.Interfaces; | |||
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 Microsoft.Extensions.DependencyInjection; | |||
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.WebApi.Handlers; | |||
using Microsoft.Extensions.DependencyInjection; | |||