• C# Mqtt 断线重连


    在通过 MqttClient 客户端连接之后,在服务端服务重启时,客户端如果没有重连机制,则无法再接收到订阅的消息。

    使用的 Mqtt 组件为:M2Mqtt.Net.dll

    一些特性发现

    (1)如果提供的服务端地址是不可解析的,会引发异常无法实例化 MqttClient 对象。
    (2)Connect 无法连接时会引发异常,IsConnected 为 false。
    (3)服务端断开会触发客户端的 ConnectionClosed 事件,IsConnected 为 false。
    (4)重新 Connect 需要重新 Subscribe 订阅主题。
    (5)MqttClient.Subscribe 第一个参数为订阅主题数组,第二个为相应的 qosLevel,两个数组长度必须一致,否则会异常。

    重连流程控制

    主要代码实现

    (1)线程主体

    // 自动重连主体
    private void _TryContinueConnect()
    {
        if (IsConnected) return;
    
        Thread retryThread = new Thread(new ThreadStart(delegate
        {
            while (_MqttClient == null || !_MqttClient.IsConnected)
            {
                if (_ToClose) break;
    
                if (_MqttClient == null)
                {
                    _BuildClient();
                    Thread.Sleep(3000);
                    continue;
                }
    
                try
                {
                    _TryCount++;
                    _Connect(); 
                }
                catch (Exception ce)
                {
                    Debug.WriteLine("re connect exception:" + ce.Message);
                }
    
                // 如果还没连接不符合结束条件则睡2秒
                if (!_MqttClient.IsConnected)
                {
                    Thread.Sleep(2000);
                }
            }
        }));
                
        retryThread.Start();
    }
    

     (2)实例化部分

    // 实例化客户端
    private void _BuildClient()
    {
        try
        {
            _MqttClient = new MqttClient(_MqttServer);
        }
        catch (Exception e)
        {
            Debug.WriteLine("build client error:" + e.Message);
            return;
        }
    
        // 消息到达事件绑定
        _MqttClient.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
    
        // 连接断开事件绑定
        _MqttClient.ConnectionClosed += (sender, e) =>
        {
            if (!_ToClose)
            {
                // 尝试重连
                _TryContinueConnect();
            }
        };
    }
    

     (3)尝试连接部分

    // 发起一次连接,连接成功则订阅相关主题 
    private void _Connect()
    {
        if (String.IsNullOrEmpty(_MqttUsername))
        {
            var b = _MqttClient.Connect(_MqttClientId);
        }
        else
        {
            var b = _MqttClient.Connect(_MqttClientId, _MqttUsername, _MqttUserpass);
        } 
    
        if (_MqttClient.IsConnected)
        {
            _MqttClient.Subscribe(new string[] { "topic1", "topic2" },
                new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });
        }
    }
    
  • 相关阅读:
    JavaScript面向对象精要(一)
    触摸事件
    移动端触摸事件介绍
    总结js常用函数和常用技巧(持续更新)
    JavaScript 常用函数总结
    windows环境下安装vue+webpack的开发环境
    js面向对象,多种创建对象方法!
    javascript遍历算法与技巧
    前端工作面试问题--摘取自github
    c++刷题(27/100)反转单项链表,链表的倒数第k个
  • 原文地址:https://www.cnblogs.com/netcs/p/11505143.html
Copyright © 2020-2023  润新知