public async Task DisconnectAsync(MqttClientDisconnectOptions options, CancellationToken cancellationToken) { if (options is null) { throw new ArgumentNullException(nameof(options)); } ThrowIfDisposed(); try { _disconnectReason = MqttClientDisconnectReason.NormalDisconnection; _cleanDisconnectInitiated = true; if (IsConnected) { var disconnectPacket = _adapter.PacketFormatterAdapter.DataConverter.CreateDisconnectPacket(options); await SendAsync(disconnectPacket, cancellationToken).ConfigureAwait(false); } } finally { if (!DisconnectIsPending()) { await DisconnectInternalAsync(null, null, null).ConfigureAwait(false); } } }
/// <inheritdoc cref="IMqttClient.DisconnectAsync" /> public Task DisconnectAsync(MqttClientDisconnectOptions options, CancellationToken cancellationToken) { _broker.Disconnect(ClientId); IsConnected = false; return(Task.CompletedTask); }
public MqttDisconnectPacket CreateDisconnectPacket(MqttClientDisconnectOptions options) { if (options != null) { throw new MqttProtocolViolationException("Reason codes for disconnect are only supported for MQTTv5."); } return(new MqttDisconnectPacket()); }
public MqttDisconnectPacket CreateDisconnectPacket(MqttClientDisconnectOptions options) { if (options.ReasonCode != MqttClientDisconnectReason.NormalDisconnection || options.ReasonString != null) { throw new MqttProtocolViolationException("Reason codes and reason string for disconnect are only supported for MQTTv5."); } return(new MqttDisconnectPacket()); }
public static Task DisconnectAsync(this IMqttClient client, MqttClientDisconnectOptions options) { if (client == null) { throw new ArgumentNullException(nameof(client)); } return(client.DisconnectAsync(options, CancellationToken.None)); }
public async Task DisconnectAsync(CancellationToken cancellationToken) { var cancelToken = cancellationToken != null ? cancellationToken : CancellationToken.None; var disconnectOptions = new MqttClientDisconnectOptions { ReasonString = "Bridge disconnect" }; await PrimaryClient.DisconnectAsync(disconnectOptions, cancelToken); await SecondaryClient.DisconnectAsync(disconnectOptions, cancelToken); }
public async Task DisconnectAsync(CancellationToken cancellationToken) { var cancelToken = cancellationToken != null ? cancellationToken : CancellationToken.None; var disconnectOptions = new MqttClientDisconnectOptions { ReasonString = "Bridge disconnect" }; await LocalClient.DisconnectAsync(disconnectOptions, cancelToken); await DeviceClient.CloseAsync(cancelToken); }
public async Task StopAsync(CancellationToken cancellationToken) { var disconnectOptions = new MqttClientDisconnectOptions { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = "Diconnection" }; await this.client.DisconnectAsync(disconnectOptions, cancellationToken); }
public async Task StopAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { var disconnectOption = new MqttClientDisconnectOptions { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = "NormalDiconnection" }; await mqttClient.DisconnectAsync(disconnectOption, cancellationToken); } await mqttClient.DisconnectAsync(); }
public async Task StopAsync(CancellationToken cancellationToken) { this.logger.LogInformation("MQTT Service Stop!"); if (cancellationToken.IsCancellationRequested) { var disconnectOption = new MqttClientDisconnectOptions { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = "NormalDiconnection" }; await this.mqttClient.DisconnectAsync(disconnectOption, cancellationToken); } await this.mqttClient.DisconnectAsync(cancellationToken); }
public MqttDisconnectPacket CreateDisconnectPacket(MqttClientDisconnectOptions options) { var packet = new MqttDisconnectPacket(); if (options == null) { packet.ReasonCode = MqttDisconnectReasonCode.NormalDisconnection; } else { packet.ReasonCode = (MqttDisconnectReasonCode)options.ReasonCode; } return(packet); }
public async Task StopAsync(CancellationToken cancellationToken) { // o app ser encerrado if (cancellationToken.IsCancellationRequested) { var disconnectOption = new MqttClientDisconnectOptions { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = "NormalDisconnection" }; await mqttClient.DisconnectAsync(disconnectOption, cancellationToken); } await mqttClient.DisconnectAsync(); _logger.LogInformation("Encerrando..."); }
async Task TrySendDisconnectPacket(MqttClientDisconnectReason reason) { try { var disconnectOptions = new MqttClientDisconnectOptions { ReasonCode = reason, ReasonString = reason.ToString() }; var disconnectPacket = _channelAdapter.PacketFormatterAdapter.DataConverter.CreateDisconnectPacket(disconnectOptions); using (var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout)) { await SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false); } } catch (Exception exception) { _logger.Warning(exception, "Client '{{0}}': Error while sending DISCONNECT packet (Reason = {1}).", ClientId, reason); } }
public async Task StopAsync(MqttClientDisconnectReason reason) { Status = MqttClientConnectionStatus.Finalizing; _disconnectReason = reason; if (reason == MqttClientDisconnectReason.SessionTakenOver || reason == MqttClientDisconnectReason.KeepAliveTimeout) { // Is is very important to send the DISCONNECT packet here BEFORE cancelling the // token because the entire connection is closed (disposed) as soon as the cancellation // token is cancelled. To there is no chance that the DISCONNECT packet will ever arrive // at the client! try { var disconnectOptions = new MqttClientDisconnectOptions { ReasonCode = reason, ReasonString = reason.ToString() }; var disconnectPacket = _channelAdapter.PacketFormatterAdapter.DataConverter.CreateDisconnectPacket(disconnectOptions); using (var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout)) { await _channelAdapter.SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false); } } catch (Exception exception) { _logger.Warning(exception, "Client '{0}': Error while sending DISCONNECT packet after takeover.", ClientId); } } StopInternal(); await(_packageReceiverTask ?? PlatformAbstractionLayer.CompletedTask); }
public RemoteMqttBroker( ILogger <RemoteMqttBroker> logger, IEventIdCreationSource eventIdCreationSource, IOptions <MqttNetworkOptions>?options = null) { _logger = logger; _eventIdCreationSource = eventIdCreationSource; EventId eventId = GetNextEventId(); _logger.LogInformation(eventId, $"Creating Mqtt Client (Id: {ClientId})."); MqttNetworkOptions mqttNetworkOptions = options?.Value ?? MqttNetworkOptions.Default; mqttNetworkOptions.Host ??= MqttNetworkOptions.Default.Host !; if (mqttNetworkOptions.Port < 0x0000) { throw new ArgumentOutOfRangeException(nameof(mqttNetworkOptions.Port), mqttNetworkOptions.Port, "Port number too small."); } else if (mqttNetworkOptions.Port > 0xffff) { throw new ArgumentOutOfRangeException(nameof(mqttNetworkOptions.Port), mqttNetworkOptions.Port, "Port number too large."); } if (mqttNetworkOptions.Timeout < 1) { throw new ArgumentOutOfRangeException(nameof(mqttNetworkOptions.Timeout), mqttNetworkOptions.Timeout, "Timeout timespan too small."); } else if (mqttNetworkOptions.Timeout > 99999) { throw new ArgumentOutOfRangeException(nameof(mqttNetworkOptions.Timeout), mqttNetworkOptions.Timeout, "Timeout timespan too large."); } _logger.LogInformation(eventId, $"MQTT Client Communication Timeout: {mqttNetworkOptions.Timeout} ms."); var clientOptionsBuilder = new MqttClientOptionsBuilder() .WithClientId(ClientId) .WithCommunicationTimeout(TimeSpan.FromSeconds(60)) .WithTcpServer(mqttNetworkOptions.Host, mqttNetworkOptions.Port); _mqttClient = new MqttFactory().CreateMqttClient(); _mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(eventArgs => { _logger.LogDebug("Client Connected. Reason: " + (eventArgs.AuthenticateResult?.ReasonString ?? "null")); }); _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(eventArgs => { _logger.LogDebug(eventArgs.Exception, "Client Disconnected. Reason: " + (eventArgs.AuthenticateResult?.ReasonString ?? "null")); }); CancellationTokenSource?cancellationTokenSource = null; #region Connecting to remote Mqtt Broker try { _logger.LogInformation(eventId, $"Connecting to remote Mqtt-Broker (mqtt://{mqttNetworkOptions.Host}:{mqttNetworkOptions.Port})."); cancellationTokenSource = new CancellationTokenSource(TimeoutTimeSpan); var result = _mqttClient.ConnectAsync(clientOptionsBuilder.Build(), cancellationTokenSource.Token).GetAwaiter().GetResult(); if (result.ResultCode != MqttClientConnectResultCode.Success) { throw new Exception("Mqtt-Client ConnectResultCode Success expected. Actual: " + result.ResultCode); } } catch (OperationCanceledException) { string errorMessage = "Connect to remote Mqtt-Broker timed out."; _logger.LogCritical(eventId, errorMessage); throw new Exception(errorMessage); } catch (Exception exception) { string errorMessage = "Failed to connect to remote Mqtt-Broker."; _logger.LogCritical(eventId, exception, errorMessage); throw new Exception(errorMessage); } finally { cancellationTokenSource?.Dispose(); } #endregion #region Subscribing to relevant Events try { _logger.LogInformation(eventId, $"Subscribing to relevant events."); MqttQualityOfServiceLevel mqttQualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce; MqttClientSubscribeResultCode expectedSubscribeResultCode = MqttClientSubscribeResultCode.GrantedQoS1; MqttClientSubscribeOptionsBuilder subscribeOptionsBuilder = new MqttClientSubscribeOptionsBuilder() .WithTopicFilter(MqttTopics.TrackerHello, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.TrackerGoodbye, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientJoinAccepted, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientJoinDenied, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientRegistered, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientGoodbye, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FileInfoPublished, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionStarted, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionDelivered, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionEnded, mqttQualityOfServiceLevel); cancellationTokenSource = new CancellationTokenSource(TimeoutTimeSpan); //timeout MqttClientSubscribeResult result = _mqttClient.SubscribeAsync(subscribeOptionsBuilder.Build(), cancellationTokenSource.Token).GetAwaiter().GetResult(); foreach (MqttClientSubscribeResultItem item in result.Items) { if (item.ResultCode != expectedSubscribeResultCode) { throw new Exception($"Expected SubscribeResultCode {expectedSubscribeResultCode} for topic \"{item.TopicFilter.Topic}\". Actual: {item.ResultCode}"); } } } catch (Exception exception) { string errorMessage; if (exception is OperationCanceledException) { errorMessage = "Subscribing to all relevant Events to remote Mqtt-Broker timed out."; _logger.LogCritical(eventId, errorMessage); } else { errorMessage = "Failed to subscribe to all relevant topics with expected SubscribeResultCode."; _logger.LogCritical(eventId, exception, errorMessage); } try { _logger.LogInformation("Disconnecting from remote Mqtt-Broker"); MqttClientDisconnectOptions disconnectOptions = new MqttClientDisconnectOptions() { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = errorMessage }; cancellationTokenSource = new CancellationTokenSource(TimeoutTimeSpan); _mqttClient.DisconnectAsync(disconnectOptions, cancellationTokenSource.Token).GetAwaiter().GetResult(); } catch (OperationCanceledException) { _logger.LogError(eventId, "Disconnecting from remote Mqtt-Broker timed out."); } catch (Exception disconnectException) { _logger.LogError(eventId, disconnectException, "Disconnecting from remote Mqtt-Broker failed."); } finally { cancellationTokenSource?.Dispose(); } throw new Exception(errorMessage); } finally { cancellationTokenSource?.Dispose(); } #endregion }
protected virtual void Dispose(bool disposing) { if (_disposed) { return; } _disposed = true; EventId eventId = GetNextEventId(); CancellationTokenSource?cancellationTokenSource = null; try { try { MqttClientUnsubscribeOptions mqttClientUnsubscribeOptions = new MqttClientUnsubscribeOptions { TopicFilters = new List <string> { MqttTopics.ClientJoinRequested, MqttTopics.ClientJoinSucceeded, MqttTopics.ClientJoinFailed, MqttTopics.ClientGoodbye, MqttTopics.FragmentDistributionRequested, MqttTopics.FragmentDistributionObtained, MqttTopics.FragmentDistributionFailed } }; _logger.LogInformation(eventId, "Unsubscribing from all events from remote Mqtt-Broker."); cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var result = _mqttClient.UnsubscribeAsync(mqttClientUnsubscribeOptions, cancellationTokenSource.Token).GetAwaiter().GetResult(); foreach (MqttClientUnsubscribeResultItem item in result.Items) { if (item.ReasonCode != MqttClientUnsubscribeResultCode.Success) { throw new Exception($"Expected UnsubscribeResultCode Success for topic \"{item.TopicFilter}\". Actual: {item.ReasonCode}"); } } } catch (OperationCanceledException) { _logger.LogError(eventId, "Unsubscribing from all events from remote Mqtt-Broker timed out."); } catch (Exception exception) { _logger.LogError(eventId, exception, "Unsubscribing from all events from remote Mqtt-Broker failed."); } finally { cancellationTokenSource?.Dispose(); } _logger.LogInformation(eventId, "Disconnecting from remote Mqtt-Broker."); MqttClientDisconnectOptions disconnectOptions = new MqttClientDisconnectOptions() { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = "Client Disposed" }; cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); _mqttClient.DisconnectAsync(disconnectOptions, cancellationTokenSource.Token).GetAwaiter().GetResult(); } catch (OperationCanceledException) { _logger.LogError(eventId, "Disconnecting from remote Mqtt-Broker timed out."); } catch (Exception exception) { _logger.LogError(eventId, exception, "Disconnecting from remote Mqtt-Broker failed."); } finally { _mqttClient.Dispose(); cancellationTokenSource?.Dispose(); } }
public MqttDisconnectPacket CreateDisconnectPacket(MqttClientDisconnectOptions options) { return(new MqttDisconnectPacket()); }
public RemoteMqttBroker( ILogger <RemoteMqttBroker> logger, IEventIdCreationSource eventIdCreationSource, string host, int port, int timeout) { _logger = logger; _eventIdCreationSource = eventIdCreationSource; EventId eventId = GetNextEventId(); #if DEBUG _logger.LogDebug(eventId, "Creating Mqtt Client."); #endif if (port < 0x0000) { throw new ArgumentOutOfRangeException(nameof(port), port, "Port number too small."); } else if (timeout > 0xffff) { throw new ArgumentOutOfRangeException(nameof(port), port, "Port number too large."); } if (timeout < 1) { throw new ArgumentOutOfRangeException(nameof(timeout), timeout, "Timeout timespan too small."); } else if (timeout > 99999) { throw new ArgumentOutOfRangeException(nameof(timeout), timeout, "Timeout timespan too large."); } _logger.LogInformation(eventId, $"MQTT Client Communication Timeout: {timeout} ms."); var clientOptionsBuilder = new MqttClientOptionsBuilder() .WithClientId(ClientId) .WithCommunicationTimeout(TimeSpan.FromMilliseconds(timeout)) .WithTcpServer(host, port); _mqttClient = new MqttFactory().CreateMqttClient(); CancellationTokenSource?cancellationTokenSource = null; #region Connecting to remote Mqtt Broker try { _logger.LogInformation(eventId, $"Connecting to remote Mqtt-Broker (mqtt://{host}:{port})."); cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); //timeout var result = _mqttClient.ConnectAsync(clientOptionsBuilder.Build(), cancellationTokenSource.Token).GetAwaiter().GetResult(); if (result.ResultCode != MqttClientConnectResultCode.Success) { throw new Exception("Mqtt-Client ConnectResultCode Success expected. Actual: " + result.ResultCode); } } catch (OperationCanceledException) { string errorMessage = "Connect to remote Mqtt-Broker timed out."; _logger.LogCritical(eventId, errorMessage); throw new Exception(errorMessage); } catch (Exception exception) { string errorMessage = "Failed to connect to remote Mqtt-Broker."; _logger.LogCritical(eventId, exception, errorMessage); throw new Exception(errorMessage); } finally { cancellationTokenSource?.Dispose(); } #endregion #region Subscribing to relevant Events try { _logger.LogInformation(eventId, $"Subscribing to relevant events."); MqttQualityOfServiceLevel mqttQualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce; MqttClientSubscribeResultCode expectedSubscribeResultCode = MqttClientSubscribeResultCode.GrantedQoS1; MqttClientSubscribeOptionsBuilder subscribeOptionsBuilder = new MqttClientSubscribeOptionsBuilder() .WithTopicFilter(MqttTopics.ClientJoinRequested, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientJoinSucceeded, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientJoinFailed, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.ClientGoodbye, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionRequested, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionObtained, mqttQualityOfServiceLevel) .WithTopicFilter(MqttTopics.FragmentDistributionFailed, mqttQualityOfServiceLevel); cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); //timeout MqttClientSubscribeResult result = _mqttClient.SubscribeAsync(subscribeOptionsBuilder.Build(), cancellationTokenSource.Token).GetAwaiter().GetResult(); foreach (MqttClientSubscribeResultItem item in result.Items) { if (item.ResultCode != expectedSubscribeResultCode) { throw new Exception($"Expected SubscribeResultCode {expectedSubscribeResultCode} for topic \"{item.TopicFilter.Topic}\". Actual: {item.ResultCode}"); } } } catch (OperationCanceledException) { string errorMessage = "Subscribing to all relevant Events to remote Mqtt-Broker timed out."; _logger.LogCritical(eventId, errorMessage); DisconnectOnError(errorMessage); throw new Exception(errorMessage); } catch (Exception exception) { string errorMessage = "Failed to subscribe to all relevant topics with expected SubscribeResultCode."; _logger.LogCritical(eventId, exception, errorMessage); DisconnectOnError(errorMessage); throw new Exception(errorMessage); } finally { cancellationTokenSource?.Dispose(); } #endregion void DisconnectOnError(string reasonString) { try { _logger.LogInformation("Disconnecting from remote Mqtt-Broker"); MqttClientDisconnectOptions disconnectOptions = new MqttClientDisconnectOptions() { ReasonCode = MqttClientDisconnectReason.NormalDisconnection, ReasonString = reasonString }; cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); _mqttClient.DisconnectAsync(disconnectOptions, cancellationTokenSource.Token).GetAwaiter().GetResult(); } catch (OperationCanceledException) { _logger.LogError(eventId, "Disconnecting from remote Mqtt-Broker timed out."); } catch (Exception exception) { _logger.LogError(eventId, exception, "Disconnecting from remote Mqtt-Broker failed."); } finally { cancellationTokenSource?.Dispose(); } } }