Пример #1
0
        public void EnqueueDataPacket(MqttPacketBusItem packetBusItem)
        {
            if (_packetBus.ItemsCount(MqttPacketBusPartition.Data) >= _serverOptions.MaxPendingMessagesPerClient)
            {
                if (_serverOptions.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropNewMessage)
                {
                    return;
                }

                if (_serverOptions.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage)
                {
                    // Only drop from the data partition. Dropping from control partition might break the connection
                    // because the client does not receive PINGREQ packets etc. any longer.
                    _packetBus.DropFirstItem(MqttPacketBusPartition.Data);
                }
            }

            var publishPacket = (MqttPublishPacket)packetBusItem.Packet;

            if (publishPacket.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
            {
                _unacknowledgedPublishPackets[publishPacket.PacketIdentifier] = publishPacket;
            }

            _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Data);
        }
Пример #2
0
        public void Await_Single_Packet()
        {
            var bus = new MqttPacketBus();

            var delivered = false;

            var item1 = new MqttPacketBusItem(new MqttPublishPacket());
            var item2 = new MqttPacketBusItem(new MqttPublishPacket());

            var item3 = new MqttPacketBusItem(new MqttPublishPacket());

            item3.Delivered += (_, __) =>
            {
                delivered = true;
            };

            bus.EnqueueItem(item1, MqttPacketBusPartition.Data);
            bus.EnqueueItem(item2, MqttPacketBusPartition.Data);
            bus.EnqueueItem(item3, MqttPacketBusPartition.Data);

            Assert.IsFalse(delivered);

            bus.DequeueItemAsync(CancellationToken.None).Result.MarkAsDelivered();

            Assert.IsFalse(delivered);

            bus.DequeueItemAsync(CancellationToken.None).Result.MarkAsDelivered();

            Assert.IsFalse(delivered);

            bus.DequeueItemAsync(CancellationToken.None).Result.MarkAsDelivered();

            // The third packet has the event attached.
            Assert.IsTrue(delivered);
        }
Пример #3
0
        public Task DeliverApplicationMessageAsync(MqttApplicationMessage applicationMessage)
        {
            if (applicationMessage == null)
            {
                throw new ArgumentNullException(nameof(applicationMessage));
            }

            var publishPacketFactory = new MqttPublishPacketFactory();
            var packetBusItem        = new MqttPacketBusItem(publishPacketFactory.Create(applicationMessage));

            _session.EnqueuePacket(packetBusItem);

            return(packetBusItem.WaitForDeliveryAsync());
        }
Пример #4
0
        public void EnqueuePacket(MqttPacketBusItem packetBusItem)
        {
            if (packetBusItem == null)
            {
                throw new ArgumentNullException(nameof(packetBusItem));
            }

            if (_packetBus.ItemsCount >= _serverOptions.MaxPendingMessagesPerClient)
            {
                if (_serverOptions.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropNewMessage)
                {
                    return;
                }

                if (_serverOptions.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage)
                {
                    // Only drop from the data partition. Dropping from control partition might break the connection
                    // because the client does not receive PINGREQ packets etc. any longer.
                    _packetBus.DropFirstItem(MqttPacketBusPartition.Data);
                }
            }

            if (packetBusItem.Packet is MqttPublishPacket publishPacket)
            {
                if (publishPacket.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
                {
                    _unacknowledgedPublishPackets[publishPacket.PacketIdentifier] = publishPacket;
                }

                _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Data);
            }
            else if (packetBusItem.Packet is MqttPingReqPacket || packetBusItem.Packet is MqttPingRespPacket)
            {
                _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Health);
            }
            else
            {
                _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Control);
            }
        }
Пример #5
0
 public void EnqueueHealthPacket(MqttPacketBusItem packetBusItem)
 {
     _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Health);
 }
Пример #6
0
 public void EnqueueControlPacket(MqttPacketBusItem packetBusItem)
 {
     _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Control);
 }
Пример #7
0
        async Task SendPacketsLoop(CancellationToken cancellationToken)
        {
            MqttPacketBusItem packetBusItem = null;

            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    packetBusItem = await Session.DequeuePacketAsync(cancellationToken).ConfigureAwait(false);

                    // Also check the cancellation token here because the dequeue is blocking and may take some time.
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    try
                    {
                        await SendPacketAsync(packetBusItem.Packet, cancellationToken).ConfigureAwait(false);

                        packetBusItem.MarkAsDelivered();
                    }
                    catch (OperationCanceledException)
                    {
                        packetBusItem.MarkAsCancelled();
                    }
                    catch (Exception exception)
                    {
                        packetBusItem.MarkAsFailed(exception);
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception exception)
            {
                if (exception is MqttCommunicationTimedOutException)
                {
                    _logger.Warning(exception, "Client '{0}': Sending publish packet failed: Timeout.", Id);
                }
                else if (exception is MqttCommunicationException)
                {
                    _logger.Warning(exception, "Client '{0}': Sending publish packet failed: Communication exception.", Id);
                }
                else
                {
                    _logger.Error(exception, "Client '{0}': Sending publish packet failed.", Id);
                }

                if (packetBusItem?.Packet is MqttPublishPacket publishPacket)
                {
                    if (publishPacket.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
                    {
                        publishPacket.Dup = true;
                        Session.EnqueueDataPacket(new MqttPacketBusItem(publishPacket));
                    }
                }

                StopInternal();
            }
        }