@@ -3,6 +3,7 @@ using JT809.DotNetty.Core.Interfaces; | |||||
using JT809.DotNetty.Core.Metadata; | using JT809.DotNetty.Core.Metadata; | ||||
using JT809.DotNetty.Core.Session; | using JT809.DotNetty.Core.Session; | ||||
using JT809.Protocol; | using JT809.Protocol; | ||||
using JT809.Protocol.Configs; | |||||
using JT809.Protocol.Enums; | using JT809.Protocol.Enums; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using JT809.Protocol.MessageBody; | using JT809.Protocol.MessageBody; | ||||
@@ -20,15 +21,18 @@ namespace JT809.DotNetty.Core.Internal | |||||
private readonly JT809SuperiorMainSessionManager jT809SuperiorMainSessionManager; | private readonly JT809SuperiorMainSessionManager jT809SuperiorMainSessionManager; | ||||
private readonly ILogger logger; | private readonly ILogger logger; | ||||
private readonly JT809Serializer JT809Serializer; | private readonly JT809Serializer JT809Serializer; | ||||
private readonly JT809HeaderOptions JT809HeaderOptions; | |||||
public JT809SubordinateLinkNotifyImplService( | public JT809SubordinateLinkNotifyImplService( | ||||
JT809HeaderOptions jT809HeaderOptions, | |||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
IJT809Config jT809Config, | IJT809Config jT809Config, | ||||
IOptions<JT809Configuration> jT809ConfigurationAccessor, | IOptions<JT809Configuration> jT809ConfigurationAccessor, | ||||
JT809SuperiorMainSessionManager jT809SuperiorMainSessionManager | JT809SuperiorMainSessionManager jT809SuperiorMainSessionManager | ||||
) | ) | ||||
{ | { | ||||
JT809Serializer = jT809Config.GetSerializer(); | JT809Serializer = jT809Config.GetSerializer(); | ||||
JT809HeaderOptions = jT809HeaderOptions; | |||||
this.logger = loggerFactory.CreateLogger<JT809SubordinateLinkNotifyImplService>(); | this.logger = loggerFactory.CreateLogger<JT809SubordinateLinkNotifyImplService>(); | ||||
configuration = jT809ConfigurationAccessor.Value; | configuration = jT809ConfigurationAccessor.Value; | ||||
this.jT809SuperiorMainSessionManager = jT809SuperiorMainSessionManager; | this.jT809SuperiorMainSessionManager = jT809SuperiorMainSessionManager; | ||||
@@ -36,28 +40,26 @@ namespace JT809.DotNetty.Core.Internal | |||||
public void Notify(JT809_0x9007_ReasonCode reasonCode) | public void Notify(JT809_0x9007_ReasonCode reasonCode) | ||||
{ | { | ||||
#warning JT809GlobalConfig | Notify(reasonCode, JT809HeaderOptions.MsgGNSSCENTERID); | ||||
//Notify(reasonCode, JT809GlobalConfig.Instance.HeaderOptions.MsgGNSSCENTERID); | |||||
} | } | ||||
public void Notify(JT809_0x9007_ReasonCode reasonCode, uint msgGNSSCENTERID) | public void Notify(JT809_0x9007_ReasonCode reasonCode, uint msgGNSSCENTERID) | ||||
{ | { | ||||
if (configuration.SubordinateClientEnable) | if (configuration.SubordinateClientEnable) | ||||
{ | { | ||||
#warning jT809SuperiorMainSessionManager | var session = jT809SuperiorMainSessionManager.GetSession(msgGNSSCENTERID); | ||||
//var session = jT809SuperiorMainSessionManager.GetSession(JT809GlobalConfig.Instance.HeaderOptions.MsgGNSSCENTERID); | if (session != null) | ||||
//if (session != null) | { | ||||
//{ | //发送从链路注销请求 | ||||
// //发送从链路注销请求 | var package = JT809BusinessType.从链路断开通知消息.Create(new JT809_0x9007() | ||||
// var package = JT809BusinessType.从链路断开通知消息.Create(new JT809_0x9007() | { | ||||
// { | ReasonCode = reasonCode | ||||
// ReasonCode = reasonCode | }); | ||||
// }); | JT809Response jT809Response = new JT809Response(package, 100); | ||||
// JT809Response jT809Response = new JT809Response(package, 100); | if (logger.IsEnabled(LogLevel.Information)) | ||||
// if (logger.IsEnabled(LogLevel.Information)) | logger.LogInformation($"从链路断开通知消息>>>{JT809Serializer.Serialize(package, 100).ToHexString()}"); | ||||
// logger.LogInformation($"从链路断开通知消息>>>{JT809Serializer.Serialize(package, 100).ToHexString()}"); | session.Channel.WriteAndFlushAsync(jT809Response); | ||||
// session.Channel.WriteAndFlushAsync(jT809Response); | } | ||||
//} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -11,6 +11,7 @@ using System.Threading.Tasks; | |||||
using JT809.Protocol.SubMessageBody; | using JT809.Protocol.SubMessageBody; | ||||
using JT809.Protocol.Metadata; | using JT809.Protocol.Metadata; | ||||
using JT809.Protocol.MessageBody; | using JT809.Protocol.MessageBody; | ||||
using JT809.Protocol.Enums; | |||||
namespace JT809.Inferior.Client | namespace JT809.Inferior.Client | ||||
{ | { | ||||
@@ -101,7 +102,7 @@ namespace JT809.Inferior.Client | |||||
Vec3 = 12 | Vec3 = 12 | ||||
} | } | ||||
}; | }; | ||||
var package = JT809.Protocol.Enums.JT809BusinessType.主链路车辆动态信息交换业务.Create(jT809_0X1200); | var package = JT809BusinessType.主链路车辆动态信息交换业务.Create(jT809_0X1200); | ||||
mainClient.SendAsync(new JT809Response(package, 256)); | mainClient.SendAsync(new JT809Response(package, 256)); | ||||
logger.LogDebug($"Thread:{Thread.CurrentThread.ManagedThreadId}-4s"); | logger.LogDebug($"Thread:{Thread.CurrentThread.ManagedThreadId}-4s"); | ||||
Thread.Sleep(4000); | Thread.Sleep(4000); | ||||
@@ -1,4 +1,5 @@ | |||||
using JT809.GrpcProtos; | using JT809.GrpcProtos; | ||||
using JT809.KafkaService; | |||||
using JT809.PubSub.Abstractions; | using JT809.PubSub.Abstractions; | ||||
using Microsoft.Extensions.Hosting; | using Microsoft.Extensions.Hosting; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
@@ -13,13 +14,13 @@ namespace JT809.GpsConsumer | |||||
{ | { | ||||
public class GpsConsumerService : IHostedService | public class GpsConsumerService : IHostedService | ||||
{ | { | ||||
private readonly IJT808ConsumerOfT<JT809GpsPosition> jT808Consumer; | private readonly JT809_GpsPosition_Consumer jT808Consumer; | ||||
private readonly ILogger logger; | private readonly ILogger logger; | ||||
public GpsConsumerService( | public GpsConsumerService( | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
IJT808ConsumerOfT<JT809GpsPosition> jT808Consumer) | JT809_GpsPosition_Consumer jT808Consumer) | ||||
{ | { | ||||
this.jT808Consumer = jT808Consumer; | this.jT808Consumer = jT808Consumer; | ||||
logger = loggerFactory.CreateLogger<GpsConsumerService>(); | logger = loggerFactory.CreateLogger<GpsConsumerService>(); | ||||
@@ -27,8 +27,7 @@ namespace JT809.GpsConsumer | |||||
{ | { | ||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | services.AddSingleton<ILoggerFactory, LoggerFactory>(); | ||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | ||||
#warning AddJT809KafkaConsumerPartitionsService | services.AddJT809KafkaConsumerService(hostContext.Configuration); | ||||
//services.AddJT809KafkaConsumerPartitionsService(hostContext.Configuration, options => options.Partition = 10); | |||||
services.AddHostedService<GpsConsumerService>(); | services.AddHostedService<GpsConsumerService>(); | ||||
}); | }); | ||||
@@ -0,0 +1,15 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.KafkaService.Configs | |||||
{ | |||||
public class JT809SameConsumerConfig : ConsumerConfig, IOptions<JT809SameConsumerConfig> | |||||
{ | |||||
public string TopicName { get; set; } | |||||
public JT809SameConsumerConfig Value => this; | |||||
} | |||||
} |
@@ -0,0 +1,15 @@ | |||||
using Confluent.Kafka; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.KafkaService.Configs | |||||
{ | |||||
public class JT809SameProducerConfig : ProducerConfig,IOptions<JT809SameProducerConfig> | |||||
{ | |||||
public string TopicName { get; set; } | |||||
public JT809SameProducerConfig Value => this; | |||||
} | |||||
} |
@@ -1,103 +0,0 @@ | |||||
using Confluent.Kafka; | |||||
using JT809.KafkaService.Configs; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT809.KafkaService | |||||
{ | |||||
public abstract class JT809Consumer<T> : JT809ConsumerBase<T> | |||||
{ | |||||
private bool _disposed = false; | |||||
public override CancellationTokenSource Cts { get; }= new CancellationTokenSource(); | |||||
protected ILogger logger { get; } | |||||
protected override IConsumer<string, T> Consumer { get; } | |||||
protected JT809Consumer( | |||||
IOptions<JT809ConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | |||||
: base(consumerConfigAccessor.Value) | |||||
{ | |||||
logger = loggerFactory.CreateLogger("JT809Consumer"); | |||||
ConsumerBuilder<string, T> consumerBuilder = new ConsumerBuilder<string, T>(ConsumerConfig); | |||||
consumerBuilder.SetErrorHandler((consumer, error) => | |||||
{ | |||||
logger.LogError(error.Reason); | |||||
}); | |||||
Consumer = consumerBuilder.Build(); | |||||
} | |||||
public override void OnMessage(Action<(string MsgId, T Data)> callback) | |||||
{ | |||||
Task.Run(() => | |||||
{ | |||||
while (!Cts.IsCancellationRequested) | |||||
{ | |||||
try | |||||
{ | |||||
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据 | |||||
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据 | |||||
//consumers[n].Assign(topicPartitionList[n]); | |||||
var data = Consumer.Consume(Cts.Token); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} Data:{string.Join("", data.Message.Value)} TopicPartitionOffset:{data.TopicPartitionOffset}"); | |||||
} | |||||
callback((data.Message.Key, data.Message.Value)); | |||||
} | |||||
catch (ConsumeException ex) | |||||
{ | |||||
logger.LogError(ex, ConsumerConfig.TopicName); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex, ConsumerConfig.TopicName); | |||||
} | |||||
} | |||||
}, Cts.Token); | |||||
} | |||||
public override void Subscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
//仅有一个分区才需要订阅 | |||||
Consumer.Subscribe(ConsumerConfig.TopicName); | |||||
} | |||||
public override void Unsubscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
Consumer.Unsubscribe(); | |||||
} | |||||
public override void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
~JT809Consumer() | |||||
{ | |||||
Dispose(false); | |||||
} | |||||
protected virtual void Dispose(bool disposing) | |||||
{ | |||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Cts.Cancel(); | |||||
Consumer.Close(); | |||||
Consumer.Dispose(); | |||||
Cts.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | |||||
} | |||||
} |
@@ -1,30 +0,0 @@ | |||||
using Confluent.Kafka; | |||||
using JT809.KafkaService.Configs; | |||||
using JT809.PubSub.Abstractions; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace JT809.KafkaService | |||||
{ | |||||
public abstract class JT809ConsumerBase<T> : IJT808ConsumerOfT<T> | |||||
{ | |||||
public JT809ConsumerConfig ConsumerConfig { get; } | |||||
protected JT809ConsumerBase(IOptions<JT809ConsumerConfig> config) | |||||
{ | |||||
ConsumerConfig = config.Value; | |||||
} | |||||
public abstract CancellationTokenSource Cts { get; } | |||||
protected abstract IConsumer<string, T> Consumer { get; } | |||||
public abstract void Dispose(); | |||||
public abstract void OnMessage(Action<(string MsgId, T Data)> callback); | |||||
public abstract void Subscribe(); | |||||
public abstract void Unsubscribe(); | |||||
} | |||||
} |
@@ -1,5 +1,6 @@ | |||||
using Confluent.Kafka; | using Confluent.Kafka; | ||||
using JT809.GrpcProtos; | using JT809.GrpcProtos; | ||||
using JT809.KafkaService.Configs; | |||||
using JT809.PubSub.Abstractions; | using JT809.PubSub.Abstractions; | ||||
using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
@@ -15,43 +16,33 @@ namespace JT809.KafkaService | |||||
{ | { | ||||
public static IServiceCollection AddJT809KafkaProducerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | public static IServiceCollection AddJT809KafkaProducerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | ||||
{ | { | ||||
serviceDescriptors.Configure<ProducerConfig>(configuration.GetSection("KafkaProducerConfig")); | serviceDescriptors.Configure<JT809ProducerConfig>(configuration.GetSection("JT809ProducerConfig")); | ||||
serviceDescriptors.AddSingleton(typeof(IJT809ProducerOfT<byte[]>), (service) => { | serviceDescriptors.AddSingleton<JT809_GpsPositio_Producer>(); | ||||
var producerConfig = service.GetRequiredService<IOptions<ProducerConfig>>(); | |||||
#warning JT809_Same_Producer | |||||
//return new JT809_Same_Producer(new JT809TopicOptions { TopicName = "jt809.same" }, producerConfig); | |||||
return null; | |||||
}); | |||||
serviceDescriptors.AddSingleton(typeof(IJT809ProducerOfT<JT809GpsPosition>), (service) => { | |||||
var producerConfig = service.GetRequiredService<IOptions<ProducerConfig>>(); | |||||
#warning JT809_GpsPositio_Producer | |||||
//return new JT809_GpsPositio_Producer(new JT809TopicOptions { TopicName = "jt809.gps" }, producerConfig); | |||||
return null; | |||||
}); | |||||
return serviceDescriptors; | return serviceDescriptors; | ||||
} | } | ||||
public static IServiceCollection AddJT809KafkaConsumerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | public static IServiceCollection AddJT809KafkaConsumerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | ||||
{ | { | ||||
serviceDescriptors.Configure<ConsumerConfig>(configuration.GetSection("KafkaConsumerConfig")); | serviceDescriptors.Configure<JT809ConsumerConfig>(configuration.GetSection("JT809ConsumerConfig")); | ||||
serviceDescriptors.AddSingleton(typeof(IJT808ConsumerOfT<byte[]>), (service)=> { | serviceDescriptors.AddSingleton<JT809_GpsPosition_Consumer>(); | ||||
var loggerFactory = service.GetRequiredService<ILoggerFactory>(); | |||||
var consumerConfig = service.GetRequiredService<IOptions<ConsumerConfig>>(); | |||||
consumerConfig.Value.GroupId = "JT809.same.Test"; | |||||
#warning JT809_Same_Consumer | |||||
//return new JT809_Same_Consumer(new JT809TopicOptions { TopicName = "jt809.same" }, consumerConfig, loggerFactory); | |||||
return null; | |||||
}); | |||||
serviceDescriptors.AddSingleton(typeof(IJT808ConsumerOfT<JT809GpsPosition>), (service) => { | |||||
var loggerFactory = service.GetRequiredService<ILoggerFactory>(); | |||||
var consumerConfig = service.GetRequiredService<IOptions<ConsumerConfig>>(); | |||||
consumerConfig.Value.GroupId = "JT809.gps.Test"; | |||||
#warning JT809_GpsPosition_Consumer | |||||
//return new JT809_GpsPosition_Consumer(new JT809TopicOptions { TopicName = "jt809.gps" }, consumerConfig, loggerFactory); | |||||
return null; | |||||
}); | |||||
return serviceDescriptors; | return serviceDescriptors; | ||||
} | } | ||||
public static IServiceCollection AddJT809KafkaSameProducerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.Configure<JT809SameProducerConfig>(configuration.GetSection("JT809SameProducerConfig")); | |||||
serviceDescriptors.AddSingleton<JT809_GpsPositio_Producer>(); | |||||
return serviceDescriptors; | |||||
} | |||||
public static IServiceCollection AddJT809KafkaSameConsumerService(this IServiceCollection serviceDescriptors, IConfiguration configuration) | |||||
{ | |||||
serviceDescriptors.Configure<JT809SameConsumerConfig>(configuration.GetSection("JT809SameConsumerConfig")); | |||||
serviceDescriptors.AddSingleton<JT809_Same_Consumer>(); | |||||
return serviceDescriptors; | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,67 +0,0 @@ | |||||
using Confluent.Kafka; | |||||
using Confluent.Kafka.Admin; | |||||
using JT809.KafkaService.Configs; | |||||
using JT809.PubSub.Abstractions; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Concurrent; | |||||
using System.Collections.Generic; | |||||
namespace JT809.KafkaService | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
/// <typeparam name="T"></typeparam> | |||||
public abstract class JT809Producer<T> : JT809ProducerBase<T> | |||||
{ | |||||
private bool _disposed = false; | |||||
protected virtual IProducer<string, T> CreateProducer() | |||||
{ | |||||
ProducerBuilder<string, T> producerBuilder = new ProducerBuilder<string, T>(ProducerConfig); | |||||
return producerBuilder.Build(); | |||||
} | |||||
protected override IProducer<string, T> Producer { get; } | |||||
protected JT809Producer( | |||||
IOptions<JT809ProducerConfig> producerConfigAccessor) | |||||
: base(producerConfigAccessor.Value) | |||||
{ | |||||
Producer = CreateProducer(); | |||||
} | |||||
public override void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
protected virtual void Dispose(bool disposing) | |||||
{ | |||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Producer.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | |||||
public override async void ProduceAsync(string msgId, string vno_color, T data) | |||||
{ | |||||
if (_disposed) return; | |||||
await Producer.ProduceAsync(ProducerConfig.TopicName, new Message<string, T> | |||||
{ | |||||
Key = msgId, | |||||
Value = data | |||||
}); | |||||
} | |||||
~JT809Producer() | |||||
{ | |||||
Dispose(false); | |||||
} | |||||
} | |||||
} |
@@ -1,23 +0,0 @@ | |||||
using Confluent.Kafka; | |||||
using JT809.KafkaService.Configs; | |||||
using JT809.PubSub.Abstractions; | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.KafkaService | |||||
{ | |||||
public abstract class JT809ProducerBase<T> : IJT809ProducerOfT<T> | |||||
{ | |||||
protected JT809ProducerBase(IOptions<JT809ProducerConfig> config) | |||||
{ | |||||
ProducerConfig = config.Value; | |||||
} | |||||
public JT809ProducerConfig ProducerConfig { get;} | |||||
protected abstract IProducer<string, T> Producer { get;} | |||||
public abstract void Dispose(); | |||||
public abstract void ProduceAsync(string msgId, string vno_color, T data); | |||||
} | |||||
} |
@@ -4,13 +4,57 @@ using JT809.GrpcProtos; | |||||
using JT809.KafkaService.Configs; | using JT809.KafkaService.Configs; | ||||
using JT809.PubSub.Abstractions; | using JT809.PubSub.Abstractions; | ||||
using Microsoft.Extensions.Options; | using Microsoft.Extensions.Options; | ||||
using System; | |||||
namespace JT809.KafkaService | namespace JT809.KafkaService | ||||
{ | { | ||||
public sealed class JT809_GpsPositio_Producer : JT809Producer<JT809GpsPosition> | public sealed class JT809_GpsPositio_Producer : IJT809Producer | ||||
{ | { | ||||
public JT809_GpsPositio_Producer(IOptions<JT809ProducerConfig> producerConfigAccessor) : base( producerConfigAccessor) | private readonly JT809ProducerConfig JT809ProducerConfig; | ||||
private IProducer<string, byte[]> Producer; | |||||
private bool _disposed = false; | |||||
public JT809_GpsPositio_Producer(IOptions<JT809ProducerConfig> producerConfigAccessor) | |||||
{ | |||||
JT809ProducerConfig = producerConfigAccessor.Value; | |||||
ProducerBuilder<string, byte[]> producerBuilder = new ProducerBuilder<string, byte[]>(producerConfigAccessor.Value); | |||||
Producer = producerBuilder.Build(); | |||||
TopicName = JT809ProducerConfig.TopicName; | |||||
} | |||||
public string TopicName { get; } | |||||
public void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
void Dispose(bool disposing) | |||||
{ | |||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Producer.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | |||||
public async void ProduceAsync(string msgId, string vno_color, byte[] data) | |||||
{ | |||||
if (_disposed) return; | |||||
await Producer.ProduceAsync(JT809ProducerConfig.TopicName, new Message<string, byte[]> | |||||
{ | |||||
Key = msgId, | |||||
Value = data | |||||
}); | |||||
} | |||||
~JT809_GpsPositio_Producer() | |||||
{ | { | ||||
Dispose(false); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -12,10 +12,97 @@ using System.Threading.Tasks; | |||||
namespace JT809.KafkaService | namespace JT809.KafkaService | ||||
{ | { | ||||
public sealed class JT809_GpsPosition_Consumer : JT809Consumer<JT809GpsPosition> | public sealed class JT809_GpsPosition_Consumer : IJT809Consumer | ||||
{ | { | ||||
public JT809_GpsPosition_Consumer(IOptions<JT809ConsumerConfig> consumerConfigAccessor, ILoggerFactory loggerFactory) : base( consumerConfigAccessor, loggerFactory) | private bool _disposed = false; | ||||
public CancellationTokenSource Cts { get; } = new CancellationTokenSource(); | |||||
private ILogger logger { get; } | |||||
public string TopicName { get; } | |||||
private IConsumer<string, byte[]> Consumer; | |||||
private readonly JT809ConsumerConfig JT809ConsumerConfig; | |||||
public JT809_GpsPosition_Consumer( | |||||
IOptions<JT809ConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger("JT809_GpsPosition_Consumer"); | |||||
JT809ConsumerConfig = consumerConfigAccessor.Value; | |||||
TopicName = JT809ConsumerConfig.TopicName; | |||||
ConsumerBuilder<string, byte[]> consumerBuilder = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value); | |||||
consumerBuilder.SetErrorHandler((consumer, error) => | |||||
{ | |||||
logger.LogError(error.Reason); | |||||
}); | |||||
Consumer = consumerBuilder.Build(); | |||||
} | |||||
public void OnMessage(Action<(string MsgId, byte[] Data)> callback) | |||||
{ | |||||
Task.Run(() => | |||||
{ | |||||
while (!Cts.IsCancellationRequested) | |||||
{ | |||||
try | |||||
{ | |||||
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据 | |||||
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据 | |||||
//consumers[n].Assign(topicPartitionList[n]); | |||||
var data = Consumer.Consume(Cts.Token); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} Data:{string.Join("", data.Message.Value)} TopicPartitionOffset:{data.TopicPartitionOffset}"); | |||||
} | |||||
callback((data.Message.Key, data.Message.Value)); | |||||
} | |||||
catch (ConsumeException ex) | |||||
{ | |||||
logger.LogError(ex, JT809ConsumerConfig.TopicName); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex, JT809ConsumerConfig.TopicName); | |||||
} | |||||
} | |||||
}, Cts.Token); | |||||
} | |||||
public void Subscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
//仅有一个分区才需要订阅 | |||||
Consumer.Subscribe(JT809ConsumerConfig.TopicName); | |||||
} | |||||
public void Unsubscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
Consumer.Unsubscribe(); | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
~JT809_GpsPosition_Consumer() | |||||
{ | |||||
Dispose(false); | |||||
} | |||||
void Dispose(bool disposing) | |||||
{ | { | ||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Cts.Cancel(); | |||||
Consumer.Close(); | |||||
Consumer.Dispose(); | |||||
Cts.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -12,11 +12,97 @@ using System.Threading.Tasks; | |||||
namespace JT809.KafkaService | namespace JT809.KafkaService | ||||
{ | { | ||||
public sealed class JT809_Same_Consumer : JT809Consumer<byte[]> | public sealed class JT809_Same_Consumer : IJT809Consumer | ||||
{ | { | ||||
public JT809_Same_Consumer(IOptions<JT809ConsumerConfig> consumerConfigAccessor, ILoggerFactory loggerFactory) | private bool _disposed = false; | ||||
: base(consumerConfigAccessor, loggerFactory) | public CancellationTokenSource Cts { get; } = new CancellationTokenSource(); | ||||
private ILogger logger { get; } | |||||
public string TopicName { get; } | |||||
private IConsumer<string, byte[]> Consumer; | |||||
private readonly JT809SameConsumerConfig JT809ConsumerConfig; | |||||
public JT809_Same_Consumer( | |||||
IOptions<JT809SameConsumerConfig> consumerConfigAccessor, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
logger = loggerFactory.CreateLogger("JT809_Same_Consumer"); | |||||
JT809ConsumerConfig = consumerConfigAccessor.Value; | |||||
TopicName = JT809ConsumerConfig.TopicName; | |||||
ConsumerBuilder<string, byte[]> consumerBuilder = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value); | |||||
consumerBuilder.SetErrorHandler((consumer, error) => | |||||
{ | |||||
logger.LogError(error.Reason); | |||||
}); | |||||
Consumer = consumerBuilder.Build(); | |||||
} | |||||
public void OnMessage(Action<(string MsgId, byte[] Data)> callback) | |||||
{ | |||||
Task.Run(() => | |||||
{ | |||||
while (!Cts.IsCancellationRequested) | |||||
{ | |||||
try | |||||
{ | |||||
//如果不指定分区,根据kafka的机制会从多个分区中拉取数据 | |||||
//如果指定分区,根据kafka的机制会从相应的分区中拉取数据 | |||||
//consumers[n].Assign(topicPartitionList[n]); | |||||
var data = Consumer.Consume(Cts.Token); | |||||
if (logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} Data:{string.Join("", data.Message.Value)} TopicPartitionOffset:{data.TopicPartitionOffset}"); | |||||
} | |||||
callback((data.Message.Key, data.Message.Value)); | |||||
} | |||||
catch (ConsumeException ex) | |||||
{ | |||||
logger.LogError(ex, JT809ConsumerConfig.TopicName); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
logger.LogError(ex, JT809ConsumerConfig.TopicName); | |||||
} | |||||
} | |||||
}, Cts.Token); | |||||
} | |||||
public void Subscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
//仅有一个分区才需要订阅 | |||||
Consumer.Subscribe(JT809ConsumerConfig.TopicName); | |||||
} | |||||
public void Unsubscribe() | |||||
{ | |||||
if (_disposed) return; | |||||
Consumer.Unsubscribe(); | |||||
} | |||||
public void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
~JT809_Same_Consumer() | |||||
{ | |||||
Dispose(false); | |||||
} | |||||
void Dispose(bool disposing) | |||||
{ | { | ||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Cts.Cancel(); | |||||
Consumer.Close(); | |||||
Consumer.Dispose(); | |||||
Cts.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -8,11 +8,53 @@ using Microsoft.Extensions.Options; | |||||
namespace JT809.KafkaService | namespace JT809.KafkaService | ||||
{ | { | ||||
public sealed class JT809_Same_Producer : JT809Producer<byte[]> | public sealed class JT809_Same_Producer : IJT809Producer | ||||
{ | { | ||||
public JT809_Same_Producer(IOptions<JT809ProducerConfig> producerConfigAccessor) | private readonly JT809SameProducerConfig JT809SameProducerConfig; | ||||
: base(producerConfigAccessor) | private IProducer<string, byte[]> Producer; | ||||
private bool _disposed = false; | |||||
public JT809_Same_Producer(IOptions<JT809SameProducerConfig> producerConfigAccessor) | |||||
{ | |||||
JT809SameProducerConfig = producerConfigAccessor.Value; | |||||
ProducerBuilder<string, byte[]> producerBuilder = new ProducerBuilder<string,byte[]>(producerConfigAccessor.Value); | |||||
Producer= producerBuilder.Build(); | |||||
TopicName = JT809SameProducerConfig.Value.TopicName; | |||||
} | |||||
public string TopicName { get; } | |||||
public void Dispose() | |||||
{ | |||||
Dispose(true); | |||||
GC.SuppressFinalize(true); | |||||
} | |||||
void Dispose(bool disposing) | |||||
{ | |||||
if (_disposed) return; | |||||
if (disposing) | |||||
{ | |||||
Producer.Dispose(); | |||||
} | |||||
_disposed = true; | |||||
} | |||||
public async void ProduceAsync(string msgId, string vno_color, byte[] data) | |||||
{ | |||||
if (_disposed) return; | |||||
await Producer.ProduceAsync(JT809SameProducerConfig.TopicName, new Message<string, byte[]> | |||||
{ | |||||
Key = msgId, | |||||
Value = data | |||||
}); | |||||
} | |||||
~JT809_Same_Producer() | |||||
{ | { | ||||
Dispose(false); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -4,6 +4,8 @@ using Microsoft.Extensions.DependencyInjection; | |||||
using JT809.Protocol.Enums; | using JT809.Protocol.Enums; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using System.Threading; | using System.Threading; | ||||
using Google.Protobuf; | |||||
using JT809.GrpcProtos; | |||||
namespace JT809.KafkaServiceTest | namespace JT809.KafkaServiceTest | ||||
{ | { | ||||
@@ -16,9 +18,10 @@ namespace JT809.KafkaServiceTest | |||||
consumerTestService.GpsConsumer.OnMessage((Message)=> | consumerTestService.GpsConsumer.OnMessage((Message)=> | ||||
{ | { | ||||
Assert.Equal(JT809SubBusinessType.实时上传车辆定位信息.ToValueString(), Message.MsgId); | Assert.Equal(JT809SubBusinessType.实时上传车辆定位信息.ToValueString(), Message.MsgId); | ||||
Assert.Equal("粤A23456", Message.Data.Vno); | JT809GpsPosition jT809GpsPosition = JT809GpsPosition.Parser.ParseFrom(Message.Data); | ||||
Assert.Equal(2, Message.Data.VColor); | Assert.Equal("粤A23456", jT809GpsPosition.Vno); | ||||
Assert.Equal("smallchi", Message.Data.FromChannel); | Assert.Equal(2, jT809GpsPosition.VColor); | ||||
Assert.Equal("smallchi", jT809GpsPosition.FromChannel); | |||||
}); | }); | ||||
consumerTestService.GpsConsumer.Subscribe(); | consumerTestService.GpsConsumer.Subscribe(); | ||||
@@ -9,9 +9,9 @@ namespace JT809.KafkaServiceTest | |||||
{ | { | ||||
public class ConsumerTestService | public class ConsumerTestService | ||||
{ | { | ||||
public IJT808ConsumerOfT<byte[]> SameConsumer { get; } | public JT809_Same_Consumer SameConsumer { get; } | ||||
public IJT808ConsumerOfT<JT809GpsPosition> GpsConsumer { get; } | public JT809_GpsPosition_Consumer GpsConsumer { get; } | ||||
public ConsumerTestService(IJT808ConsumerOfT<byte[]> sameConsumer, IJT808ConsumerOfT<JT809GpsPosition> gpsConsumer) | public ConsumerTestService(JT809_Same_Consumer sameConsumer, JT809_GpsPosition_Consumer gpsConsumer) | ||||
{ | { | ||||
SameConsumer = sameConsumer; | SameConsumer = sameConsumer; | ||||
GpsConsumer = gpsConsumer; | GpsConsumer = gpsConsumer; | ||||
@@ -3,6 +3,7 @@ using Xunit; | |||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using JT809.Protocol.Enums; | using JT809.Protocol.Enums; | ||||
using JT809.Protocol.Extensions; | using JT809.Protocol.Extensions; | ||||
using Google.Protobuf; | |||||
namespace JT809.KafkaServiceTest | namespace JT809.KafkaServiceTest | ||||
{ | { | ||||
@@ -12,19 +13,21 @@ namespace JT809.KafkaServiceTest | |||||
public void Test1() | public void Test1() | ||||
{ | { | ||||
ProducerTestService producerTestService = ServiceProvider.GetRequiredService<ProducerTestService>(); | ProducerTestService producerTestService = ServiceProvider.GetRequiredService<ProducerTestService>(); | ||||
producerTestService.GpsProducer.ProduceAsync(JT809SubBusinessType.实时上传车辆定位信息.ToValueString(), "粤A23456_2", new GrpcProtos.JT809GpsPosition | producerTestService.GpsProducer.ProduceAsync(JT809SubBusinessType.实时上传车辆定位信息.ToValueString(), "粤A23456_2", | ||||
{ | new GrpcProtos.JT809GpsPosition | ||||
Vno= "粤A23456", | { | ||||
VColor=2, | Vno = "粤A23456", | ||||
GpsTime= (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000, | VColor = 2, | ||||
FromChannel="smallchi" | GpsTime = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000, | ||||
}); | FromChannel = "smallchi" | ||||
}.ToByteArray()); | |||||
} | } | ||||
[Fact] | [Fact] | ||||
public void Test2() | public void Test2() | ||||
{ | { | ||||
ProducerTestService producerTestService = ServiceProvider.GetRequiredService<ProducerTestService>(); | ProducerTestService producerTestService = ServiceProvider.GetRequiredService<ProducerTestService>(); | ||||
producerTestService.SameProducer.ProduceAsync(JT809SubBusinessType.None.ToValueString(), "粤A23457_2", new byte[] { 0x01, 0x02, 0x03 }); | producerTestService.SameProducer.ProduceAsync(JT809SubBusinessType.None.ToValueString(), "粤A23457_2", new byte[] { 0x01, 0x02, 0x03 }); | ||||
} | } | ||||
} | } | ||||
@@ -9,9 +9,9 @@ namespace JT809.KafkaServiceTest | |||||
{ | { | ||||
public class ProducerTestService | public class ProducerTestService | ||||
{ | { | ||||
public IJT809ProducerOfT<byte[]> SameProducer { get; } | public JT809_Same_Producer SameProducer { get; } | ||||
public IJT809ProducerOfT<JT809GpsPosition> GpsProducer { get; } | public JT809_GpsPositio_Producer GpsProducer { get; } | ||||
public ProducerTestService(IJT809ProducerOfT<byte[]> sameProducer, IJT809ProducerOfT<JT809GpsPosition> gpsProducer) | public ProducerTestService(JT809_Same_Producer sameProducer, JT809_GpsPositio_Producer gpsProducer) | ||||
{ | { | ||||
SameProducer = sameProducer; | SameProducer = sameProducer; | ||||
GpsProducer = gpsProducer; | GpsProducer = gpsProducer; | ||||
@@ -5,13 +5,9 @@ using System.Threading; | |||||
namespace JT809.PubSub.Abstractions | namespace JT809.PubSub.Abstractions | ||||
{ | { | ||||
public interface IJT809Consumer : IJT809PubSub, IJT808ConsumerOfT<byte[]> | public interface IJT809Consumer : IJT809PubSub | ||||
{ | { | ||||
void OnMessage(Action<(string MsgId, byte[] Data)> callback); | |||||
} | |||||
public interface IJT808ConsumerOfT<T> :IDisposable | |||||
{ | |||||
void OnMessage(Action<(string MsgId, T Data)> callback); | |||||
CancellationTokenSource Cts { get; } | CancellationTokenSource Cts { get; } | ||||
void Subscribe(); | void Subscribe(); | ||||
void Unsubscribe(); | void Unsubscribe(); | ||||
@@ -3,12 +3,7 @@ using System.Threading.Tasks; | |||||
namespace JT809.PubSub.Abstractions | namespace JT809.PubSub.Abstractions | ||||
{ | { | ||||
public interface IJT809Producer: IJT809PubSub, IJT809ProducerOfT<byte[]> | public interface IJT809Producer: IJT809PubSub, IDisposable | ||||
{ | |||||
} | |||||
public interface IJT809ProducerOfT<T>: IDisposable | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// | /// | ||||
@@ -16,6 +11,6 @@ namespace JT809.PubSub.Abstractions | |||||
/// <param name="msgId">消息Id</param> | /// <param name="msgId">消息Id</param> | ||||
/// <param name="vno_color">车牌号+车牌颜色</param> | /// <param name="vno_color">车牌号+车牌颜色</param> | ||||
/// <param name="data">hex data</param> | /// <param name="data">hex data</param> | ||||
void ProduceAsync(string msgId, string vno_color, T data); | void ProduceAsync(string msgId, string vno_color, byte[] data); | ||||
} | } | ||||
} | } |
@@ -1,17 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.PubSub.Abstractions | |||||
{ | |||||
/// <summary> | |||||
/// jt809生产者分区工厂 | |||||
/// 分区策略: | |||||
/// 1.可以根据(车牌号+颜色)进行分区 | |||||
/// 2.可以根据msgId(消息Id)+(车牌号+颜色)进行分区 | |||||
/// </summary> | |||||
public interface IJT809ProducerPartitionFactory | |||||
{ | |||||
int CreatePartition(string topicName, string msgId, string vno_color); | |||||
} | |||||
} |
@@ -1,35 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Security.Cryptography; | |||||
namespace JT809.PubSub.Abstractions | |||||
{ | |||||
public class JT809HashAlgorithm | |||||
{ | |||||
/// <summary> | |||||
/// 使用Ketama | |||||
/// </summary> | |||||
/// <param name="digest"></param> | |||||
/// <param name="nTime"></param> | |||||
/// <returns></returns> | |||||
public static long Hash(byte[] digest, int nTime=1) | |||||
{ | |||||
long rv = ((long)(digest[3 + nTime * 4] & 0xFF) << 24) | |||||
| ((long)(digest[2 + nTime * 4] & 0xFF) << 16) | |||||
| ((long)(digest[1 + nTime * 4] & 0xFF) << 8) | |||||
| ((long)digest[0 + nTime * 4] & 0xFF); | |||||
return rv & 0xffffffffL; | |||||
} | |||||
public static byte[] ComputeMd5(string key) | |||||
{ | |||||
using (MD5 md5 = new MD5CryptoServiceProvider()) | |||||
{ | |||||
byte[] keyBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); | |||||
md5.Clear(); | |||||
return keyBytes; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,16 +0,0 @@ | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.PubSub.Abstractions | |||||
{ | |||||
public class JT809PartitionOptions:IOptions<JT809PartitionOptions> | |||||
{ | |||||
public int Partition { get; set; } = 1; | |||||
public JT809PartitionOptions Value => this; | |||||
public List<int> AssignPartitions { get; set; } | |||||
} | |||||
} |
@@ -1,14 +0,0 @@ | |||||
using Microsoft.Extensions.Options; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace JT809.PubSub.Abstractions | |||||
{ | |||||
public class JT809TopicOptions:IOptions<JT809TopicOptions> | |||||
{ | |||||
public string TopicName { get; set; } = JT809Constants.JT809TopicName; | |||||
public JT809TopicOptions Value => this; | |||||
} | |||||
} |
@@ -1,7 +1,9 @@ | |||||
using JT809.DotNetty.Core.Handlers; | using Google.Protobuf; | ||||
using JT809.DotNetty.Core.Handlers; | |||||
using JT809.DotNetty.Core.Interfaces; | using JT809.DotNetty.Core.Interfaces; | ||||
using JT809.DotNetty.Core.Metadata; | using JT809.DotNetty.Core.Metadata; | ||||
using JT809.GrpcProtos; | using JT809.GrpcProtos; | ||||
using JT809.KafkaService; | |||||
using JT809.Protocol; | using JT809.Protocol; | ||||
using JT809.Protocol.SubMessageBody; | using JT809.Protocol.SubMessageBody; | ||||
using JT809.PubSub.Abstractions; | using JT809.PubSub.Abstractions; | ||||
@@ -16,11 +18,11 @@ namespace JT809.Superior.Server | |||||
{ | { | ||||
public sealed class JT809SuperiorMsgIdReceiveHandler : JT809SuperiorMsgIdReceiveHandlerBase | public sealed class JT809SuperiorMsgIdReceiveHandler : JT809SuperiorMsgIdReceiveHandlerBase | ||||
{ | { | ||||
private readonly IJT809ProducerOfT<JT809GpsPosition> producer; | private readonly JT809_GpsPositio_Producer producer; | ||||
private readonly JT809GpsOptions gpsOptions; | private readonly JT809GpsOptions gpsOptions; | ||||
public JT809SuperiorMsgIdReceiveHandler( | public JT809SuperiorMsgIdReceiveHandler( | ||||
IOptions<JT809GpsOptions>jt809GpsAccessor, | IOptions<JT809GpsOptions>jt809GpsAccessor, | ||||
IJT809ProducerOfT<JT809GpsPosition> producer, | JT809_GpsPositio_Producer producer, | ||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
IJT809SubordinateLoginService jT809SubordinateLoginService, | IJT809SubordinateLoginService jT809SubordinateLoginService, | ||||
IJT809VerifyCodeGenerator verifyCodeGenerator) | IJT809VerifyCodeGenerator verifyCodeGenerator) | ||||
@@ -55,7 +57,7 @@ namespace JT809.Superior.Server | |||||
gpsBodies.VehiclePosition.Minute, | gpsBodies.VehiclePosition.Minute, | ||||
gpsBodies.VehiclePosition.Second).ToUniversalTime().Ticks - 621355968000000000) / 10000000; | gpsBodies.VehiclePosition.Second).ToUniversalTime().Ticks - 621355968000000000) / 10000000; | ||||
gpsPosition.FromChannel = gpsOptions.FromChannel; | gpsPosition.FromChannel = gpsOptions.FromChannel; | ||||
producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition); | producer.ProduceAsync($"{0x1202}", $"{exchangeMessageBodies.VehicleNo}{exchangeMessageBodies.VehicleColor}", gpsPosition.ToByteArray()); | ||||
return base.Msg0x1200_0x1202(request); | return base.Msg0x1200_0x1202(request); | ||||
} | } | ||||
} | } | ||||
@@ -40,8 +40,7 @@ namespace JT809.Superior.Server | |||||
options.TcpPort = 808; | options.TcpPort = 808; | ||||
}); | }); | ||||
services.Configure<JT809GpsOptions>(hostContext.Configuration.GetSection("JT809GpsOptions")); | services.Configure<JT809GpsOptions>(hostContext.Configuration.GetSection("JT809GpsOptions")); | ||||
#warning AddJT809KafkaProducerPartitionsService | services.AddJT809KafkaProducerService(hostContext.Configuration); | ||||
//services.AddJT809KafkaProducerPartitionsService(hostContext.Configuration,options=> options.Partition=10); | |||||
services.Replace(new ServiceDescriptor(typeof(JT809SuperiorMsgIdReceiveHandlerBase), typeof(JT809SuperiorMsgIdReceiveHandler), ServiceLifetime.Singleton)); | services.Replace(new ServiceDescriptor(typeof(JT809SuperiorMsgIdReceiveHandlerBase), typeof(JT809SuperiorMsgIdReceiveHandler), ServiceLifetime.Singleton)); | ||||
}); | }); | ||||
@@ -1,5 +1,6 @@ | |||||
using JT809.DotNetty.Core; | using JT809.DotNetty.Core; | ||||
using JT809.DotNetty.Core.Configurations; | using JT809.DotNetty.Core.Configurations; | ||||
using JT809.Protocol; | |||||
using JT809.Protocol.Configs; | using JT809.Protocol.Configs; | ||||
using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
@@ -14,15 +15,6 @@ namespace JT809.DotNetty.Host.Test | |||||
{ | { | ||||
static async Task Main(string[] args) | static async Task Main(string[] args) | ||||
{ | { | ||||
#warning JT809.Protocol.JT809GlobalConfig.Instance | |||||
//JT809.Protocol.JT809GlobalConfig.Instance | |||||
// .SetHeaderOptions(new JT809HeaderOptions | |||||
// { | |||||
// MsgGNSSCENTERID = 20141013, | |||||
// Version = new JT809.Protocol.JT809Header_Version(1, 0, 0), | |||||
// EncryptKey = 9595 | |||||
// }); | |||||
//主链路登录请求消息 | //主链路登录请求消息 | ||||
//5B00000048000000851001013353D5010000000000270F0133530D32303134303831333132372E302E302E3100000000000000000000000000000000000000000000001FA3275F5D | //5B00000048000000851001013353D5010000000000270F0133530D32303134303831333132372E302E302E3100000000000000000000000000000000000000000000001FA3275F5D | ||||
//主链路注销请求消息 | //主链路注销请求消息 | ||||
@@ -45,6 +37,12 @@ namespace JT809.DotNetty.Host.Test | |||||
{ | { | ||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | services.AddSingleton<ILoggerFactory, LoggerFactory>(); | ||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | ||||
services.AddSingleton(new JT809HeaderOptions | |||||
{ | |||||
MsgGNSSCENTERID = 20141013, | |||||
Version = new JT809Header_Version(1, 0, 0), | |||||
EncryptKey = 9595 | |||||
}); | |||||
services.AddJT809Core(hostContext.Configuration) | services.AddJT809Core(hostContext.Configuration) | ||||
.AddJT809SuperiorPlatform(options:options=> { | .AddJT809SuperiorPlatform(options:options=> { | ||||
options.TcpPort = 839; | options.TcpPort = 839; | ||||