예제 #1
0
        private Task HandleIncomingPublishPacketAsync(IMqttChannelAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            var applicationMessage = publishPacket.ToApplicationMessage();

            switch (applicationMessage.QualityOfServiceLevel)
            {
            case MqttQualityOfServiceLevel.AtMostOnce:
            {
                return(_sessionsManager.DispatchApplicationMessageAsync(this, applicationMessage));
            }

            case MqttQualityOfServiceLevel.AtLeastOnce:
            {
                return(HandleIncomingPublishPacketWithQoS1(adapter, applicationMessage, publishPacket, cancellationToken));
            }

            case MqttQualityOfServiceLevel.ExactlyOnce:
            {
                return(HandleIncomingPublishPacketWithQoS2(adapter, applicationMessage, publishPacket, cancellationToken));
            }

            default:
            {
                throw new MqttCommunicationException("Received a not supported QoS level.");
            }
            }
        }
예제 #2
0
        private async Task HandleIncomingPublishPacketAsync(IMqttCommunicationAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            var applicationMessage = publishPacket.ToApplicationMessage();

            var interceptorContext = new MqttApplicationMessageInterceptorContext
            {
                ApplicationMessage = applicationMessage
            };

            _options.ApplicationMessageInterceptor?.Invoke(interceptorContext);
            applicationMessage = interceptorContext.ApplicationMessage;

            if (applicationMessage.Retain)
            {
                await _clientRetainedMessageManager.HandleMessageAsync(ClientId, applicationMessage).ConfigureAwait(false);
            }

            switch (applicationMessage.QualityOfServiceLevel)
            {
            case MqttQualityOfServiceLevel.AtMostOnce:
            {
                _sessionsManager.DispatchApplicationMessage(this, applicationMessage);
                return;
            }

            case MqttQualityOfServiceLevel.AtLeastOnce:
            {
                _sessionsManager.DispatchApplicationMessage(this, applicationMessage);

                await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken,
                                               new MqttPubAckPacket { PacketIdentifier = publishPacket.PacketIdentifier });

                return;
            }

            case MqttQualityOfServiceLevel.ExactlyOnce:
            {
                // QoS 2 is implement as method "B" [4.3.3 QoS 2: Exactly once delivery]
                lock (_unacknowledgedPublishPackets)
                {
                    _unacknowledgedPublishPackets.Add(publishPacket.PacketIdentifier);
                }

                _sessionsManager.DispatchApplicationMessage(this, applicationMessage);

                await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken,
                                               new MqttPubRecPacket { PacketIdentifier = publishPacket.PacketIdentifier }).ConfigureAwait(false);

                return;
            }

            default:
                throw new MqttCommunicationException("Received a not supported QoS level.");
            }
        }
예제 #3
0
        private void FireApplicationMessageReceivedEvent(MqttPublishPacket publishPacket)
        {
            if (publishPacket.QualityOfServiceLevel != MqttQualityOfServiceLevel.AtMostOnce)
            {
                _processedPublishPackets.Add(publishPacket.PacketIdentifier);
            }

            var applicationMessage = publishPacket.ToApplicationMessage();

            ApplicationMessageReceived?.Invoke(this, new MqttApplicationMessageReceivedEventArgs(applicationMessage));
        }
예제 #4
0
파일: MqttClient.cs 프로젝트: pangfd/SAEA
 private void FireApplicationMessageReceivedEvent(MqttPublishPacket publishPacket)
 {
     try
     {
         var applicationMessage = publishPacket.ToApplicationMessage();
         ApplicationMessageReceived?.Invoke(this, new MqttMessageReceivedEventArgs(Options.ClientId, applicationMessage));
     }
     catch (Exception exception)
     {
         _logger.Error(exception, "Unhandled exception while handling application message.");
     }
 }
예제 #5
0
 private void FireApplicationMessageReceivedEvent(MqttPublishPacket publishPacket)
 {
     try
     {
         var applicationMessage = publishPacket.ToApplicationMessage();
         ApplicationMessageReceived?.Invoke(this, new MqttApplicationMessageReceivedEventArgs(applicationMessage));
     }
     catch (Exception exception)
     {
         MqttTrace.Error(nameof(MqttClient), exception, "Unhandled exception while handling application message.");
     }
 }
        public void EnqueueApplicationMessage(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
        {
            if (publishPacket == null)
            {
                throw new ArgumentNullException(nameof(publishPacket));
            }

            var checkSubscriptionsResult = _subscriptionsManager.CheckSubscriptions(publishPacket.Topic, publishPacket.QualityOfServiceLevel);

            if (!checkSubscriptionsResult.IsSubscribed)
            {
                return;
            }

            publishPacket = new MqttPublishPacket
            {
                Topic   = publishPacket.Topic,
                Payload = publishPacket.Payload,
                QualityOfServiceLevel = checkSubscriptionsResult.QualityOfServiceLevel,
                Retain = publishPacket.Retain,
                Dup    = false
            };

            if (publishPacket.QualityOfServiceLevel > 0)
            {
                publishPacket.PacketIdentifier = _packetIdentifierProvider.GetNewPacketIdentifier();
            }

            if (_options.ClientMessageQueueInterceptor != null)
            {
                var context = new MqttClientMessageQueueInterceptorContext(
                    senderClientSession?.ClientId,
                    ClientId,
                    publishPacket.ToApplicationMessage());

                _options.ClientMessageQueueInterceptor?.Invoke(context);

                if (!context.AcceptEnqueue || context.ApplicationMessage == null)
                {
                    return;
                }

                publishPacket.Topic   = context.ApplicationMessage.Topic;
                publishPacket.Payload = context.ApplicationMessage.Payload;
                publishPacket.QualityOfServiceLevel = context.ApplicationMessage.QualityOfServiceLevel;
            }

            _pendingPacketsQueue.Enqueue(publishPacket);
        }
예제 #7
0
        private void DispatchPublishPacket(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
        {
            var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession.ClientId, publishPacket.ToApplicationMessage());

            ApplicationMessageReceived?.Invoke(this, eventArgs);

            foreach (var clientSession in _clientSessions.Values.ToList())
            {
                clientSession.EnqueuePublishPacket(senderClientSession, publishPacket);
            }
        }
예제 #8
0
        public void DispatchPublishPacket(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
        {
            try
            {
                var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession?.ClientId, publishPacket.ToApplicationMessage());
                ApplicationMessageReceived?.Invoke(this, eventArgs);
            }
            catch (Exception exception)
            {
                MqttTrace.Error(nameof(MqttClientSessionsManager), exception, "Error while processing application message");
            }

            lock (_syncRoot)
            {
                foreach (var clientSession in _clientSessions.Values.ToList())
                {
                    clientSession.EnqueuePublishPacket(publishPacket);
                }
            }
        }