Ejemplo n.º 1
0
        void SaveMessage(Publish message, string clientId, PendingMessageStatus status)
        {
            if (message.QualityOfService == MqttQualityOfService.AtMostOnce)
            {
                return;
            }

            var session = sessionRepository.Get(s => s.ClientId == clientId);

            if (session == null)
            {
                throw new MqttException(string.Format(Properties.Resources.SessionRepository_ClientSessionNotFound, clientId));
            }

            var savedMessage = new PendingMessage {
                Status           = status,
                QualityOfService = message.QualityOfService,
                Duplicated       = message.Duplicated,
                Retain           = message.Retain,
                Topic            = message.Topic,
                PacketId         = message.PacketId,
                Payload          = message.Payload
            };

            session.AddPendingMessage(savedMessage);

            sessionRepository.Update(session);
        }
Ejemplo n.º 2
0
        public async Task SendPublishAsync(string clientId, Publish message, IMqttChannel <IPacket> channel, PendingMessageStatus status = PendingMessageStatus.PendingToSend)
        {
            if (channel == null || !channel.IsConnected)
            {
                SaveMessage(message, clientId, PendingMessageStatus.PendingToSend);
                return;
            }

            var qos = configuration.GetSupportedQos(message.QualityOfService);

            if (qos != MqttQualityOfService.AtMostOnce && status == PendingMessageStatus.PendingToSend)
            {
                SaveMessage(message, clientId, PendingMessageStatus.PendingToAcknowledge);
            }

            await channel.SendAsync(message)
            .ConfigureAwait(continueOnCapturedContext: false);

            if (qos == MqttQualityOfService.AtLeastOnce)
            {
                await MonitorAckAsync <PublishAck> (message, clientId, channel)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
            else if (qos == MqttQualityOfService.ExactlyOnce)
            {
                await MonitorAckAsync <PublishReceived> (message, clientId, channel).ConfigureAwait(continueOnCapturedContext: false);

                await channel
                .ReceiverStream
                .ObserveOn(NewThreadScheduler.Default)
                .OfType <PublishComplete> ()
                .FirstOrDefaultAsync(x => x.PacketId == message.PacketId.Value);
            }
        }
Ejemplo n.º 3
0
        public async Task SendAckAsync(string clientId, IFlowPacket ack, IMqttChannel <IPacket> channel, PendingMessageStatus status = PendingMessageStatus.PendingToSend)
        {
            if ((ack.Type == MqttPacketType.PublishReceived || ack.Type == MqttPacketType.PublishRelease) &&
                status == PendingMessageStatus.PendingToSend)
            {
                SavePendingAcknowledgement(ack, clientId);
            }

            if (!channel.IsConnected)
            {
                return;
            }

            await channel.SendAsync(ack)
            .ConfigureAwait(continueOnCapturedContext: false);

            if (ack.Type == MqttPacketType.PublishReceived)
            {
                await MonitorAckAsync <PublishRelease> (ack, clientId, channel)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
            else if (ack.Type == MqttPacketType.PublishRelease)
            {
                await MonitorAckAsync <PublishComplete> (ack, clientId, channel)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
        }