예제 #1
0
        public async Task DispatchApplicationMessageAsync(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
        {
            try
            {
                var interceptorContext = new MqttApplicationMessageInterceptorContext
                {
                    ApplicationMessage = applicationMessage
                };

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

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

                var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession?.ClientId, applicationMessage);
                ApplicationMessageReceived?.Invoke(this, eventArgs);
            }
            catch (Exception exception)
            {
                _logger.LogError(new EventId(), exception, "Error while processing application message");
            }

            lock (_sessions)
            {
                foreach (var clientSession in _sessions.Values.ToList())
                {
                    clientSession.EnqueuePublishPacket(applicationMessage.ToPublishPacket());
                }
            }
        }
예제 #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
        public void Publish(IEnumerable <MqttApplicationMessage> applicationMessages)
        {
            if (applicationMessages == null)
            {
                throw new ArgumentNullException(nameof(applicationMessages));
            }

            if (_cancellationTokenSource == null)
            {
                throw new InvalidOperationException("The server is not started.");
            }

            foreach (var applicationMessage in applicationMessages)
            {
                var interceptorContext = new MqttApplicationMessageInterceptorContext
                {
                    ApplicationMessage = applicationMessage
                };

                _options.ApplicationMessageInterceptor?.Invoke(interceptorContext);

                _clientSessionsManager.DispatchApplicationMessage(null, interceptorContext.ApplicationMessage);
            }
        }