Exemplo n.º 1
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);
            }
        }
        async Task SendPendingAcknowledgementsAsync(ClientSession session, IMqttChannel <IPacket> channel)
        {
            foreach (PendingAcknowledgement pendingAcknowledgement in session.GetPendingAcknowledgements())
            {
                IFlowPacket ack = default;

                if (pendingAcknowledgement.Type == MqttPacketType.PublishReceived)
                {
                    ack = new PublishReceived(pendingAcknowledgement.PacketId);
                }
                else if (pendingAcknowledgement.Type == MqttPacketType.PublishRelease)
                {
                    ack = new PublishRelease(pendingAcknowledgement.PacketId);
                }

                await _senderFlow.SendAckAsync(session.Id, ack, channel);
            }
        }
        public override async Task ExecuteAsync(string clientId, IPacket input, IMqttChannel <IPacket> channel)
        {
            if (!_senderRules.TryGetValue(input.Type, out Func <string, ushort, IFlowPacket> senderRule))
            {
                return;
            }

            if (!(input is IFlowPacket flowPacket))
            {
                return;
            }

            IFlowPacket ackPacket = senderRule(clientId, flowPacket.PacketId);

            if (ackPacket != default(IFlowPacket))
            {
                await SendAckAsync(clientId, ackPacket, channel);
            }
        }
Exemplo n.º 4
0
        protected async Task MonitorAckAsync <T> (IFlowPacket sentMessage, string clientId, IMqttChannel <IPacket> channel)
            where T : IFlowPacket
        {
            var intervalSubscription = Observable
                                       .Interval(TimeSpan.FromSeconds(configuration.WaitTimeoutSecs), NewThreadScheduler.Default)
                                       .Subscribe(async _ => {
                if (channel.IsConnected)
                {
                    tracer.Warn(Properties.Resources.PublishFlow_RetryingQoSFlow, sentMessage.Type, clientId);

                    await channel.SendAsync(sentMessage);
                }
            });

            await channel
            .ReceiverStream
            .ObserveOn(NewThreadScheduler.Default)
            .OfType <T> ()
            .FirstOrDefaultAsync(x => x.PacketId == sentMessage.PacketId);

            intervalSubscription.Dispose();
        }
Exemplo n.º 5
0
        void SavePendingAcknowledgement(IFlowPacket ack, string clientId)
        {
            if (ack.Type != MqttPacketType.PublishReceived && ack.Type != MqttPacketType.PublishRelease)
            {
                return;
            }

            var unacknowledgeMessage = new PendingAcknowledgement {
                PacketId = ack.PacketId,
                Type     = ack.Type
            };

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

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

            session.AddPendingAcknowledgement(unacknowledgeMessage);

            sessionRepository.Update(session);
        }
        void SavePendingAcknowledgement(IFlowPacket ack, string clientId)
        {
            if (ack.Type != MqttPacketType.PublishReceived && ack.Type != MqttPacketType.PublishRelease)
            {
                return;
            }

            PendingAcknowledgement unacknowledgeMessage = new PendingAcknowledgement
            {
                PacketId = ack.PacketId,
                Type     = ack.Type
            };

            ClientSession session = sessionRepository.Read(clientId);

            if (session == null)
            {
                throw new MqttException(ClientProperties.SessionRepository_ClientSessionNotFound(clientId));
            }

            session.AddPendingAcknowledgement(unacknowledgeMessage);

            sessionRepository.Update(session);
        }