Exemplo n.º 1
0
        private static void HandleDisconnect(MqttClientAuthenticateResult mqttClientAuthenticateResult)
        {
            Console.WriteLine("Got disconnection");
            var result = mqttClientAuthenticateResult;

            Console.WriteLine(result.ReasonString);
        }
Exemplo n.º 2
0
 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}].");
     }
 }
Exemplo n.º 3
0
        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;
            }
        }
Exemplo n.º 4
0
        public async Task <bool> StartUpClientAsync()
        {
            _ = InitClient();
            MqttClientAuthenticateResult mqttRs = await mqttClient.ConnectAsync(options);

            return(mqttRs.ResultCode == MqttClientConnectResultCode.Success);
        }
Exemplo n.º 5
0
        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);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        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
            });
        }
Exemplo n.º 7
0
 public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult, MqttClientDisconnectReason reasonCode)
 {
     ClientWasConnected = clientWasConnected;
     Exception          = exception;
     AuthenticateResult = authenticateResult;
     ReasonCode         = reasonCode;
 }
Exemplo n.º 8
0
        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);
                }
            }
        }
Exemplo n.º 9
0
        Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult)
        {
            var clientWasConnected = IsConnected;

            if (!DisconnectIsPendingOrFinished())
            {
                return(DisconnectCoreAsync(sender, exception, authenticateResult, clientWasConnected));
            }

            return(PlatformAbstractionLayer.CompletedTask);
        }
Exemplo n.º 10
0
 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)
             );
     }
 }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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);
            }
        }
Exemplo n.º 13
0
        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);
                }
            }
        }
Exemplo n.º 14
0
        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);
                }
            }
        }
Exemplo n.º 15
0
        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;
        }
Exemplo n.º 16
0
        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;
            }
        }
Exemplo n.º 17
0
 protected virtual void OnConnected(MqttClientAuthenticateResult connected)
 {
 }
Exemplo n.º 18
0
        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;
                }
            }
        }
Exemplo n.º 19
0
 public MqttConnectingFailedException(MqttClientAuthenticateResult result)
     : base($"Connecting with MQTT server failed ({result.ResultCode.ToString()}).")
 {
     Result = result;
 }
Exemplo n.º 20
0
        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);
        }
Exemplo n.º 21
0
        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);
        }
Exemplo n.º 22
0
        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);
            }
        }
Exemplo n.º 23
0
        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);
        }
Exemplo n.º 24
0
        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));
        }
Exemplo n.º 25
0
 public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult)
 {
     ClientWasConnected = clientWasConnected;
     Exception          = exception;
     AuthenticateResult = authenticateResult;
 }
Exemplo n.º 26
0
        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;
                }
            }
        }
Exemplo n.º 27
0
        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;
 }
Exemplo n.º 29
0
        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;
            }
        }
Exemplo n.º 30
0
        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);
        }