Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

111 linhas
4.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using MQTTnet.Core.Diagnostics;
  6. using MQTTnet.Core.Packets;
  7. namespace MQTTnet.Core.Server
  8. {
  9. public sealed class MqttClientRetainedMessagesManager
  10. {
  11. private readonly Dictionary<string, MqttApplicationMessage> _retainedMessages = new Dictionary<string, MqttApplicationMessage>();
  12. private readonly MqttNetTrace _trace;
  13. private readonly MqttServerOptions _options;
  14. public MqttClientRetainedMessagesManager(MqttServerOptions options, MqttNetTrace trace)
  15. {
  16. _trace = trace ?? throw new ArgumentNullException(nameof(trace));
  17. _options = options ?? throw new ArgumentNullException(nameof(options));
  18. }
  19. public async Task LoadMessagesAsync()
  20. {
  21. if (_options.Storage == null)
  22. {
  23. return;
  24. }
  25. try
  26. {
  27. var retainedMessages = await _options.Storage.LoadRetainedMessagesAsync();
  28. lock (_retainedMessages)
  29. {
  30. _retainedMessages.Clear();
  31. foreach (var retainedMessage in retainedMessages)
  32. {
  33. _retainedMessages[retainedMessage.Topic] = retainedMessage;
  34. }
  35. }
  36. }
  37. catch (Exception exception)
  38. {
  39. _trace.Error(nameof(MqttClientRetainedMessagesManager), exception, "Unhandled exception while loading retained messages.");
  40. }
  41. }
  42. public async Task HandleMessageAsync(string clientId, MqttApplicationMessage applicationMessage)
  43. {
  44. if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
  45. List<MqttApplicationMessage> allRetainedMessages;
  46. lock (_retainedMessages)
  47. {
  48. if (applicationMessage.Payload?.Any() == false)
  49. {
  50. _retainedMessages.Remove(applicationMessage.Topic);
  51. _trace.Information(nameof(MqttClientRetainedMessagesManager), "Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
  52. }
  53. else
  54. {
  55. _retainedMessages[applicationMessage.Topic] = applicationMessage;
  56. _trace.Information(nameof(MqttClientRetainedMessagesManager), "Client '{0}' updated retained message for topic '{1}'.", clientId, applicationMessage.Topic);
  57. }
  58. allRetainedMessages = new List<MqttApplicationMessage>(_retainedMessages.Values);
  59. }
  60. try
  61. {
  62. // ReSharper disable once UseNullPropagation
  63. if (_options.Storage != null)
  64. {
  65. await _options.Storage.SaveRetainedMessagesAsync(allRetainedMessages);
  66. }
  67. }
  68. catch (Exception exception)
  69. {
  70. _trace.Error(nameof(MqttClientRetainedMessagesManager), exception, "Unhandled exception while saving retained messages.");
  71. }
  72. }
  73. public List<MqttApplicationMessage> GetMessages(MqttSubscribePacket subscribePacket)
  74. {
  75. var retainedMessages = new List<MqttApplicationMessage>();
  76. lock (_retainedMessages)
  77. {
  78. foreach (var retainedMessage in _retainedMessages.Values)
  79. {
  80. foreach (var topicFilter in subscribePacket.TopicFilters)
  81. {
  82. if (retainedMessage.QualityOfServiceLevel < topicFilter.QualityOfServiceLevel)
  83. {
  84. continue;
  85. }
  86. if (!MqttTopicFilterComparer.IsMatch(retainedMessage.Topic, topicFilter.Topic))
  87. {
  88. continue;
  89. }
  90. retainedMessages.Add(retainedMessage);
  91. break;
  92. }
  93. }
  94. }
  95. return retainedMessages;
  96. }
  97. }
  98. }