Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

102 řádky
3.6 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> _subscriptions = 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 (_subscriptions)
  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. _subscriptions[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 (_subscriptions)
  48. {
  49. foreach (var topicFilter in unsubscribePacket.TopicFilters)
  50. {
  51. _subscriptions.Remove(topicFilter);
  52. }
  53. }
  54. return unsubscribePacket.CreateResponse<MqttUnsubAckPacket>();
  55. }
  56. public CheckSubscriptionsResult CheckSubscriptions(MqttPublishPacket publishPacket)
  57. {
  58. if (publishPacket == null) throw new ArgumentNullException(nameof(publishPacket));
  59. lock (_subscriptions)
  60. {
  61. foreach (var subscription in _subscriptions)
  62. {
  63. if (!MqttTopicFilterComparer.IsMatch(publishPacket.Topic, subscription.Key))
  64. {
  65. continue;
  66. }
  67. var effectiveQos = subscription.Value;
  68. if (publishPacket.QualityOfServiceLevel < effectiveQos)
  69. {
  70. effectiveQos = publishPacket.QualityOfServiceLevel;
  71. }
  72. return new CheckSubscriptionsResult
  73. {
  74. IsSubscribed = true,
  75. QualityOfServiceLevel = effectiveQos
  76. };
  77. }
  78. }
  79. return new CheckSubscriptionsResult
  80. {
  81. IsSubscribed = false
  82. };
  83. }
  84. }
  85. }