• 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 });
        }
    }
    

    实测效果不错,其中延时时间可以适当调整。

  • 相关阅读:
    SAP:建表时如果有QUAN、CURR类型的字段不能激活的问题
    ABAP:ALV的 Header中添加HTML内容
    iframe中cookie失效问题
    让flash自动显示代码提示的两种方式
    event.srcElement说明,方法,技巧
    ABAP:FI常用BAPI
    加入收藏夹功能(jQuery)
    ABAP笔记:BDC完整版例子
    BDC处理时用到结构BDCDATA
    ABAP 自动生成EXCEL文件并作简单格式处理
  • 原文地址:https://www.cnblogs.com/timeddd/p/11435450.html
Copyright © 2020-2023  润新知