private async Task DisconnectInternalAsync() { var cts = _cancellationTokenSource; if (cts == null || cts.IsCancellationRequested) { return; } cts.Cancel(false); cts.Dispose(); _cancellationTokenSource = null; try { await _adapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false); MqttTrace.Information(nameof(MqttClient), "Disconnected from adapter."); } catch (Exception exception) { MqttTrace.Warning(nameof(MqttClient), exception, "Error while disconnecting from adapter."); } finally { Disconnected?.Invoke(this, EventArgs.Empty); } }
private async Task TrySendPendingPublishPacketAsync(MqttClientPublishPacketContext publishPacketContext) { try { if (_adapter == null) { return; } publishPacketContext.PublishPacket.Dup = publishPacketContext.SendTries > 0; await _adapter.SendPacketAsync(publishPacketContext.PublishPacket, _options.DefaultCommunicationTimeout); publishPacketContext.IsSent = true; } catch (MqttCommunicationException exception) { MqttTrace.Warning(nameof(MqttClientMessageQueue), exception, "Sending publish packet failed."); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClientMessageQueue), exception, "Sending publish packet failed."); } finally { publishPacketContext.SendTries++; } }
private async Task ReceivePackets(CancellationToken cancellationToken) { MqttTrace.Information(nameof(MqttClient), "Start receiving packets."); try { while (!cancellationToken.IsCancellationRequested) { var mqttPacket = await _adapter.ReceivePacketAsync(TimeSpan.Zero); MqttTrace.Information(nameof(MqttClient), $"Received <<< {mqttPacket}"); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(() => ProcessReceivedPacketAsync(mqttPacket), cancellationToken); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } } catch (MqttCommunicationException exception) { MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication error while receiving packets."); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Error while receiving packets."); } finally { MqttTrace.Information(nameof(MqttClient), "Stopped receiving packets."); await DisconnectInternalAsync(); } }
public async Task <MqttBasePacket> ReceivePacketAsync(TimeSpan timeout) { MqttBasePacket packet; if (timeout > TimeSpan.Zero) { var workerTask = _serializer.DeserializeAsync(_channel); var timeoutTask = Task.Delay(timeout); var hasTimeout = Task.WhenAny(timeoutTask, workerTask) == timeoutTask; if (hasTimeout) { throw new MqttCommunicationTimedOutException(); } packet = workerTask.Result; } else { packet = await _serializer.DeserializeAsync(_channel); } if (packet == null) { throw new MqttProtocolViolationException("Received malformed packet."); } MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), $"RX <<< {packet}"); return(packet); }
private Task ProcessReceivedPacketAsync(MqttBasePacket mqttPacket) { try { if (mqttPacket is MqttPingReqPacket) { return(SendAsync(new MqttPingRespPacket())); } if (mqttPacket is MqttDisconnectPacket) { return(DisconnectAsync()); } var publishPacket = mqttPacket as MqttPublishPacket; if (publishPacket != null) { return(ProcessReceivedPublishPacket(publishPacket)); } var pubRelPacket = mqttPacket as MqttPubRelPacket; if (pubRelPacket != null) { return(ProcessReceivedPubRelPacket(pubRelPacket)); } _packetDispatcher.Dispatch(mqttPacket); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Error while processing received packet."); } return(Task.FromResult(0)); }
private async Task SendKeepAliveMessagesAsync(CancellationToken cancellationToken) { MqttTrace.Information(nameof(MqttClient), "Start sending keep alive packets."); try { while (!cancellationToken.IsCancellationRequested) { await Task.Delay(_options.KeepAlivePeriod, cancellationToken); await SendAndReceiveAsync <MqttPingRespPacket>(new MqttPingReqPacket()); } } catch (MqttCommunicationException exception) { MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication error while receiving packets."); } catch (Exception exception) { MqttTrace.Warning(nameof(MqttClient), exception, "Error while sending/receiving keep alive packets."); } finally { MqttTrace.Information(nameof(MqttClient), "Stopped sending keep alive packets."); await DisconnectInternalAsync(); } }
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs) { MqttTrace.Information(nameof(MqttServer), $"Client '{eventArgs.Identifier}': Connected."); ClientConnected?.Invoke(this, eventArgs); Task.Run(() => _clientSessionsManager.RunClientSessionAsync(eventArgs), _cancellationTokenSource.Token); }
private async Task ReceivePackets(CancellationToken cancellationToken) { MqttTrace.Information(nameof(MqttClient), "Start receiving packets."); try { while (!cancellationToken.IsCancellationRequested) { var mqttPacket = await _adapter.ReceivePacketAsync(TimeSpan.Zero); MqttTrace.Information(nameof(MqttClient), $"Received <<< {mqttPacket}"); Task.Run(() => ProcessReceivedPacket(mqttPacket), cancellationToken).Forget(); } } catch (MqttCommunicationException exception) { MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication error while receiving packets."); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Error while receiving packets."); } finally { MqttTrace.Information(nameof(MqttClient), "Stopped receiving packets."); await DisconnectInternalAsync(); } }
public void Stop() { _cancellationTokenSource?.Cancel(); _cancellationTokenSource = null; _adapter.ClientConnected -= OnClientConnected; _adapter.Stop(); _clientSessionsManager.Clear(); MqttTrace.Information(nameof(MqttServer), "Stopped."); }
private void AcceptDefaultEndpointConnectionsAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { try { var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(args.Socket), new MqttV311PacketSerializer()); ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(args.Socket.Information.RemoteAddress.ToString(), clientAdapter)); } catch (Exception exception) { MqttTrace.Error(nameof(MqttServerAdapter), exception, "Error while acceping connection at default endpoint."); } }
private Task HandleIncomingPacketAsync(MqttBasePacket packet) { var subscribePacket = packet as MqttSubscribePacket; if (subscribePacket != null) { return(_adapter.SendPacketAsync(_subscriptionsManager.Subscribe(subscribePacket), _options.DefaultCommunicationTimeout)); } var unsubscribePacket = packet as MqttUnsubscribePacket; if (unsubscribePacket != null) { return(_adapter.SendPacketAsync(_subscriptionsManager.Unsubscribe(unsubscribePacket), _options.DefaultCommunicationTimeout)); } var publishPacket = packet as MqttPublishPacket; if (publishPacket != null) { return(HandleIncomingPublishPacketAsync(publishPacket)); } var pubRelPacket = packet as MqttPubRelPacket; if (pubRelPacket != null) { return(HandleIncomingPubRelPacketAsync(pubRelPacket)); } var pubAckPacket = packet as MqttPubAckPacket; if (pubAckPacket != null) { return(HandleIncomingPubAckPacketAsync(pubAckPacket)); } if (packet is MqttPingReqPacket) { return(_adapter.SendPacketAsync(new MqttPingRespPacket(), _options.DefaultCommunicationTimeout)); } if (packet is MqttDisconnectPacket || packet is MqttConnectPacket) { _cancellationTokenSource.Cancel(); return(Task.FromResult((object)null)); } MqttTrace.Warning(nameof(MqttClientSession), $"Client '{_identifier}': Received not supported packet ({packet}). Closing connection."); _cancellationTokenSource.Cancel(); return(Task.FromResult((object)null)); }
private void FireApplicationMessageReceivedEvent(MqttPublishPacket publishPacket) { try { var applicationMessage = publishPacket.ToApplicationMessage(); ApplicationMessageReceived?.Invoke(this, new MqttApplicationMessageReceivedEventArgs(applicationMessage)); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Unhandled exception while handling application message."); } }
public async Task ConnectAsync(MqttApplicationMessage willApplicationMessage = null) { MqttTrace.Verbose(nameof(MqttClient), "Trying to connect."); if (IsConnected) { throw new MqttProtocolViolationException("It is not allowed to connect with a server after the connection is established."); } var connectPacket = new MqttConnectPacket { ClientId = _options.ClientId, Username = _options.UserName, Password = _options.Password, CleanSession = _options.CleanSession, KeepAlivePeriod = (ushort)_options.KeepAlivePeriod.TotalSeconds, WillMessage = willApplicationMessage }; await _adapter.ConnectAsync(_options, _options.DefaultCommunicationTimeout); MqttTrace.Verbose(nameof(MqttClient), "Connection with server established."); _cancellationTokenSource = new CancellationTokenSource(); _latestPacketIdentifier = 0; _processedPublishPackets.Clear(); _packetDispatcher.Reset(); IsConnected = true; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(() => ReceivePackets(_cancellationTokenSource.Token), _cancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed var response = await SendAndReceiveAsync <MqttConnAckPacket>(connectPacket); if (response.ConnectReturnCode != MqttConnectReturnCode.ConnectionAccepted) { await DisconnectAsync(); throw new MqttConnectingFailedException(response.ConnectReturnCode); } if (_options.KeepAlivePeriod != TimeSpan.Zero) { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(() => SendKeepAliveMessagesAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } Connected?.Invoke(this, EventArgs.Empty); }
public void Start() { if (_cancellationTokenSource != null) { throw new InvalidOperationException("The MQTT server is already started."); } _cancellationTokenSource = new CancellationTokenSource(); _adapter.ClientConnected += OnClientConnected; _adapter.Start(_options); MqttTrace.Information(nameof(MqttServer), "Started."); }
public async Task ConnectAsync(MqttApplicationMessage willApplicationMessage = null) { ThrowIfConnected("It is not allowed to connect with a server after the connection is established."); try { _cancellationTokenSource = new CancellationTokenSource(); _latestPacketIdentifier = 0; _packetDispatcher.Reset(); MqttTrace.Verbose(nameof(MqttClient), "Trying to connect with server."); await _adapter.ConnectAsync(_options.DefaultCommunicationTimeout, _options).ConfigureAwait(false); MqttTrace.Verbose(nameof(MqttClient), "Connection with server established."); StartReceivePackets(_cancellationTokenSource.Token); var connectPacket = new MqttConnectPacket { ClientId = _options.ClientId, Username = _options.UserName, Password = _options.Password, CleanSession = _options.CleanSession, KeepAlivePeriod = (ushort)_options.KeepAlivePeriod.TotalSeconds, WillMessage = willApplicationMessage }; var response = await SendAndReceiveAsync <MqttConnAckPacket>(connectPacket).ConfigureAwait(false); if (response.ConnectReturnCode != MqttConnectReturnCode.ConnectionAccepted) { throw new MqttConnectingFailedException(response.ConnectReturnCode); } MqttTrace.Verbose(nameof(MqttClient), "MQTT connection with server established."); if (_options.KeepAlivePeriod != TimeSpan.Zero) { StartSendKeepAliveMessages(_cancellationTokenSource.Token); } Connected?.Invoke(this, EventArgs.Empty); } catch (Exception) { await DisconnectInternalAsync().ConfigureAwait(false); throw; } }
private Task HandleIncomingPacketAsync(MqttBasePacket packet) { if (packet is MqttSubscribePacket subscribePacket) { return(Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Subscribe(subscribePacket))); } if (packet is MqttUnsubscribePacket unsubscribePacket) { return(Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Unsubscribe(unsubscribePacket))); } if (packet is MqttPublishPacket publishPacket) { return(HandleIncomingPublishPacketAsync(publishPacket)); } if (packet is MqttPubRelPacket pubRelPacket) { return(HandleIncomingPubRelPacketAsync(pubRelPacket)); } if (packet is MqttPubRecPacket pubRecPacket) { return(Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, pubRecPacket.CreateResponse <MqttPubRelPacket>())); } if (packet is MqttPubAckPacket || packet is MqttPubCompPacket) { // Discard message. return(Task.FromResult((object)null)); } if (packet is MqttPingReqPacket) { return(Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPingRespPacket())); } if (packet is MqttDisconnectPacket || packet is MqttConnectPacket) { _cancellationTokenSource.Cancel(); return(Task.FromResult((object)null)); } MqttTrace.Warning(nameof(MqttClientSession), "Client '{0}': Received not supported packet ({1}). Closing connection.", _identifier, packet); _cancellationTokenSource.Cancel(); return(Task.FromResult((object)null)); }
public void EnqueuePublishPacket(MqttPublishPacket publishPacket) { if (publishPacket == null) { throw new ArgumentNullException(nameof(publishPacket)); } if (!_subscriptionsManager.IsSubscribed(publishPacket)) { return; } _messageQueue.Enqueue(publishPacket); MqttTrace.Verbose(nameof(MqttClientSession), "Client '{0}': Enqueued pending publish packet.", _identifier); }
public void Stop() { _cancellationTokenSource?.Cancel(false); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; foreach (var adapter in _adapters) { adapter.ClientConnected -= OnClientConnected; adapter.Stop(); } _clientSessionsManager.Clear(); MqttTrace.Information(nameof(MqttServer), "Stopped."); }
private async Task AcceptDefaultEndpointConnectionsAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null); var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, null), new DefaultMqttV311PacketSerializer()); ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); } catch (Exception exception) when(!(exception is ObjectDisposedException)) { MqttTrace.Error(nameof(MqttServerAdapter), exception, "Error while acceping connection at default endpoint."); } } }
public async Task <MqttBasePacket> ReceivePacketAsync(TimeSpan timeout, CancellationToken cancellationToken) { try { ReceivedMqttPacket receivedMqttPacket; if (timeout > TimeSpan.Zero) { receivedMqttPacket = await ReceiveAsync(_channel.RawReceiveStream, cancellationToken).TimeoutAfter(timeout).ConfigureAwait(false); } else { receivedMqttPacket = await ReceiveAsync(_channel.ReceiveStream, cancellationToken).ConfigureAwait(false); } if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } var packet = PacketSerializer.Deserialize(receivedMqttPacket); if (packet == null) { throw new MqttProtocolViolationException("Received malformed packet."); } MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), "RX <<< {0}", packet); return(packet); } catch (TaskCanceledException) { throw; } catch (MqttCommunicationTimedOutException) { throw; } catch (MqttCommunicationException) { throw; } catch (Exception exception) { throw new MqttCommunicationException(exception); } }
public async Task RunAsync(string identifier, MqttApplicationMessage willApplicationMessage, IMqttCommunicationAdapter adapter) { if (adapter == null) { throw new ArgumentNullException(nameof(adapter)); } _willApplicationMessage = willApplicationMessage; try { _identifier = identifier; Adapter = adapter; _cancellationTokenSource = new CancellationTokenSource(); _messageQueue.Start(adapter); while (!_cancellationTokenSource.IsCancellationRequested) { var packet = await adapter.ReceivePacketAsync(TimeSpan.Zero, _cancellationTokenSource.Token).ConfigureAwait(false); await HandleIncomingPacketAsync(packet).ConfigureAwait(false); } } catch (MqttCommunicationException) { } catch (Exception exception) { MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", _identifier); } finally { if (willApplicationMessage != null) { _publishPacketReceivedCallback(this, _willApplicationMessage.ToPublishPacket()); } _messageQueue.Stop(); _cancellationTokenSource.Cancel(); Adapter = null; MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", _identifier); } }
public async Task SendPacketsAsync(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable <MqttBasePacket> packets) { try { lock (_channel) { foreach (var packet in packets) { MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), "TX >>> {0} [Timeout={1}]", packet, timeout); var writeBuffer = PacketSerializer.Serialize(packet); _sendTask = _sendTask.ContinueWith(p => _channel.SendStream.WriteAsync(writeBuffer, 0, writeBuffer.Length, cancellationToken).ConfigureAwait(false), cancellationToken); } } await _sendTask; // configure await false generates stackoverflow if (timeout > TimeSpan.Zero) { await _channel.SendStream.FlushAsync(cancellationToken).TimeoutAfter(timeout).ConfigureAwait(false); } else { await _channel.SendStream.FlushAsync(cancellationToken).ConfigureAwait(false); } } catch (TaskCanceledException) { throw; } catch (MqttCommunicationTimedOutException) { throw; } catch (MqttCommunicationException) { throw; } catch (Exception exception) { throw new MqttCommunicationException(exception); } }
public async Task RunClientSessionAsync(MqttClientConnectedEventArgs eventArgs) { try { if (!(await eventArgs.ClientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false) is MqttConnectPacket connectPacket)) { throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1]."); } // Switch to the required protocol version before sending any response. eventArgs.ClientAdapter.PacketSerializer.ProtocolVersion = connectPacket.ProtocolVersion; var connectReturnCode = ValidateConnection(connectPacket); if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted) { await eventArgs.ClientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket { ConnectReturnCode = connectReturnCode }).ConfigureAwait(false); return; } var clientSession = GetOrCreateClientSession(connectPacket); await eventArgs.ClientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket { ConnectReturnCode = connectReturnCode, IsSessionPresent = clientSession.IsExistingSession }).ConfigureAwait(false); await clientSession.Session.RunAsync(eventArgs.Identifier, connectPacket.WillMessage, eventArgs.ClientAdapter).ConfigureAwait(false); } catch (Exception exception) { MqttTrace.Error(nameof(MqttServer), exception, exception.Message); } finally { await eventArgs.ClientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false); } }
public void DispatchPublishPacket(MqttClientSession senderClientSession, MqttPublishPacket publishPacket) { try { var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession?.ClientId, publishPacket.ToApplicationMessage()); ApplicationMessageReceived?.Invoke(this, eventArgs); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClientSessionsManager), exception, "Error while processing application message"); } lock (_syncRoot) { foreach (var clientSession in _clientSessions.Values.ToList()) { clientSession.EnqueuePublishPacket(publishPacket); } } }
private async Task AcceptDefaultEndpointConnectionsAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var clientSocket = await _defaultEndpointSocket.AcceptAsync().ConfigureAwait(false); var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer()); ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); } catch (Exception exception) { MqttTrace.Error(nameof(MqttServerAdapter), exception, "Error while accepting connection at default endpoint."); //excessive CPU consumed if in endless loop of socket errors await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false); } } }
private async Task AcceptTlsEndpointConnectionsAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null); var sslStream = new SslStream(new NetworkStream(clientSocket)); await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false); var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, sslStream), new DefaultMqttV311PacketSerializer()); ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); } catch (Exception exception) { MqttTrace.Error(nameof(MqttServerAdapter), exception, "Error while acceping connection at TLS endpoint."); } } }
public async Task RunClientSessionAsync(MqttClientConnectedEventArgs eventArgs) { try { var connectPacket = await eventArgs.ClientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout) as MqttConnectPacket; if (connectPacket == null) { throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1]."); } var connectReturnCode = ValidateConnection(connectPacket); if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted) { await eventArgs.ClientAdapter.SendPacketAsync(new MqttConnAckPacket { ConnectReturnCode = connectReturnCode }, _options.DefaultCommunicationTimeout); return; } var clientSession = GetOrCreateClientSession(connectPacket); await eventArgs.ClientAdapter.SendPacketAsync(new MqttConnAckPacket { ConnectReturnCode = connectReturnCode, IsSessionPresent = clientSession.IsExistingSession }, _options.DefaultCommunicationTimeout); await clientSession.Session.RunAsync(eventArgs.Identifier, connectPacket.WillMessage, eventArgs.ClientAdapter); } catch (Exception exception) { MqttTrace.Error(nameof(MqttServer), exception, exception.Message); } finally { await eventArgs.ClientAdapter.DisconnectAsync(); } }
private async Task SendKeepAliveMessagesAsync(CancellationToken cancellationToken) { MqttTrace.Information(nameof(MqttClient), "Start sending keep alive packets."); try { while (!cancellationToken.IsCancellationRequested) { await Task.Delay(_options.KeepAlivePeriod, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } await SendAndReceiveAsync <MqttPingRespPacket>(new MqttPingReqPacket()).ConfigureAwait(false); } } catch (TaskCanceledException) { } catch (MqttCommunicationException exception) { if (cancellationToken.IsCancellationRequested) { return; } MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while sending/receiving keep alive packets."); await DisconnectInternalAsync().ConfigureAwait(false); } catch (Exception exception) { MqttTrace.Warning(nameof(MqttClient), exception, "Unhandled exception while sending/receiving keep alive packets."); await DisconnectInternalAsync().ConfigureAwait(false); } finally { MqttTrace.Information(nameof(MqttClient), "Stopped sending keep alive packets."); } }
private async Task ReceivePackets(CancellationToken cancellationToken) { MqttTrace.Information(nameof(MqttClient), "Start receiving packets."); try { while (!cancellationToken.IsCancellationRequested) { var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } StartProcessReceivedPacket(packet, cancellationToken); } } catch (TaskCanceledException) { } catch (MqttCommunicationException exception) { if (cancellationToken.IsCancellationRequested) { return; } MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while receiving packets."); await DisconnectInternalAsync().ConfigureAwait(false); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Unhandled exception while receiving packets."); await DisconnectInternalAsync().ConfigureAwait(false); } finally { MqttTrace.Information(nameof(MqttClient), "Stopped receiving packets."); } }
private async void ProcessReceivedPacket(MqttBasePacket mqttPacket) { try { if (mqttPacket is MqttPingReqPacket) { await SendAsync(new MqttPingRespPacket()); return; } if (mqttPacket is MqttDisconnectPacket) { await DisconnectAsync(); return; } var publishPacket = mqttPacket as MqttPublishPacket; if (publishPacket != null) { await ProcessReceivedPublishPacket(publishPacket); return; } var pubRelPacket = mqttPacket as MqttPubRelPacket; if (pubRelPacket != null) { await ProcessReceivedPubRelPacket(pubRelPacket); return; } _packetDispatcher.Dispatch(mqttPacket); } catch (Exception exception) { MqttTrace.Error(nameof(MqttClient), exception, "Error while processing received packet."); } }