mqtt客户端不停重连服务器的问题

最近在一个物联网项目中用到了MQTT协议通信。在开发过程中网页端通过websocket连接到MQTT服务器后,不停的弹出“连接成功”的提醒。

由于网页中同时采用layui,use()和require.js加载了一些外部扩展,所以首先排查了是否是JS冲突导致的。

经过一番排查,最终问题锁定在了client_id上。发现造成客户端不断重连的原因竟然是由于client_id造成的。即:网页写死client_id后,若建立连接时clean设置为true(清理会话)。则会造成此类问题。因此最后的解决办法就是在client_id后增加了一个随机数

附MQTT网页代码:

  1. let device_id = '{$device.id}';
  2.     //MQTT通讯,正式上线后要将配置文件放到后端处理,以防止网页爬虫
  3.     require(['mqtt'],function (mqtt){
  4.         var ws_opt = '';
  5.         var ws_url = '';
  6.         var gateway = 0;
  7.         $.ajax({
  8.             url:'{:url("/admin/api/websockets")}',
  9.             data:{device_id:device_id},
  10.             dataType:'json',
  11.             async:false,   //必须同步请求,不能异步
  12.             method:'POST',
  13.             success:function (res) {
  14.                 if(res.code == 200){
  15.                     ws_url = res.data.url;
  16.                     ws_opt = {clean: true,connectTimeout: res.data.connectTimeout,clientId:res.data.clientId+Math.round(Math.random()*800+100),username:res.data.username,password:res.data.password};
  17.                     gateway = res.data.gateway;
  18.                 }else{
  19.                     console.log("初始化失败:"+res.msg);
  20.                 }
  21.             }
  22.         })
  23.         if(ws_url == '' || ws_opt.length < 5){
  24.             return false;
  25.         }
  26.         const client = mqtt.connect(ws_url,ws_opt);
  27.         client.on('connect',(success)=>{
  28.             client.subscribe('at/data',{qos:0},function (err) {
  29.                 if(!err){
  30.                     $.msg.tips("服务器连接成功");
  31.                 }else{
  32.                     $.msg.error(err);
  33.                 }
  34.             })
  35.         });
  36.         client.on('error',(error)=>{
  37.             $.msg.error(error);
  38.         })
  39.         client.on('message',(topic,message)=>{
  40.             var msg = JSON.parse(message.toString());
  41.             //判断网关ClientID
  42.             if(msg.a == gateway && msg.d == device_id ){
  43.                 //核心逻辑开始-begin
  44.                 var msgArr = msg.vs;
  45.                 msgArr.forEach(function (item,key) {
  46.                     var inname = "data"+key;
  47.                     var tmp_val = item.toString().split(",");
  48.                     $("input[name='"+ inname +"']").val(tmp_val[1]);
  49.                 })
  50.                 //核心逻辑结束-end
  51.             }
  52.         })
  53.     });

由于MQTT采用订阅和发布模式,因此在数据处理方面要区分网关或客户端发布的消息。

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!