Exemplo n.º 1
0
        /// <summary>
        /// Constructor of client and serializer
        /// </summary>
        /// <param name="InternalClientInfo"></param>
        public MqttClient(ConnectConfig config)
        {
            _config = config;
            //建立MqttClient物件
            _client = new MqttFactory().CreateMqttClient() as MQTTnet.Client.MqttClient;
            _client.Disconnected += MqttClient_Disconnected;
            _mqttStatus           = MqttBrokerConnectionStatus.DisConnected;

            _mqttClientRunningThread = new Thread(new ThreadStart(mqttClientRunningProcess));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create new connection
        /// </summary>
        private void mqttClientRunningProcess()
        {
            _isRunningThread = true;
            Task connectTask    = null;
            Task publishTask    = null;
            Task disConnectTask = null;

            int maxPublishFailTimes = 15;
            int maxReconnectTimes   = 10;

            int numOfReconnectTimes   = 0;
            int numOfPublishFailTimes = 0;

            //MQTT Connection Options
            var options = new MqttClientOptionsBuilder()
                          .WithClientId($"{Convert.ToBase64String(Guid.NewGuid().ToByteArray())}")
                          .WithTcpServer(_config.IpAddress.ToString(), _config.Port)
                          .WithCredentials(_config.UserName, _config.Password)
                          .WithKeepAlivePeriod(new TimeSpan(200000000))
                          .WithCommunicationTimeout(TimeSpan.FromSeconds(3000))
                          .WithCleanSession()
                          .WithProtocolVersion(MQTTnet.Serializer.MqttProtocolVersion.V311)
                          .Build();

            MqttApplicationMessage[] publishingMessages = null;

            while (_isRunningThread)
            {
                Thread.Sleep(0);

                if (_client == null)
                {
                    continue;
                }

                switch (_mqttStatus)
                {
                case MqttBrokerConnectionStatus.DisConnected:

                    #region DisConnected

                    if (numOfReconnectTimes++ > maxReconnectTimes)
                    {
                        numOfReconnectTimes = 0;
                        Thread.Sleep(10000);
                    }

                    // Create TCP based options using the builder.
                    _mqttStatus = MqttBrokerConnectionStatus.Connecting;
                    Console.WriteLine($"Start Connecting");

                    try
                    {
                        connectTask = _client.ConnectAsync(options);
                        connectTask.ConfigureAwait(false);
                    }
                    catch
                    {
                        _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                    }
                    #endregion

                    break;

                case MqttBrokerConnectionStatus.Connecting:

                    #region Connecting

                    switch (connectTask.Status)
                    {
                    //工作成功完成
                    case TaskStatus.RanToCompletion:
                        Console.WriteLine("Connected");
                        _mqttStatus = MqttBrokerConnectionStatus.Connected;
                        break;

                    //工作失敗
                    case TaskStatus.Faulted:
                        Console.WriteLine($"Connecting Fail.");
                        _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                        break;

                    //工作取消
                    case TaskStatus.Canceled:
                        Console.WriteLine($"Connecting canceled");
                        _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                        break;
                    }
                    break;

                    #endregion

                //已經連線
                case MqttBrokerConnectionStatus.Connected:

                    #region Connected

                    if (publishTask == null)     //沒有 publishTask 在運行,發送新的Publish Task
                    {
                        if (!_client.IsConnected)
                        {
                            _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                            continue;
                        }

                        if (_waitForPublishMessages.Any())
                        {
                            if (_waitForPublishMessages.Count() < 100)
                            {
                                publishingMessages = _waitForPublishMessages.ToArray();
                            }
                            else
                            {
                                publishingMessages = _waitForPublishMessages.Take(100).ToArray();
                            }

                            try
                            {
                                publishTask = _client.PublishAsync(publishingMessages);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"Publishing Fail.");
                                _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                            }
                        }
                        else
                        {
                            Thread.Sleep(1);
                        }
                    }
                    else
                    {
                        switch (publishTask.Status)
                        {
                        case TaskStatus.RanToCompletion:

                            MqttApplicationMessage deQueueMsg;
                            for (int index = 0; index < publishingMessages.Length; index++)
                            {
                                _waitForPublishMessages.TryDequeue(out deQueueMsg);
                            }

                            numOfPublishFailTimes = 0;
                            //清空工作
                            publishTask.Dispose();
                            publishTask = null;
                            break;

                        case TaskStatus.Faulted:

                            numOfPublishFailTimes++;
                            Console.WriteLine($"Publishing Fail.");

                            if (publishTask.Exception != null)
                            {
                                _mqttStatus = MqttBrokerConnectionStatus.DisConnecting;
                            }

                            //清空工作
                            publishTask = null;

                            if (numOfPublishFailTimes > maxPublishFailTimes)
                            {
                                numOfPublishFailTimes = 0;
                                _mqttStatus           = MqttBrokerConnectionStatus.DisConnecting;
                            }
                            break;

                        case TaskStatus.Canceled:

                            numOfPublishFailTimes++;
                            //清空工作
                            publishTask = null;

                            if (numOfPublishFailTimes > maxPublishFailTimes)
                            {
                                numOfPublishFailTimes = 0;
                                _mqttStatus           = MqttBrokerConnectionStatus.DisConnecting;
                            }
                            break;
                        }
                    }
                    break;

                    #endregion

                case MqttBrokerConnectionStatus.DisConnecting:

                    if (disConnectTask == null)
                    {
                        Console.WriteLine($"DisConnecting.");
                        try
                        {
                            disConnectTask = _client.DisconnectAsync();
                        }
                        catch
                        {
                            Console.WriteLine($"DisConnected.");
                            disConnectTask = null;
                            _mqttStatus    = MqttBrokerConnectionStatus.DisConnected;
                        }
                    }
                    else
                    {
                        if (disConnectTask.IsCompleted)
                        {
                            Console.WriteLine($"DisConnected.");
                            disConnectTask = null;
                            _mqttStatus    = MqttBrokerConnectionStatus.DisConnected;
                        }
                    }
                    break;
                }
            }
        }