示例#1
0
        public async Task <SubscribeResult> Subscribe(MqttSubscribePacket subscribePacket)
        {
            if (subscribePacket == null)
            {
                throw new ArgumentNullException(nameof(subscribePacket));
            }

            var retainedApplicationMessages = await _retainedMessagesManager.GetMessagesAsync().ConfigureAwait(false);

            var result = new SubscribeResult();

            // The topic filters are order by its QoS so that the higher QoS will win over a
            // lower one.
            foreach (var originalTopicFilter in subscribePacket.TopicFilters.OrderByDescending(f => f.QualityOfServiceLevel))
            {
                var interceptorContext = await InterceptSubscribe(originalTopicFilter).ConfigureAwait(false);

                var finalTopicFilter   = interceptorContext?.TopicFilter ?? originalTopicFilter;
                var acceptSubscription = interceptorContext?.AcceptSubscription ?? true;
                var closeConnection    = interceptorContext?.CloseConnection ?? false;

                if (string.IsNullOrEmpty(finalTopicFilter.Topic) || !acceptSubscription)
                {
                    result.ReturnCodes.Add(MqttSubscribeReturnCode.Failure);
                    result.ReasonCodes.Add(MqttSubscribeReasonCode.UnspecifiedError);
                }
                else
                {
                    result.ReturnCodes.Add(ConvertToSubscribeReturnCode(finalTopicFilter.QualityOfServiceLevel));
                    result.ReasonCodes.Add(ConvertToSubscribeReasonCode(finalTopicFilter.QualityOfServiceLevel));
                }

                if (closeConnection)
                {
                    result.CloseConnection = true;
                }

                if (!acceptSubscription || string.IsNullOrEmpty(finalTopicFilter.Topic))
                {
                    continue;
                }

                var subscription = CreateSubscription(finalTopicFilter, subscribePacket);

                await _eventDispatcher.SafeNotifyClientSubscribedTopicAsync(_clientSession.ClientId, finalTopicFilter).ConfigureAwait(false);

                FilterRetainedApplicationMessages(retainedApplicationMessages, subscription, result);
            }

            return(result);
        }
示例#2
0
        static void FilterRetainedApplicationMessages(IList <MqttApplicationMessage> retainedApplicationMessages, Subscription subscription, SubscribeResult subscribeResult)
        {
            for (var i = retainedApplicationMessages.Count - 1; i >= 0; i--)
            {
                var retainedApplicationMessage = retainedApplicationMessages[i];
                if (retainedApplicationMessage == null)
                {
                    continue;
                }

                if (subscription.RetainHandling == MqttRetainHandling.DoNotSendOnSubscribe)
                {
                    // This is a MQTT V5+ feature.
                    continue;
                }

                if (subscription.RetainHandling == MqttRetainHandling.SendAtSubscribeIfNewSubscriptionOnly && !subscription.IsNewSubscription)
                {
                    // This is a MQTT V5+ feature.
                    continue;
                }

                if (!MqttTopicFilterComparer.IsMatch(retainedApplicationMessage.Topic, subscription.Topic))
                {
                    continue;
                }

                var queuedApplicationMessage = new MqttQueuedApplicationMessage
                {
                    ApplicationMessage = retainedApplicationMessage,
                    IsRetainedMessage  = true,
                    SubscriptionQualityOfServiceLevel = subscription.QualityOfServiceLevel
                };

                if (subscription.Identifier > 0)
                {
                    queuedApplicationMessage.SubscriptionIdentifiers = new List <uint> {
                        subscription.Identifier
                    };
                }

                subscribeResult.RetainedApplicationMessages.Add(queuedApplicationMessage);

                retainedApplicationMessages[i] = null;
            }
        }