public async Task DispatchApplicationMessageAsync(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage) { try { var interceptorContext = new MqttApplicationMessageInterceptorContext { ApplicationMessage = applicationMessage }; _options.ApplicationMessageInterceptor?.Invoke(interceptorContext); applicationMessage = interceptorContext.ApplicationMessage; if (applicationMessage.Retain) { await _clientRetainedMessageManager.HandleMessageAsync(senderClientSession?.ClientId, applicationMessage).ConfigureAwait(false); } var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession?.ClientId, applicationMessage); ApplicationMessageReceived?.Invoke(this, eventArgs); } catch (Exception exception) { _logger.LogError(new EventId(), exception, "Error while processing application message"); } lock (_sessions) { foreach (var clientSession in _sessions.Values.ToList()) { clientSession.EnqueuePublishPacket(applicationMessage.ToPublishPacket()); } } }
private async Task HandleIncomingPublishPacketAsync(IMqttCommunicationAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken) { var applicationMessage = publishPacket.ToApplicationMessage(); var interceptorContext = new MqttApplicationMessageInterceptorContext { ApplicationMessage = applicationMessage }; _options.ApplicationMessageInterceptor?.Invoke(interceptorContext); applicationMessage = interceptorContext.ApplicationMessage; if (applicationMessage.Retain) { await _clientRetainedMessageManager.HandleMessageAsync(ClientId, applicationMessage).ConfigureAwait(false); } switch (applicationMessage.QualityOfServiceLevel) { case MqttQualityOfServiceLevel.AtMostOnce: { _sessionsManager.DispatchApplicationMessage(this, applicationMessage); return; } case MqttQualityOfServiceLevel.AtLeastOnce: { _sessionsManager.DispatchApplicationMessage(this, applicationMessage); await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPubAckPacket { PacketIdentifier = publishPacket.PacketIdentifier }); return; } case MqttQualityOfServiceLevel.ExactlyOnce: { // QoS 2 is implement as method "B" [4.3.3 QoS 2: Exactly once delivery] lock (_unacknowledgedPublishPackets) { _unacknowledgedPublishPackets.Add(publishPacket.PacketIdentifier); } _sessionsManager.DispatchApplicationMessage(this, applicationMessage); await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPubRecPacket { PacketIdentifier = publishPacket.PacketIdentifier }).ConfigureAwait(false); return; } default: throw new MqttCommunicationException("Received a not supported QoS level."); } }
public void Publish(IEnumerable <MqttApplicationMessage> applicationMessages) { if (applicationMessages == null) { throw new ArgumentNullException(nameof(applicationMessages)); } if (_cancellationTokenSource == null) { throw new InvalidOperationException("The server is not started."); } foreach (var applicationMessage in applicationMessages) { var interceptorContext = new MqttApplicationMessageInterceptorContext { ApplicationMessage = applicationMessage }; _options.ApplicationMessageInterceptor?.Invoke(interceptorContext); _clientSessionsManager.DispatchApplicationMessage(null, interceptorContext.ApplicationMessage); } }