async Task <MqttPacket> InterceptPacketAsync(MqttPacket packet, CancellationToken cancellationToken) { if (!_eventContainer.InterceptingOutboundPacketEvent.HasHandlers) { return(packet); } var interceptingPacketEventArgs = new InterceptingPacketEventArgs { ClientId = Id, Endpoint = Endpoint, Packet = packet, CancellationToken = cancellationToken }; await _eventContainer.InterceptingOutboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false); if (!interceptingPacketEventArgs.ProcessPacket || packet == null) { return(null); } return(interceptingPacketEventArgs.Packet); }
async Task ReceivePackagesLoop(CancellationToken cancellationToken) { try { // We do not listen for the cancellation token here because the internal buffer might still // contain data to be read even if the TCP connection was already dropped. So we rely on an // own exception in the reading loop! while (!cancellationToken.IsCancellationRequested) { var packet = await ChannelAdapter.ReceivePacketAsync(cancellationToken).ConfigureAwait(false); if (packet == null) { return; } var processPacket = true; if (_eventContainer.InterceptingInboundPacketEvent.HasHandlers) { var interceptingPacketEventArgs = new InterceptingPacketEventArgs { ClientId = Id, Endpoint = Endpoint, Packet = packet, CancellationToken = cancellationToken }; await _eventContainer.InterceptingInboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false); packet = interceptingPacketEventArgs.Packet; processPacket = interceptingPacketEventArgs.ProcessPacket; } if (!processPacket || packet == null) { // Restart the receiving process to get the next packet ignoring the current one.. continue; } Statistics.HandleReceivedPacket(packet); if (packet is MqttPublishPacket publishPacket) { await HandleIncomingPublishPacket(publishPacket, cancellationToken).ConfigureAwait(false); } else if (packet is MqttPubAckPacket pubAckPacket) { Session.AcknowledgePublishPacket(pubAckPacket.PacketIdentifier); } else if (packet is MqttPubCompPacket pubCompPacket) { Session.AcknowledgePublishPacket(pubCompPacket.PacketIdentifier); } else if (packet is MqttPubRecPacket pubRecPacket) { HandleIncomingPubRecPacket(pubRecPacket); } else if (packet is MqttPubRelPacket pubRelPacket) { HandleIncomingPubRelPacket(pubRelPacket); } else if (packet is MqttSubscribePacket subscribePacket) { await HandleIncomingSubscribePacket(subscribePacket, cancellationToken).ConfigureAwait(false); } else if (packet is MqttUnsubscribePacket unsubscribePacket) { await HandleIncomingUnsubscribePacket(unsubscribePacket, cancellationToken).ConfigureAwait(false); } else if (packet is MqttPingReqPacket) { // See: The Server MUST send a PINGRESP packet in response to a PINGREQ packet [MQTT-3.12.4-1]. Session.EnqueueHealthPacket(new MqttPacketBusItem(MqttPingRespPacket.Instance)); } else if (packet is MqttPingRespPacket) { throw new MqttProtocolViolationException("A PINGRESP Packet is sent by the Server to the Client in response to a PINGREQ Packet only."); } else if (packet is MqttDisconnectPacket) { IsCleanDisconnect = true; return; } else { if (!_packetDispatcher.TryDispatch(packet)) { throw new MqttProtocolViolationException($"Received packet '{packet}' at an unexpected time."); } } } } catch (OperationCanceledException) { } catch (Exception exception) { if (exception is MqttCommunicationException) { _logger.Warning(exception, "Client '{0}': Communication exception while receiving client packets.", Id); } else { _logger.Error(exception, "Client '{0}': Error while receiving client packets.", Id); } } }