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); MqttNetTrace.Information(nameof(MqttClient), "Disconnected from adapter."); } catch (Exception exception) { MqttNetTrace.Warning(nameof(MqttClient), exception, "Error while disconnecting from adapter."); } finally { Disconnected?.Invoke(this, EventArgs.Empty); } }
public async Task SendPacketsAsync(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable <MqttBasePacket> packets) { await _semaphore.WaitAsync(cancellationToken); try { foreach (var packet in packets) { if (packet == null) { continue; } MqttNetTrace.Information(nameof(MqttChannelCommunicationAdapter), "TX >>> {0} [Timeout={1}]", packet, timeout); var writeBuffer = PacketSerializer.Serialize(packet); await _channel.SendStream.WriteAsync(writeBuffer, 0, writeBuffer.Length, cancellationToken).ConfigureAwait(false); } 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 (OperationCanceledException) { throw; } catch (MqttCommunicationTimedOutException) { throw; } catch (MqttCommunicationException) { throw; } catch (Exception exception) { throw new MqttCommunicationException(exception); } finally { _semaphore.Release(); } }
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."); } MqttNetTrace.Information(nameof(MqttChannelCommunicationAdapter), "RX <<< {0}", packet); return(packet); } catch (TaskCanceledException) { throw; } catch (OperationCanceledException) { throw; } catch (MqttCommunicationTimedOutException) { throw; } catch (MqttCommunicationException) { throw; } catch (Exception exception) { throw new MqttCommunicationException(exception); } }
public void Stop() { if (_willMessage != null) { _mqttClientSessionsManager.DispatchPublishPacket(this, _willMessage.ToPublishPacket()); } _cancellationTokenSource?.Cancel(false); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; _adapter = null; MqttNetTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", ClientId); }
public async Task StopAsync() { _cancellationTokenSource?.Cancel(false); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; foreach (var adapter in _adapters) { adapter.ClientAccepted -= OnClientAccepted; await adapter.StopAsync(); } _clientSessionsManager.Clear(); MqttNetTrace.Information(nameof(MqttServer), "Stopped."); }
private async Task ReceivePackets(CancellationToken cancellationToken) { MqttNetTrace.Information(nameof(MqttClient), "Start receiving packets."); try { while (!cancellationToken.IsCancellationRequested) { _isReceivingPackets = true; var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } StartProcessReceivedPacket(packet, cancellationToken); } } catch (OperationCanceledException) { } catch (MqttCommunicationException exception) { if (cancellationToken.IsCancellationRequested) { return; } MqttNetTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while receiving packets."); await DisconnectInternalAsync().ConfigureAwait(false); } catch (Exception exception) { MqttNetTrace.Error(nameof(MqttClient), exception, "Unhandled exception while receiving packets."); await DisconnectInternalAsync().ConfigureAwait(false); } finally { MqttNetTrace.Information(nameof(MqttClient), "Stopped receiving packets."); } }
public async Task StartAsync() { if (_cancellationTokenSource != null) { throw new InvalidOperationException("The MQTT server is already started."); } _cancellationTokenSource = new CancellationTokenSource(); await _clientSessionsManager.RetainedMessagesManager.LoadMessagesAsync(); foreach (var adapter in _adapters) { adapter.ClientAccepted += OnClientAccepted; await adapter.StartAsync(_options); } MqttNetTrace.Information(nameof(MqttServer), "Started."); }
private async Task SendKeepAliveMessagesAsync(CancellationToken cancellationToken) { MqttNetTrace.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 (OperationCanceledException) { } catch (MqttCommunicationException exception) { if (cancellationToken.IsCancellationRequested) { return; } MqttNetTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while sending/receiving keep alive packets."); await DisconnectInternalAsync().ConfigureAwait(false); } catch (Exception exception) { MqttNetTrace.Warning(nameof(MqttClient), exception, "Unhandled exception while sending/receiving keep alive packets."); await DisconnectInternalAsync().ConfigureAwait(false); } finally { MqttNetTrace.Information(nameof(MqttClient), "Stopped sending keep alive packets."); } }
private async Task ProcessReceivedPacketAsync(MqttBasePacket packet) { try { MqttNetTrace.Information(nameof(MqttClient), "Received <<< {0}", packet); if (packet is MqttPingReqPacket) { await SendAsync(new MqttPingRespPacket()); return; } if (packet is MqttDisconnectPacket) { await DisconnectAsync(); return; } if (packet is MqttPublishPacket publishPacket) { await ProcessReceivedPublishPacket(publishPacket); return; } if (packet is MqttPubRelPacket pubRelPacket) { await ProcessReceivedPubRelPacket(pubRelPacket); return; } _packetDispatcher.Dispatch(packet); } catch (Exception exception) { MqttNetTrace.Error(nameof(MqttClient), exception, "Unhandled exception while processing received packet."); } }
public async Task HandleMessageAsync(string clientId, MqttPublishPacket publishPacket) { if (publishPacket == null) { throw new ArgumentNullException(nameof(publishPacket)); } List <MqttPublishPacket> allRetainedMessages; lock (_retainedMessages) { if (publishPacket.Payload?.Any() == false) { _retainedMessages.Remove(publishPacket.Topic); MqttNetTrace.Information(nameof(MqttClientRetainedMessagesManager), "Client '{0}' cleared retained message for topic '{1}'.", clientId, publishPacket.Topic); } else { _retainedMessages[publishPacket.Topic] = publishPacket; MqttNetTrace.Information(nameof(MqttClientRetainedMessagesManager), "Client '{0}' updated retained message for topic '{1}'.", clientId, publishPacket.Topic); } allRetainedMessages = new List <MqttPublishPacket>(_retainedMessages.Values); } try { // ReSharper disable once UseNullPropagation if (_options.Storage != null) { await _options.Storage.SaveRetainedMessagesAsync(allRetainedMessages.Select(p => p.ToApplicationMessage()).ToList()); } } catch (Exception exception) { MqttNetTrace.Error(nameof(MqttClientRetainedMessagesManager), exception, "Unhandled exception while saving retained messages."); } }
private void OnClientDisconnected(object sender, MqttClientDisconnectedEventArgs eventArgs) { MqttNetTrace.Information(nameof(MqttServer), "Client '{0}': Disconnected.", eventArgs.Client.ClientId); ClientDisconnected?.Invoke(this, eventArgs); }