解决 mqtt 诡异重复连接问题

以下问题为 阿里云 mqtt 使用过程中发现

一、首先贴出简单核心代码如下


client.on('connect', function () {
    client.publish('test/clientE', '' + (Math.random() * 10).toFixed(2), {'qos': 2, 'retain': true}, function (err) {
        if (err) {
            console.log(err)
        } else {
            console.log('消息发送成功')
        }
    })
})

二、运行结果如下

在这里插入图片描述
三、结果分析

正常情况下连接上只会发送一条消息,但结果显然不是,于是我打开 Wireshark 进行抓包分析如下

在这里插入图片描述
四、原因分析

从上图中可以看到,客户端一直在连接服务器,导致一直出发 connect 事件,导致结果就是一直发布消息,并不是理想中的只

发布一条消息。

我看了 mqtt.js 中的 connect事件,如下

事件 ‘connect’

function (connack) {}

在成功(重新)连接时发出(即connack rc = 0)。

connack收到connack数据包。当clean连接选项为false且服务器具有连接选项的上一个会话时clientId,则

connack.sessionPresent标志为true。在这种情况下,您可能依赖于存储的会话,而不希望不为客户端发送订阅命令。

结论:看到这里我想可能存在重复的 clientId 连接。(就是存在两个客户端 clientId 相同,两个在打架,一直争同一连接,
导致一直重连,重复发布消息

五、解决方法

1、使用 client 的 connected 属性进行判断,简单判断如下


exports.pubMsg = function (ms) {
    if (!client.connected) {
        client.on('connect', function () {
            console.log('连接成功')
        })
    } else {
        client.publish('test/clientE', ms, {'qos': 2}, function (err) {
            if (err) {
                console.log(err)
            }
        })
    }
}

connected 判断是否已成功连接服务器

2、保证你的 clientId 全局唯一

Client ID 由两部分组成,组织形式为 @@@,GroupID 代表一类设备,会重复,则使用 DeviceID 保证实

例 Id 唯一,因为我做的测试,DeviceID 都是随便写的导致出现如上问题,如果正式用在生产环境,DeviceID 可以用物联网设

备的设备ID 代替,可以保证全局唯一,但还是有必要加上上面的方法一。

猜你喜欢

转载自blog.csdn.net/qq_41538097/article/details/107961192
今日推荐