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); }
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); }
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()); }
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); } }
public void EnqueueHealthPacket(MqttPacketBusItem packetBusItem) { _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Health); }
public void EnqueueControlPacket(MqttPacketBusItem packetBusItem) { _packetBus.EnqueueItem(packetBusItem, MqttPacketBusPartition.Control); }
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(); } }