Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

94 строки
3.3 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using Microsoft.Extensions.Options;
  4. using MQTTnet.Core.Packets;
  5. using MQTTnet.Core.Protocol;
  6. namespace MQTTnet.Core.Server
  7. {
  8. public sealed class MqttClientSubscriptionsManager
  9. {
  10. private readonly Dictionary<string, MqttQualityOfServiceLevel> _subscribedTopics = new Dictionary<string, MqttQualityOfServiceLevel>();
  11. private readonly MqttServerOptions _options;
  12. public MqttClientSubscriptionsManager(IOptions<MqttServerOptions> options)
  13. {
  14. _options = options?.Value ?? throw new ArgumentNullException(nameof(options));
  15. }
  16. public MqttClientSubscribeResult Subscribe(MqttSubscribePacket subscribePacket, string clientId)
  17. {
  18. if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
  19. var responsePacket = subscribePacket.CreateResponse<MqttSubAckPacket>();
  20. var closeConnection = false;
  21. lock (_subscribedTopics)
  22. {
  23. foreach (var topicFilter in subscribePacket.TopicFilters)
  24. {
  25. var interceptorContext = new MqttSubscriptionInterceptorContext(clientId, topicFilter);
  26. _options.SubscriptionsInterceptor?.Invoke(interceptorContext);
  27. responsePacket.SubscribeReturnCodes.Add(interceptorContext.AcceptSubscription ? MqttSubscribeReturnCode.SuccessMaximumQoS1 : MqttSubscribeReturnCode.Failure);
  28. if (interceptorContext.CloseConnection)
  29. {
  30. closeConnection = true;
  31. }
  32. if (interceptorContext.AcceptSubscription)
  33. {
  34. _subscribedTopics[topicFilter.Topic] = topicFilter.QualityOfServiceLevel;
  35. }
  36. }
  37. }
  38. return new MqttClientSubscribeResult
  39. {
  40. ResponsePacket = responsePacket,
  41. CloseConnection = closeConnection
  42. };
  43. }
  44. public MqttUnsubAckPacket Unsubscribe(MqttUnsubscribePacket unsubscribePacket)
  45. {
  46. if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
  47. lock (_subscribedTopics)
  48. {
  49. foreach (var topicFilter in unsubscribePacket.TopicFilters)
  50. {
  51. _subscribedTopics.Remove(topicFilter);
  52. }
  53. }
  54. return unsubscribePacket.CreateResponse<MqttUnsubAckPacket>();
  55. }
  56. public bool IsSubscribed(MqttPublishPacket publishPacket)
  57. {
  58. if (publishPacket == null) throw new ArgumentNullException(nameof(publishPacket));
  59. lock (_subscribedTopics)
  60. {
  61. foreach (var subscribedTopic in _subscribedTopics)
  62. {
  63. if (publishPacket.QualityOfServiceLevel > subscribedTopic.Value)
  64. {
  65. continue;
  66. }
  67. if (!MqttTopicFilterComparer.IsMatch(publishPacket.Topic, subscribedTopic.Key))
  68. {
  69. continue;
  70. }
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. }
  77. }