Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

103 rader
3.3 KiB

  1. using Confluent.Kafka;
  2. using JT808.DotNetty.Abstractions;
  3. using Microsoft.Extensions.Logging;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace JT808.DotNetty.Kafka
  11. {
  12. public sealed class JT808MsgReplyConsumer : IJT808MsgReplyConsumer
  13. {
  14. private bool disposed = false;
  15. public CancellationTokenSource Cts { get; private set; } = new CancellationTokenSource();
  16. private readonly IConsumer<string, byte[]> consumer;
  17. private readonly ILogger logger;
  18. public string TopicName { get; }
  19. public JT808MsgReplyConsumer(
  20. IOptions<JT808MsgReplyConsumerConfig> consumerConfigAccessor,
  21. ILoggerFactory loggerFactory)
  22. {
  23. consumer = new ConsumerBuilder<string, byte[]>(consumerConfigAccessor.Value).Build();
  24. TopicName = consumerConfigAccessor.Value.TopicName;
  25. logger = loggerFactory.CreateLogger("JT808MsgReplyConsumer");
  26. }
  27. public void OnMessage(Action<(string TerminalNo, byte[] Data)> callback)
  28. {
  29. Task.Run(() =>
  30. {
  31. while (!Cts.IsCancellationRequested)
  32. {
  33. if (disposed) return;
  34. try
  35. {
  36. //如果不指定分区,根据kafka的机制会从多个分区中拉取数据
  37. //如果指定分区,根据kafka的机制会从相应的分区中拉取数据
  38. var data = consumer.Consume(Cts.Token);
  39. if (logger.IsEnabled(LogLevel.Debug))
  40. {
  41. logger.LogDebug($"Topic: {data.Topic} Key: {data.Message.Key} Partition: {data.Partition} Offset: {data.Offset} TopicPartitionOffset:{data.TopicPartitionOffset}");
  42. }
  43. callback((data.Message.Key, data.Message.Value));
  44. }
  45. catch (ConsumeException ex)
  46. {
  47. logger.LogError(ex, TopicName);
  48. }
  49. catch (OperationCanceledException ex)
  50. {
  51. logger.LogError(ex, TopicName);
  52. }
  53. catch (Exception ex)
  54. {
  55. logger.LogError(ex, TopicName);
  56. }
  57. }
  58. }, Cts.Token);
  59. }
  60. public void Subscribe()
  61. {
  62. consumer.Subscribe(TopicName);
  63. }
  64. public void Unsubscribe()
  65. {
  66. if (disposed) return;
  67. consumer.Unsubscribe();
  68. Cts.Cancel();
  69. }
  70. private void Dispose(bool disposing)
  71. {
  72. if (disposed) return;
  73. if (disposing)
  74. {
  75. consumer.Close();
  76. consumer.Dispose();
  77. Cts.Dispose();
  78. }
  79. disposed = true;
  80. }
  81. ~JT808MsgReplyConsumer()
  82. {
  83. Dispose(false);
  84. }
  85. public void Dispose()
  86. {
  87. //必须为true
  88. Dispose(true);
  89. //通知垃圾回收机制不再调用终结器(析构器)
  90. GC.SuppressFinalize(this);
  91. }
  92. }
  93. }