记vue集成阿里微消息队列MQTT更新设备实时状态

通过阿里的的微消息队列MQTT监测客户端状态,后端把状态通过MQTT传到前端实时更新客户端状态

1、在vue状态管理里面创建mqtt客户端连接,用来接收后端传来的要更新的客户端状态;

store/index.js主要代码

const mqttClient = localStorage.getItem("mqttClient")
export default new Vuex.Store({
    state: {
        mqttClient
    },
    mutations: {
        changeMqtt(state, mqtt) {
            state.mqttClient = mqtt
        }
    },

 actions: {
        mqttServer({
            commit
        }) {
            var cid = "客户端id";
            var pwd = CryptoJS.HmacSHA1(cid, "阿里Access Key Secret").toString(CryptoJS.enc.Base64);
            var mqttOptions = {
                username: "Signature|阿里AccessKey ID|MQTT实例ID",
                password: pwd,
                clientId: cid,
                keepalive: 90,
                connectTimeout: 3000
            }
            console.log('mmmm', 'password:'+pwd+"clientId:"+cid)
            var client = mqtt.connect('ws://MQTT地址:80', mqttOptions)
            client.on('connect', function() {
                localStorage.setItem("mqttClient", client);
                console.log("连接mqtt成功!" + userInfo.id);
                commit('changeMqtt', client)
            })
        }
   }

2、在客户端显示页面获取MQTT对象并订阅相关推送状态主题;

mapPage.vue主要代码

import { mapState } from "vuex"
var devises=new Map();
 computed: {
     ...mapState(["mqttClient"])
  },

   addMarker(lng, lat,status,module) {
      var marker;
      var that=this
      var iconimg=null
      if(status==0){
        iconimg=iotOffline
      }else if(status==1){
        iconimg=iotOnline
      }else if(status==2){
        iconimg=iotError
      }
      var endIcon = new AMap.Icon({
        size: new AMap.Size(68, 68),
        image: iconimg ,
        imageSize: new AMap.Size(68,68 ),
        imageOffset: new AMap.Pixel(-5, 3)
      });

      marker = new AMap.Marker({
        position: new AMap.LngLat(lng, lat),
        offset: new AMap.Pixel(-25, -10),
       icon: endIcon, // 添加 Icon 实例
        zoom: 12
      });
      marker.setExtData(module.id)
       AMap.event.addListener(marker, 'mouseover', function(e) {
         var param = {
        moduleId: module.id
      };
      getModleDataApi(param, that.userInfo.token)
        .then(res => {
          status=res.data.online
         var info = [];
        info.push("<div><h2 style='color:#0068A6'><strong>模块信息</strong></h2>");
         if(res.data.online==0){
         info.push("<p class='input-item'><strong>状态 :</strong><span style='color:red'>离线</span></p>");
         info.push("<p class='input-item'><strong>离线时间 :</strong>"+res.data.offline_date+"</p>");
        }else if(res.data.online==1){
          var onlineDate= new Date(res.data.online_date)
          var d=onlineDate.getTime()
          var n= (new Date()).getTime()
          var sc= ((n-d)/(3600*1000)).toFixed(2)
         info.push("<p class='input-item'><strong>状态 :</strong><span style='color:green'>在线</span></p>");
         info.push("<p class='input-item'><strong>在线时长 :</strong><span >"+sc+"小时</span></p>");
        }else if(res.data.online==2){
          info.push("<p class='input-item'><strong>状态 :</strong><span style='color:red'>告警</span></p>");
        }
        info.push("<p class='input-item'><strong>使用单位 :</strong> "+module.unit+"</p>");
        info.push("<p class='input-item'><strong>所属项目 :</strong> "+module.project_name+"</p>");
        info.push("<p class='input-item'><strong>编号 :</strong> "+module.id+"</p>");
        info.push("<p class='input-item'><strong>地址 :</strong>"+module.address+"</p></div></div>");

        infoWindow = new AMap.InfoWindow({
            content: info.join("")  //使用默认信息窗体框样式,显示信息内容
        });

        infoWindow.open(map, marker.getPosition());
        })
  
        
    });
     AMap.event.addListener(marker, 'dblclick', function(e) {
      map.setZoomAndCenter(20, marker.getPosition());
     });
     // marker.on('mouseover', that.openInfoWin);
      marker.on('mouseout', that.closeInfoWin);
      map.add(marker);
      devises.set(module.id,marker)
      
    },
getModelInfo(){
      var that = this;
      getModleForMapApi(null,this.userInfo.token).then(res =>{
        console.log("data",res)
        if(res){
          for(var i=0;i<res.data.length;i++){
            that.addMarker(
              res.data[i].longitude,
              res.data[i].latitude,
              res.data[i].online,
              res.data[i]
            )
          }
        }
      })
    setTimeout( that.connectMqtt, 1000)
     
    },
      connectMqtt(){
      var that=this
      that.mqttClient.subscribe("要订阅的主题", {'qos':1})
        that.mqttClient.on('message', function (topic, message) {
          console.log('mes', message.toString())
           var d=JSON.parse(message.toString())  
           if(devises.has(d.id)){
             var mar=devises.get(d.id)//根据id从map里取出对应的markker
             var iconimg=null 
              if(mar.getExtData()==d.id){
                 if(d.lineStatus==0){
                  iconimg=iotOffline
                }else if(d.lineStatus==1){
                  iconimg=iotOnline
                }
                var endIcon = new AMap.Icon({
                size: new AMap.Size(68, 68),
                image: iconimg ,
                imageSize: new AMap.Size(68,68 ),
                imageOffset: new AMap.Pixel(0, 3)
              });
                mar.setIcon(endIcon)//根据状态更改marker图标
                //mar.setExtData(d.lineStatus)
              } 

           }
            })
    },

注意:在获取mqtt连接对象时,要设置大概1秒的延迟,mqtt在状态里是异步加载的,不然获取的mqtt对象为null。

3、模拟测试

新建一个页面模拟MQTT上线和下线

下线

经测试 几乎连接成功的时候地图上标记点状态就发生变化,并且每个设备的状态都是独立控制,无需轮询和异步刷新

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值