private static void HandleDisconnect(MqttClientAuthenticateResult mqttClientAuthenticateResult) { Console.WriteLine("Got disconnection"); var result = mqttClientAuthenticateResult; Console.WriteLine(result.ReasonString); }
void ValidateConnectResult(MqttClientAuthenticateResult authenticateResult) { if (authenticateResult.ResultCode != MqttClientConnectResultCode.Success) { throw new MqttException(isTemporary: IsTemporaryFailure(authenticateResult.ResultCode), message: $"Authentication failed: [code={authenticateResult.ResultCode}, message={authenticateResult.ReasonString}]."); } }
static void HandleError(MqttClientAuthenticateResult result) { switch (result.ResultCode) { case MqttClientConnectResultCode.BadUserNameOrPassword: Dbg.Write("MQTTPublish - Connect - Invalid User Name or Password!"); DisposeInstance(); break; case MqttClientConnectResultCode.BadAuthenticationMethod: Dbg.Write("MQTTPublish - Connect - Bad authentication method - secure connection type invaid? " + result.ResultCode.ToString()); DisposeInstance(); break; case MqttClientConnectResultCode.NotAuthorized: Dbg.Write("MQTTPublish - Connect - User Not Authorized: " + result.ResultCode.ToString()); DisposeInstance(); break; case MqttClientConnectResultCode.ServerUnavailable: Dbg.Write("MQTTPublish - Connect - The server is unavailable"); break; default: Dbg.Write("MQTTPublish - Connect Error - Error Code: " + result.ResultCode.ToString()); break; } }
public async Task <bool> StartUpClientAsync() { _ = InitClient(); MqttClientAuthenticateResult mqttRs = await mqttClient.ConnectAsync(options); return(mqttRs.ResultCode == MqttClientConnectResultCode.Success); }
private static void SubscribePreviousConnection(Guid key, MqttClientAuthenticateResult result) { if (!result.IsSessionPresent) { return; } for (int i = 0; i < result.UserProperties.Count; i++) { MqttUserProperty prop = result.UserProperties[i]; if (prop.Name == "subscriptions") { using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(prop.Value))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(SubscriptionList)); SubscriptionList list = (SubscriptionList)serializer.ReadObject(ms); foreach (PreviousSubscription subscription in list) { MqttClient client = GetClient(key); string gxproc = client.GetProc(subscription.topic); if (!string.IsNullOrEmpty(gxproc)) { Subscribe(key, subscription.topic, gxproc, subscription.qos); } } } } } }
public async Task <MqttClientPublishResult> Publish(string topic, byte[] data, MqttQualityOfServiceLevel level = MqttQualityOfServiceLevel.AtMostOnce) { bool rs = mqttClient.IsConnected; if (!rs) // 掉线重连 { MqttClientAuthenticateResult mqttRs = await mqttClient.ConnectAsync(options); rs = mqttRs.ResultCode == MqttClientConnectResultCode.Success; } if (rs) { MqttApplicationMessage msg = new MqttApplicationMessage { Topic = topic, Payload = data, QualityOfServiceLevel = level, Retain = false }; return(await mqttClient.PublishAsync(msg)); } return(new MqttClientPublishResult { ReasonCode = MqttClientPublishReasonCode.UnspecifiedError }); }
public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult, MqttClientDisconnectReason reasonCode) { ClientWasConnected = clientWasConnected; Exception = exception; AuthenticateResult = authenticateResult; ReasonCode = reasonCode; }
async Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult) { var clientWasConnected = _isConnected; var reasonCode = MqttClientDisconnectReason.NormalDisconnection; TryInitiateDisconnect(); _isConnected = false; try { if (_adapter != null) { _logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout); await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false); } _logger.Verbose("Disconnected from adapter."); } catch (Exception adapterException) { _logger.Warning(adapterException, "Error while disconnecting from adapter."); reasonCode = MqttClientDisconnectReason.UnspecifiedError; } try { var receiverTask = WaitForTaskAsync(_packetReceiverTask, sender); var publishPacketReceiverTask = WaitForTaskAsync(_publishPacketReceiverTask, sender); var keepAliveTask = WaitForTaskAsync(_keepAlivePacketsSenderTask, sender); await Task.WhenAll(receiverTask, publishPacketReceiverTask, keepAliveTask).ConfigureAwait(false); _publishPacketReceiverQueue?.Dispose(); } catch (Exception e) { _logger.Warning(e, "Error while waiting for internal tasks."); reasonCode = MqttClientDisconnectReason.UnspecifiedError; } finally { Cleanup(); _cleanDisconnectInitiated = false; _logger.Info("Disconnected."); var disconnectedHandler = DisconnectedHandler; if (disconnectedHandler != null) { // This handler must be executed in a new thread because otherwise a dead lock may happen // when trying to reconnect in that handler etc. Task.Run(() => disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception, authenticateResult, reasonCode))).Forget(_logger); } } }
Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult) { var clientWasConnected = IsConnected; if (!DisconnectIsPendingOrFinished()) { return(DisconnectCoreAsync(sender, exception, authenticateResult, clientWasConnected)); } return(PlatformAbstractionLayer.CompletedTask); }
private void LogUnsuccessfulAuthenticationResult(MqttClientAuthenticateResult authenticationResult) { if (!IsShuttingDown && authenticationResult != null && authenticationResult.ResultCode != MqttClientConnectResultCode.Success) { Logger.LogWarning( "Authentication Result: " + authenticationResult.ResultCode + ( !string.IsNullOrEmpty(authenticationResult.ReasonString) ? $": {authenticationResult.ReasonString}" : string.Empty) ); } }
async internal Task <MqttClientAuthenticateResult> Connect() { var connection = new MqttClientAuthenticateResult(); while (!this.mqttClient.IsConnected) { connection = await mqttClient.ConnectAsync(mqttOptions, CancellationToken.None); } var result = await mqttClient.SubscribeAsync(new TopicFilterBuilder() .WithTopic(agentVeraSettings.topic + topicSubscription) .WithAtLeastOnceQoS().Build()); return(connection); }
private async void disconnectionHandler(MqttClientDisconnectedEventArgs arg) { if (Client.IsConnected) { await Client.DisconnectAsync(); } if (btnSubscribe.Text == "Stop") { auth = await Client.ConnectAsync(options); if (auth.ResultCode != MqttClientConnectResultCode.Success) { throw new Exception(auth.ResultCode.ToString()); } Client.UseApplicationMessageReceivedHandler((Action <MqttApplicationMessageReceivedEventArgs>)receiveHandler); } }
private async Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult) { var clientWasConnected = IsConnected; InitiateDisconnect(); IsConnected = false; try { if (_adapter != null) { _logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout); await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false); } await WaitForTaskAsync(_packetReceiverTask, sender).ConfigureAwait(false); await WaitForTaskAsync(_keepAlivePacketsSenderTask, sender).ConfigureAwait(false); _logger.Verbose("Disconnected from adapter."); } catch (Exception adapterException) { _logger.Warning(adapterException, "Error while disconnecting from adapter."); } finally { Dispose(); _cleanDisconnectInitiated = false; _logger.Info("Disconnected."); var disconnectedHandler = DisconnectedHandler; if (disconnectedHandler != null) { // This handler must be executed in a new thread because otherwise a dead lock may happen // when trying to reconnect in that handler etc. Task.Run(() => disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception, authenticateResult))).Forget(_logger); } } }
private async Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult) { var clientWasConnected = IsConnected; InitiateDisconnect(); IsConnected = false; try { if (_adapter != null) { _logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout); await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false); } await WaitForTaskAsync(_packetReceiverTask, sender).ConfigureAwait(false); await WaitForTaskAsync(_keepAlivePacketsSenderTask, sender).ConfigureAwait(false); _logger.Verbose("Disconnected from adapter."); } catch (Exception adapterException) { _logger.Warning(adapterException, "Error while disconnecting from adapter."); } finally { Dispose(); _cleanDisconnectInitiated = false; _logger.Info("Disconnected."); var disconnectedHandler = DisconnectedHandler; if (disconnectedHandler != null) { await disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception, authenticateResult)).ConfigureAwait(false); } } }
static void HandleError(MqttClientAuthenticateResult result) { string err = string.Empty; switch (result.ResultCode) { case MqttClientConnectResultCode.BadUserNameOrPassword: err = "MQTTPublish - Connect - Invalid User Name or Password!"; DisposeInstance(); break; case MqttClientConnectResultCode.BadAuthenticationMethod: err = "MQTTPublish - Connect - Bad authentication method - secure connection type invaid? " + result.ResultCode.ToString(); DisposeInstance(); break; case MqttClientConnectResultCode.NotAuthorized: err = "MQTTPublish - Connect - User Not Authorized: " + result.ResultCode.ToString(); DisposeInstance(); break; case MqttClientConnectResultCode.ServerUnavailable: err = "MQTTPublish - Connect - The server is unavailable"; break; default: err = "MQTTPublish - Connect Error - Error Code: " + result.ResultCode.ToString(); break; } if (!_loggedError) { Dbg.Write(err); } _loggedError = true; }
public async Task <MqttClientAuthenticateResult> ConnectAsync(IMqttClientOptions options, CancellationToken cancellationToken) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (options.ChannelOptions == null) { throw new ArgumentException("ChannelOptions are not set."); } ThrowIfConnected("It is not allowed to connect with a server after the connection is established."); ThrowIfDisposed(); if (CompareExchangeConnectionStatus(MqttClientConnectionStatus.Connecting, MqttClientConnectionStatus.Disconnected) != MqttClientConnectionStatus.Disconnected) { throw new InvalidOperationException("Not allowed to connect while connect/disconnect is pending."); } MqttClientAuthenticateResult authenticateResult = null; try { Options = options; _packetIdentifierProvider.Reset(); _packetDispatcher.CancelAll(); _backgroundCancellationTokenSource = new CancellationTokenSource(); var backgroundCancellationToken = _backgroundCancellationTokenSource.Token; var adapter = _adapterFactory.CreateClientAdapter(options); _adapter = adapter; using (var combined = CancellationTokenSource.CreateLinkedTokenSource(backgroundCancellationToken, cancellationToken)) { _logger.Verbose("Trying to connect with server '{0}' (Timeout={1}).", options.ChannelOptions, options.CommunicationTimeout); await adapter.ConnectAsync(options.CommunicationTimeout, combined.Token).ConfigureAwait(false); _logger.Verbose("Connection with server established."); _publishPacketReceiverQueue = new AsyncQueue <MqttPublishPacket>(); _publishPacketReceiverTask = Task.Run(() => ProcessReceivedPublishPackets(backgroundCancellationToken), backgroundCancellationToken); _packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken); authenticateResult = await AuthenticateAsync(adapter, options.WillMessage, combined.Token).ConfigureAwait(false); } _lastPacketSentTimestamp = DateTime.UtcNow; if (Options.KeepAlivePeriod != TimeSpan.Zero) { _keepAlivePacketsSenderTask = Task.Run(() => TrySendKeepAliveMessagesAsync(backgroundCancellationToken), backgroundCancellationToken); } CompareExchangeConnectionStatus(MqttClientConnectionStatus.Connected, MqttClientConnectionStatus.Connecting); _logger.Info("Connected."); var connectedHandler = ConnectedHandler; if (connectedHandler != null) { await connectedHandler.HandleConnectedAsync(new MqttClientConnectedEventArgs(authenticateResult)).ConfigureAwait(false); } return(authenticateResult); } catch (Exception exception) { _disconnectReason = MqttClientDisconnectReason.UnspecifiedError; _logger.Error(exception, "Error while connecting with server."); await DisconnectInternalAsync(null, exception, authenticateResult).ConfigureAwait(false); throw; } }
protected virtual void OnConnected(MqttClientAuthenticateResult connected) { }
public static async Task Connect() { string clientId = "OnGuard"; string mqttURI = Storage.GetGlobalString("MQTTServerAddress"); string mqttUser = Storage.GetGlobalString("MQTTUser"); string mqttPassword = Storage.GetGlobalString("MQTTPassword"); int mqttPort = Storage.GetGlobalInt("MQTTPort"); bool mqttSecure = Storage.GetGlobalBool("MQTTUseSecureLink"); var messageBuilder = new MqttClientOptionsBuilder() .WithClientId(clientId) .WithCredentials(mqttUser, mqttPassword) .WithTcpServer(mqttURI, mqttPort) .WithCleanSession(); var options = mqttSecure ? messageBuilder .WithTls() .Build() : messageBuilder .Build(); if (s_client.IsConnected == false) { try { MqttClientAuthenticateResult result = await s_client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false); if (result.ResultCode == MqttClientConnectResultCode.Success) { Dbg.Write("MQTTPublish - Connected to server!"); _loggedError = false; _loggedNotConnected = false; } else { HandleError(result); // Here we let it go setup the disconnect handler -- things may improve in the future } } catch (MqttCommunicationException ex) { if (!_loggedNotConnected) { Dbg.Write("MQTTPublish - The Connection to server failed - it is unreachable - check your server status and your MQTT settings: " + ex.Message); _loggedNotConnected = true; } return; } catch (Exception ex) { if (!_loggedNotConnected) { Dbg.Write("MQTTPublish - Connection to server failed: " + ex.Message); _loggedNotConnected = true; } return; } } }
public MqttConnectingFailedException(MqttClientAuthenticateResult result) : base($"Connecting with MQTT server failed ({result.ResultCode.ToString()}).") { Result = result; }
public async Task <bool> Connect() { using var Trace = new Trace(); //This c# 8.0 using feature will auto dispose when the function is done. bool ret = false; try { this.server = AppSettings.Settings.mqtt_serverandport.GetWord("", ":"); this.port = AppSettings.Settings.mqtt_serverandport.GetWord(":", "/"); this.portint = 0; if (!string.IsNullOrEmpty(this.port)) { this.portint = Convert.ToInt32(this.port); } if (this.portint == 0 && AppSettings.Settings.mqtt_UseTLS) { this.portint = 8883; } else if (this.portint == 0) { this.portint = 1883; } bool IsWebSocket = (AppSettings.Settings.mqtt_serverandport.IndexOf("ws://", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("/mqtt", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("wss://", StringComparison.OrdinalIgnoreCase) >= 0); bool UseTLS = (AppSettings.Settings.mqtt_UseTLS || portint == 8883 || AppSettings.Settings.mqtt_serverandport.IndexOf("wss://", StringComparison.OrdinalIgnoreCase) >= 0); //bool UseCreds = (!string.IsNullOrWhiteSpace(AppSettings.Settings.mqtt_username)); //===================================================================== //Seems like there should be a better way here with this Options builder... //I dont see an obvious way to directly modify options without the builder //and I cant seem to put IF statements around each part of the option builder //parameters. //===================================================================== var lw = new MqttApplicationMessage() { Topic = AppSettings.Settings.mqtt_LastWillTopic, Payload = Encoding.UTF8.GetBytes(AppSettings.Settings.mqtt_LastWillPayload), QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce, Retain = true }; if (UseTLS) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithWillMessage(lw) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithWillMessage(lw) .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithWillMessage(lw) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithWillMessage(lw) .WithCleanSession() .Build(); } } mqttClient.UseDisconnectedHandler(async e => { IsConnected = false; string excp = ""; if (e.Exception != null) { excp = e.Exception.Message; } Log($"Debug: MQTT: ### DISCONNECTED FROM SERVER ### - Reason: {e.Reason}, ClientWasDisconnected: {e.ClientWasConnected}, {excp}"); //reconnect here if needed? }); mqttClient.UseApplicationMessageReceivedHandler(async e => { Log($"Debug: MQTT: ### RECEIVED APPLICATION MESSAGE ###"); Log($"Debug: MQTT: + Topic = {e.ApplicationMessage.Topic}"); Log($"Debug: MQTT: + Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload).Truncate(128, true)}"); Log($"Debug: MQTT: + QoS = {e.ApplicationMessage.QualityOfServiceLevel}"); Log($"Debug: MQTT: + Retain = {e.ApplicationMessage.Retain}"); Log(""); }); mqttClient.UseConnectedHandler(async e => { IsConnected = true; Log($"Debug: MQTT: ### CONNECTED WITH SERVER '{AppSettings.Settings.mqtt_serverandport}' ### - Result: {e.AuthenticateResult.ResultCode}, '{e.AuthenticateResult.ReasonString}'"); MqttApplicationMessage ma = new MqttApplicationMessageBuilder() .WithTopic(AppSettings.Settings.mqtt_LastWillTopic) .WithPayload(AppSettings.Settings.mqtt_OnlinePayload) .WithAtLeastOnceQoS() .WithRetainFlag(true) .Build(); Log($"Debug: MQTT: Sending '{AppSettings.Settings.mqtt_OnlinePayload}' message..."); MqttClientPublishResult res = await mqttClient.PublishAsync(ma, CancellationToken.None); //if (!string.IsNullOrWhiteSpace(this.LastTopic)) //{ // // Subscribe to the topic // MqttClientSubscribeResult res = await mqttClient.SubscribeAsync(this.LastTopic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce); // IsSubscribed = true; // Log($"Debug: MQTT: ### SUBSCRIBED to topic '{this.LastTopic}'"); //} }); Log($"Debug: MQTT: Connecting to server '{this.server}:{this.portint}' with ClientID '{AppSettings.Settings.mqtt_clientid}', Username '{AppSettings.Settings.mqtt_username}', Password '{AppSettings.Settings.mqtt_username.ReplaceChars('*')}'..."); cres = await mqttClient.ConnectAsync(options, CancellationToken.None); } catch (Exception ex) { Log($"Error: {ex.Msg()}"); } return(ret); }
public async Task <bool> Connect() { bool ret = false; try { this.server = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, "", ":"); this.port = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, ":", "/"); this.portint = 0; if (!string.IsNullOrEmpty(this.port)) { this.portint = Convert.ToInt32(this.port); } if (this.portint == 0 && AppSettings.Settings.mqtt_UseTLS) { this.portint = 8883; } else if (this.portint == 0) { this.portint = 1883; } bool IsWebSocket = (AppSettings.Settings.mqtt_serverandport.IndexOf("ws://", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("/mqtt", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("wss://", StringComparison.OrdinalIgnoreCase) >= 0); bool UseTLS = (AppSettings.Settings.mqtt_UseTLS || portint == 8883 || AppSettings.Settings.mqtt_serverandport.IndexOf("wss://", StringComparison.OrdinalIgnoreCase) >= 0); bool UseCreds = (!string.IsNullOrWhiteSpace(AppSettings.Settings.mqtt_username)); //===================================================================== //Seems like there should be a better way here with this Options builder... //I dont see an obvious way to directly modify options without the builder //and I cant seem to put IF statements around each part of the option builder //parameters. //===================================================================== if (UseTLS) { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithTls() .WithCleanSession() .Build(); } } } else { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCleanSession() .Build(); } } } mqttClient.UseDisconnectedHandler(async e => { IsConnected = false; string excp = ""; if (e.Exception != null) { excp = e.Exception.Message; } Log($"Debug: MQTT: ### DISCONNECTED FROM SERVER ### - Reason: {e.ReasonCode}, ClientWasDisconnected: {e.ClientWasConnected}, {excp}"); //reconnect here if needed? }); mqttClient.UseApplicationMessageReceivedHandler(async e => { Log($"Debug: MQTT: ### RECEIVED APPLICATION MESSAGE ###"); Log($"Debug: MQTT: + Topic = {e.ApplicationMessage.Topic}"); if (e.ApplicationMessage.Payload.Length < 64) { Log($"Debug: MQTT: + Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}"); } Log($"Debug: MQTT: + QoS = {e.ApplicationMessage.QualityOfServiceLevel}"); Log($"Debug: MQTT: + Retain = {e.ApplicationMessage.Retain}"); Log(""); }); mqttClient.UseConnectedHandler(async e => { IsConnected = true; Log($"Debug: MQTT: ### CONNECTED WITH SERVER '{AppSettings.Settings.mqtt_serverandport}' ### - Result: {e.AuthenticateResult.ResultCode}, '{e.AuthenticateResult.ReasonString}'"); //if (!string.IsNullOrWhiteSpace(this.LastTopic)) //{ // // Subscribe to the topic // MqttClientSubscribeResult res = await mqttClient.SubscribeAsync(this.LastTopic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce); // IsSubscribed = true; // Log($"Debug: MQTT: ### SUBSCRIBED to topic '{this.LastTopic}'"); //} }); Log($"Debug: MQTT: Connecting to server '{this.server}:{this.portint}'..."); cres = await mqttClient.ConnectAsync(options, CancellationToken.None); } catch (Exception ex) { Log($"Error: {Global.ExMsg(ex)}"); } return(ret); }
private async void btnStartTerminal_Click(object sender, EventArgs e) { try { if (btnSubscribe.Text == "Start") { uiLocked = true; if (Client.IsConnected) { await Client.DisconnectAsync(); } options = new MqttClientOptionsBuilder() .WithTcpServer(connectionForm.GetHost(), connectionForm.GetPort()) .WithCredentials(connectionForm.GetUserName(), connectionForm.GetPassword()) .WithProtocolVersion(MqttProtocolVersion.V311) .Build(); auth = await Client.ConnectAsync(options); if (auth.ResultCode != MqttClientConnectResultCode.Success) { throw new Exception(auth.ResultCode.ToString()); } btnSubscribe.Text = "Stop"; txtTopic.Enabled = false; var result = (await Client.SubscribeAsync( new TopicFilterBuilder() .WithTopic(txtTopic.Text) .Build() )).Items[0]; switch (result.ResultCode) { case MqttClientSubscribeResultCode.GrantedQoS0: case MqttClientSubscribeResultCode.GrantedQoS1: case MqttClientSubscribeResultCode.GrantedQoS2: Client.UseDisconnectedHandler(arg => { disconnectionHandler(arg); }); Client.UseApplicationMessageReceivedHandler((Action <MqttApplicationMessageReceivedEventArgs>)receiveHandler); break; default: throw new Exception(result.ResultCode.ToString()); } } else { btnSubscribe.Text = "Start"; txtTopic.Enabled = true; var result = (await Client.UnsubscribeAsync(txtTopic.Text)).Items[0]; await Client.DisconnectAsync(); switch (result.ReasonCode) { case MQTTnet.Client.Unsubscribing.MqttClientUnsubscribeResultCode.Success: break; //default: //throw new Exception(result.ReasonCode.ToString()); } uiLocked = false; } } catch (Exception ex) { txtTopic.Enabled = true; btnSubscribe.Enabled = true; this.Error(ex); } }
public async Task <MqttClientPublishResult> PublishAsync(string topic, string payload, bool retain, ClsImageQueueItem CurImg) { using var Trace = new Trace(); //This c# 8.0 using feature will auto dispose when the function is done. MqttClientPublishResult res = null; Stopwatch sw = Stopwatch.StartNew(); await Task.Run(async() => { MqttFactory factory = new MqttFactory(); IMqttClient mqttClient = null; bool subscribed = false; bool IsConnected = false; using (mqttClient = factory.CreateMqttClient()) { try { string server = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, "", ":"); string port = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, ":", "/"); int portint = 0; if (!string.IsNullOrEmpty(port)) { portint = Convert.ToInt32(port); } if (portint == 0 && AppSettings.Settings.mqtt_UseTLS) { portint = 8883; } else if (portint == 0) { portint = 1883; } bool IsWebSocket = (AppSettings.Settings.mqtt_serverandport.IndexOf("ws://", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("/mqtt", StringComparison.OrdinalIgnoreCase) >= 0 || AppSettings.Settings.mqtt_serverandport.IndexOf("wss://", StringComparison.OrdinalIgnoreCase) >= 0); bool UseTLS = (AppSettings.Settings.mqtt_UseTLS || portint == 8883 || AppSettings.Settings.mqtt_serverandport.ToLower().Contains("wss://")); bool UseCreds = (!string.IsNullOrWhiteSpace(AppSettings.Settings.mqtt_username)); IMqttClientOptions options; //===================================================================== //Seems like there should be a better way here with this Options builder... //I dont see an obvious way to directly modify options without the builder //and I cant seem to put IF statements around each part of the option builder //parameters. //===================================================================== if (UseTLS) { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithTls() .WithCleanSession() .Build(); } } } else { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCleanSession() .Build(); } } } if (string.IsNullOrWhiteSpace(topic)) { topic = Guid.NewGuid().ToString(); } mqttClient.UseDisconnectedHandler(async e => { IsConnected = false; string excp = ""; if (e.Exception != null) { excp = e.Exception.Message; } Log($"Debug: MQTT: ### DISCONNECTED FROM SERVER ### - Reason: {e.ReasonCode}, ClientWasDisconnected: {e.ClientWasConnected}, {excp}"); //reconnect here if needed? }); mqttClient.UseApplicationMessageReceivedHandler(async e => { Log($"Debug: MQTT: ### RECEIVED APPLICATION MESSAGE ###"); Log($"Debug: MQTT: + Topic = {e.ApplicationMessage.Topic}"); if (e.ApplicationMessage.Payload.Length < 64) { Log($"Debug: MQTT: + Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}"); } Log($"Debug: MQTT: + QoS = {e.ApplicationMessage.QualityOfServiceLevel}"); Log($"Debug: MQTT: + Retain = {e.ApplicationMessage.Retain}"); Log(""); }); mqttClient.UseConnectedHandler(async e => { IsConnected = true; Log($"Debug: MQTT: ### CONNECTED WITH SERVER '{AppSettings.Settings.mqtt_serverandport}' ### - Result: {e.AuthenticateResult.ResultCode}, '{e.AuthenticateResult.ReasonString}'"); // Subscribe to the topic await mqttClient.SubscribeAsync(topic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce); subscribed = true; Log($"Debug: MQTT: ### SUBSCRIBED to topic '{topic}'"); }); Log($"Debug: MQTT: Sending topic '{topic}' with payload '{payload}' to server '{server}:{portint}'..."); MqttClientAuthenticateResult cres = await mqttClient.ConnectAsync(options, CancellationToken.None); if (cres != null && mqttClient.IsConnected && cres.ResultCode == MqttClientConnectResultCode.Success) { IsConnected = true; MqttApplicationMessage ma; if (CurImg != null) { using FileStream image_data = System.IO.File.OpenRead(CurImg.image_path); ma = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(image_data) .WithAtLeastOnceQoS() .WithRetainFlag(retain) .Build(); res = await mqttClient.PublishAsync(ma, CancellationToken.None); if (res.ReasonCode == MqttClientPublishReasonCode.Success) { Log($"Debug: MQTT: ...Sent image in {sw.ElapsedMilliseconds}ms, Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } else { Log($"Error: MQTT: sending image: ({sw.ElapsedMilliseconds}ms) Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } } else { ma = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(payload) .WithAtLeastOnceQoS() .WithRetainFlag(retain) .Build(); res = await mqttClient.PublishAsync(ma, CancellationToken.None); //Success = 0, // NoMatchingSubscribers = 0x10, // UnspecifiedError = 0x80, // ImplementationSpecificError = 0x83, // NotAuthorized = 0x87, // TopicNameInvalid = 0x90, // PacketIdentifierInUse = 0x91, // QuotaExceeded = 0x97, // PayloadFormatInvalid = 0x99 if (res.ReasonCode == MqttClientPublishReasonCode.Success) { Log($"Debug: MQTT: ...Sent in {sw.ElapsedMilliseconds}ms, Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } else { Log($"Error: MQTT: sending: ({sw.ElapsedMilliseconds}ms) Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } } } else if (cres != null) { IsConnected = false; Log($"Error: MQTT: connecting: ({sw.ElapsedMilliseconds}ms) Result: '{cres.ResultCode}' - '{cres.ReasonString}'"); } else { IsConnected = false; Log($"Error: MQTT: Error connecting: ({sw.ElapsedMilliseconds}ms) cres=null"); } if (mqttClient != null && mqttClient.IsConnected && IsConnected) { if (subscribed) { Log($"Debug: MQTT: Unsubscribing from topic '{topic}'"); await mqttClient.UnsubscribeAsync(topic); } if (mqttClient.IsConnected && IsConnected) { Log($"Debug: MQTT: Disconnecting from server."); try { await mqttClient.DisconnectAsync(); } catch (Exception ex) { //dont throw ERROR in the log if fail to disconnect Log($"Debug: MQTT: Could not disconnect from server, got: {Global.ExMsg(ex)}"); } } else { Log($"Debug: MQTT: Already disconnected from server, no need to disconnect."); } IsConnected = false; } } catch (Exception ex) { Log($"Error: MQTT: Unexpected Problem: Topic '{topic}' Payload '{payload}': " + Global.ExMsg(ex)); } finally { if (mqttClient != null && mqttClient.IsConnected) { if (subscribed) { Log($"Debug: MQTT: Un-Subscribing from topic '{topic}'"); await mqttClient.UnsubscribeAsync(topic); } Log($"Debug: MQTT: Disconnecting from server."); await mqttClient.DisconnectAsync(); mqttClient.Dispose(); //using should dispose anyway } } } }); return(res); }
public static MqttStatus Connect(string url, MqttConfig config) { Guid key = Guid.NewGuid(); try { #if DEBUG IMqttClient client = new MqttFactory().CreateMqttClient(new ConsoleLogger()); #else IMqttClient client = new MqttFactory().CreateMqttClient(); #endif var b = new MqttClientOptionsBuilder() .WithTcpServer(url, config.Port) .WithKeepAlivePeriod(TimeSpan.FromSeconds(config.KeepAlive)) .WithMaximumPacketSize(Convert.ToUInt32(config.BufferSize)) .WithCommunicationTimeout(TimeSpan.FromSeconds(config.ConnectionTimeout)) .WithCleanSession(config.CleanSession); if (config.SessionExpiryInterval > 0) { b = b.WithSessionExpiryInterval((uint)config.SessionExpiryInterval); } if (!string.IsNullOrEmpty(config.ClientId)) { b = b.WithClientId(config.ClientId); } if (!config.SSLConnection) { b = b.WithCredentials(config.UserName, config.Password); } switch (config.ProtocolVersion) { case 310: b = b.WithProtocolVersion(MqttProtocolVersion.V310); break; case 311: b = b.WithProtocolVersion(MqttProtocolVersion.V311); break; case 500: b = b.WithProtocolVersion(MqttProtocolVersion.V500); break; default: throw new InvalidDataException("Invalid protocol versions. Valid versions are 310, 311 or 500"); } if (config.SSLConnection) { string base64CACert = RSAKeys.GetPlainBase64(config.CAcertificate); X509Certificate2 caCert = new X509Certificate2(Convert.FromBase64String(base64CACert)); byte[] caBytes = caCert.Export(X509ContentType.Cert); string base64Client = RSAKeys.GetPlainBase64(config.ClientCertificate); X509Certificate2 cliCert = new X509Certificate2(Convert.FromBase64String(base64Client), config.ClientCerificatePassphrase); cliCert = cliCert.CopyWithPrivateKey(RSAKeys.ImportPrivateKey(config.PrivateKey, new PasswordFinder(config.ClientCerificatePassphrase))); byte[] cliBytes = cliCert.Export(X509ContentType.Pfx); try { var tls = new MqttClientOptionsBuilderTlsParameters { SslProtocol = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls, UseTls = true, AllowUntrustedCertificates = true, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, Certificates = new List <X509Certificate>() { caCert, cliCert }, //CertificateValidationHandler = context => true CertificateValidationCallback = (certificate, chain, sslError, opts) => true }; b = b.WithTls(tls); } finally { caCert.Dispose(); cliCert.Dispose(); } } client.UseDisconnectedHandler(async e => { try { if (Connections.ContainsKey(key)) { await Task.Delay(TimeSpan.FromSeconds(config.AutoReconnectDelay)); MqttClientAuthenticateResult reconnectResult = await client.ConnectAsync(b.Build()); SubscribePreviousConnection(key, reconnectResult); } } catch { Connections.Remove(key); client.Dispose(); } }); MqttClientAuthenticateResult result = client.ConnectAsync(b.Build()).GetAwaiter().GetResult(); MqttClient mqtt = new MqttClient(client, config); Connections[key] = mqtt; SubscribePreviousConnection(key, result); } catch (Exception ex) { return(MqttStatus.Fail(Guid.Empty, ex)); } return(MqttStatus.Success(key)); }
public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult) { ClientWasConnected = clientWasConnected; Exception = exception; AuthenticateResult = authenticateResult; }
public static async Task Connect() { string clientId = "OnGuard"; string mqttURI = Settings.Default.MQTTServerAddress; string mqttUser = Settings.Default.MQTTUser; string mqttPassword = Settings.Default.MQTTPassword; int mqttPort = Settings.Default.MQTTPort; bool mqttSecure = Settings.Default.MQTTUseSecureLink; var messageBuilder = new MqttClientOptionsBuilder() .WithClientId(clientId) .WithCredentials(mqttUser, mqttPassword) .WithTcpServer(mqttURI, mqttPort) .WithCleanSession(); var options = mqttSecure ? messageBuilder .WithTls() .Build() : messageBuilder .Build(); _ = s_client.UseDisconnectedHandler(async e => { Dbg.Write("MQTTPublish - Server Disconnected"); if (_retryDelay > 0) { await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); } _retryDelay = 5; try { MqttClientAuthenticateResult disconnectRetryResult = await s_client.ConnectAsync(options).ConfigureAwait(false); if (disconnectRetryResult.ResultCode != MqttClientConnectResultCode.Success) { HandleError(disconnectRetryResult); } else { Dbg.Write("MQTTPublish - Connected succeeded after retry"); s_ready.Set(); } } catch (Exception ex) { Dbg.Write("MQTTPublish - Reconnection Failed: " + ex.Message); } }); if (s_client.IsConnected == false) { try { MqttClientAuthenticateResult result = await s_client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false); s_ready.Set(); if (result.ResultCode == MqttClientConnectResultCode.Success) { Dbg.Write("MQTTPublish - Connected to server!"); } else { HandleError(result); // Here we let it go setup the disconnect handler -- things may improve in the future } } catch (Exception ex) { Dbg.Write("MQTTPublish - Connection to server failed: " + ex.Message); s_ready.Set(); // Well, it isn't "ready", but there is no sense waiting for a connection that will never come return; } } }
public async Task <MQTTnet.Client.Connecting.MqttClientAuthenticateResult> ConnectAsync(CancellationToken cancellationToken) { var cancelToken = cancellationToken != null ? cancellationToken : CancellationToken.None; MqttClientAuthenticateResult connectPrimary = null; if (!PrimaryClient.IsConnected) { PrimaryClient.UseConnectedHandler(async e => { var primaryFilters = Options.PrimaryFilters != null && Options.PrimaryFilters.Any() ? Options.PrimaryFilters : new TopicFilter[] { new TopicFilterBuilder().WithTopic("#").Build() }; await PrimaryClient.SubscribeAsync(primaryFilters); }); connectPrimary = await PrimaryClient.ConnectAsync(Options.PrimaryOptions, cancelToken); if (connectPrimary.ResultCode != MqttClientConnectResultCode.Success) { throw new ArgumentException("PrimaryOptions, could not connect to primary server."); } } if (!SecondaryClient.IsConnected) { var connectSecondary = await SecondaryClient.ConnectAsync(Options.SecondaryOptions, cancelToken); if (connectSecondary.ResultCode != MqttClientConnectResultCode.Success) { throw new ArgumentException("SecondaryOptions, could not connect to secondary server."); } } PrimaryClient.UseDisconnectedHandler(async e => { var connectRetry = Policy .Handle <Exception>() .WaitAndRetryForeverAsync( retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (exception, timespan) => { Console.WriteLine("### DISCONNECTED FROM SERVER ###"); }); await connectRetry.ExecuteAsync(async() => { var response = await PrimaryClient.ConnectAsync(Options.PrimaryOptions, cancelToken); Console.Write($"{response.ResultCode} {response.ReasonString}"); }); }); SecondaryClient.UseDisconnectedHandler(async e => { var connectRetry = Policy .Handle <Exception>() .WaitAndRetryForeverAsync( retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (exception, timespan) => { Console.WriteLine("### DISCONNECTED FROM SERVER ###"); }); await connectRetry.ExecuteAsync(async() => { var response = await SecondaryClient.ConnectAsync(Options.SecondaryOptions, cancelToken); Console.Write($"{response.ResultCode} {response.ReasonString}"); }); }); PrimaryClient.UseApplicationMessageReceivedHandler(e => { var message = new MqttApplicationMessageBuilder() .WithTopic(e.ApplicationMessage.Topic) .WithPayload(e.ApplicationMessage.Payload); if (e.ApplicationMessage.Retain) { message = message.WithRetainFlag(); } switch (e.ApplicationMessage.QualityOfServiceLevel) { case MqttQualityOfServiceLevel.ExactlyOnce: message = message.WithExactlyOnceQoS(); break; case MqttQualityOfServiceLevel.AtLeastOnce: message = message.WithAtLeastOnceQoS(); break; case MqttQualityOfServiceLevel.AtMostOnce: message = message.WithAtMostOnceQoS(); break; default: throw new ArgumentOutOfRangeException(); } Task.Run(() => SecondaryClient.PublishAsync(message.Build(), cancelToken), cancelToken); }); if (Options.SyncMode) { SecondaryClient.UseConnectedHandler(async e => { var secondaryFilters = Options.SecondaryFilters != null && Options.SecondaryFilters.Any() ? Options.SecondaryFilters : new TopicFilter[] { new TopicFilterBuilder().WithTopic("#").Build() }; await SecondaryClient.SubscribeAsync(secondaryFilters); }); SecondaryClient.UseApplicationMessageReceivedHandler(e => { var message = new MqttApplicationMessageBuilder() .WithTopic(e.ApplicationMessage.Topic) .WithPayload(e.ApplicationMessage.Payload); if (e.ApplicationMessage.Retain) { message = message.WithRetainFlag(); } switch (e.ApplicationMessage.QualityOfServiceLevel) { case MqttQualityOfServiceLevel.ExactlyOnce: message = message.WithExactlyOnceQoS(); break; case MqttQualityOfServiceLevel.AtLeastOnce: message = message.WithAtLeastOnceQoS(); break; case MqttQualityOfServiceLevel.AtMostOnce: message = message.WithAtMostOnceQoS(); break; default: throw new ArgumentOutOfRangeException(); } Task.Run(() => PrimaryClient.PublishAsync(message.Build(), cancelToken), cancelToken); }); } return(connectPrimary); }
public MqttConnectingFailedException(string message, Exception innerException, MqttClientAuthenticateResult authenticateResult) : base(message, innerException) { Result = authenticateResult; }
public async Task <MqttClientAuthenticateResult> ConnectAsync(IMqttClientOptions options, CancellationToken cancellationToken) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (options.ChannelOptions == null) { throw new ArgumentException("ChannelOptions are not set."); } ThrowIfConnected("It is not allowed to connect with a server after the connection is established."); ThrowIfDisposed(); MqttClientAuthenticateResult authenticateResult = null; try { Options = options; _packetIdentifierProvider.Reset(); _packetDispatcher.Reset(); _backgroundCancellationTokenSource = new CancellationTokenSource(); var backgroundCancellationToken = _backgroundCancellationTokenSource.Token; _isDisconnectPending = 0; var adapter = _adapterFactory.CreateClientAdapter(options); _adapter = adapter; using (var combined = CancellationTokenSource.CreateLinkedTokenSource(backgroundCancellationToken, cancellationToken)) { _logger.Verbose($"Trying to connect with server '{options.ChannelOptions}' (Timeout={options.CommunicationTimeout})."); await _adapter.ConnectAsync(options.CommunicationTimeout, combined.Token).ConfigureAwait(false); _logger.Verbose("Connection with server established."); _publishPacketReceiverQueue = new AsyncQueue <MqttPublishPacket>(); _publishPacketReceiverTask = Task.Run(() => ProcessReceivedPublishPackets(backgroundCancellationToken), backgroundCancellationToken); _packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken); authenticateResult = await AuthenticateAsync(adapter, options.WillMessage, combined.Token).ConfigureAwait(false); } _sendTracker.Restart(); _receiveTracker.Restart(); if (Options.KeepAlivePeriod != TimeSpan.Zero) { _keepAlivePacketsSenderTask = Task.Run(() => TrySendKeepAliveMessagesAsync(backgroundCancellationToken), backgroundCancellationToken); } _isConnected = true; _logger.Info("Connected."); var connectedHandler = ConnectedHandler; if (connectedHandler != null) { await connectedHandler.HandleConnectedAsync(new MqttClientConnectedEventArgs(authenticateResult)).ConfigureAwait(false); } return(authenticateResult); } catch (Exception exception) { _logger.Error(exception, "Error while connecting with server."); if (!DisconnectIsPending()) { await DisconnectInternalAsync(null, exception, authenticateResult).ConfigureAwait(false); } throw; } }
public async Task <MqttClientPublishResult> PublishAsync(string topic, string payload) { MqttClientPublishResult res = null; Stopwatch sw = Stopwatch.StartNew(); await Task.Run(async() => { MqttFactory factory = new MqttFactory(); IMqttClient mqttClient = null; bool subscribed = false; using (mqttClient = factory.CreateMqttClient()) { try { string server = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, "", ":"); string port = Global.GetWordBetween(AppSettings.Settings.mqtt_serverandport, ":", "/"); int portint = 0; if (!string.IsNullOrEmpty(port)) { portint = Convert.ToInt32(port); } if (portint == 0 && AppSettings.Settings.mqtt_UseTLS) { portint = 8883; } else if (portint == 0) { portint = 1883; } bool IsWebSocket = (AppSettings.Settings.mqtt_serverandport.ToLower().Contains("ws://") || AppSettings.Settings.mqtt_serverandport.ToLower().Contains("/mqtt") || AppSettings.Settings.mqtt_serverandport.ToLower().Contains("wss://")); bool UseTLS = (AppSettings.Settings.mqtt_UseTLS || portint == 8883 || AppSettings.Settings.mqtt_serverandport.ToLower().Contains("wss://")); bool UseCreds = (!string.IsNullOrWhiteSpace(AppSettings.Settings.mqtt_username)); IMqttClientOptions options; //===================================================================== //Seems like there should be a better way here with this Options builder... //===================================================================== if (UseTLS) { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithTls() .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithTls() .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithTls() .WithCleanSession() .Build(); } } } else { if (UseCreds) { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCredentials(AppSettings.Settings.mqtt_username, AppSettings.Settings.mqtt_password) .WithCleanSession() .Build(); } } else { if (IsWebSocket) { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithTcpServer(server, portint) .WithCleanSession() .Build(); } else { options = new MqttClientOptionsBuilder() .WithClientId(AppSettings.Settings.mqtt_clientid) .WithWebSocketServer(AppSettings.Settings.mqtt_serverandport) .WithCleanSession() .Build(); } } } if (string.IsNullOrWhiteSpace(topic)) { topic = Guid.NewGuid().ToString(); } mqttClient.UseDisconnectedHandler(async e => { string excp = ""; if (e.Exception != null) { excp = e.Exception.Message; } Global.Log($"MQTT: ### DISCONNECTED FROM SERVER ### - Reason: {e.ReasonCode}, ClientWasDisconnected: {e.ClientWasConnected}, {excp}"); //reconnect here if needed? }); mqttClient.UseApplicationMessageReceivedHandler(async e => { Global.Log($"MQTT: ### RECEIVED APPLICATION MESSAGE ###"); Global.Log($"MQTT: + Topic = {e.ApplicationMessage.Topic}"); Global.Log($"MQTT: + Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}"); Global.Log($"MQTT: + QoS = {e.ApplicationMessage.QualityOfServiceLevel}"); Global.Log($"MQTT: + Retain = {e.ApplicationMessage.Retain}"); Global.Log(""); }); mqttClient.UseConnectedHandler(async e => { Global.Log($"MQTT: ### CONNECTED WITH SERVER '{AppSettings.Settings.mqtt_serverandport}' ### - Result: {e.AuthenticateResult.ResultCode}, '{e.AuthenticateResult.ReasonString}'"); // Subscribe to the topic await mqttClient.SubscribeAsync(topic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce); subscribed = true; Global.Log($"MQTT: ### SUBSCRIBED to topic '{topic}'"); }); Global.Log($"MQTT: Sending topic '{topic}' with payload '{payload}' to server '{server}:{portint}'..."); MqttClientAuthenticateResult cres = await mqttClient.ConnectAsync(options, CancellationToken.None); if (cres != null && cres.ResultCode == MqttClientConnectResultCode.Success) { MqttApplicationMessage ma = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(payload) .WithAtLeastOnceQoS() .Build(); res = await mqttClient.PublishAsync(ma, CancellationToken.None); //Success = 0, // NoMatchingSubscribers = 0x10, // UnspecifiedError = 0x80, // ImplementationSpecificError = 0x83, // NotAuthorized = 0x87, // TopicNameInvalid = 0x90, // PacketIdentifierInUse = 0x91, // QuotaExceeded = 0x97, // PayloadFormatInvalid = 0x99 if (res.ReasonCode == MqttClientPublishReasonCode.Success) { Global.Log($"MQTT: ...Sent in {sw.ElapsedMilliseconds}ms, Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } else { Global.Log($"MQTT: Error sending: ({sw.ElapsedMilliseconds}ms) Reason: '{res.ReasonCode}' ({Convert.ToInt32(res.ReasonCode)} - '{res.ReasonString}')"); } } else if (cres != null) { Global.Log($"MQTT: Error connecting: ({sw.ElapsedMilliseconds}ms) Result: '{cres.ResultCode}' - '{cres.ReasonString}'"); } else { Global.Log($"MQTT: Error connecting: ({sw.ElapsedMilliseconds}ms) cres=null"); } if (mqttClient != null && mqttClient.IsConnected) { if (subscribed) { Global.Log($"MQTT: Unsubscribing from topic '{topic}'"); await mqttClient.UnsubscribeAsync(topic); } Global.Log($"MQTT: Disconnecting from server."); await mqttClient.DisconnectAsync(); } } catch (Exception ex) { Global.Log($"MQTT: Unexpected Error: Topic '{topic}' Payload '{payload}': " + Global.ExMsg(ex)); } finally { if (mqttClient != null && mqttClient.IsConnected) { if (subscribed) { Global.Log($"MQTT: Unsubscribing from topic '{topic}'"); await mqttClient.UnsubscribeAsync(topic); } Global.Log($"MQTT: Disconnecting from server."); await mqttClient.DisconnectAsync(); mqttClient.Dispose(); //using should dispose anyway } } } }); return(res); }