websocekt 应用案例

写过一篇关于websocekt的文章,感觉不太清楚,所以再次记录下实际项目中的使用方法

在Vue中,created钩子函数中就可以初始化websocket

// created钩子函数中初始化websocekt
created() {
   this.initWebSocket()
},

在websocekt初始化完成,连接成功之后,向服务器发送请求

initWebSocket() {
        // console.log('---------initWebSocket----10-----')
        const vm = this
        vm.websocket = new WebSocket(process.env.WEBSOCKET_API)
        // vm.websocket = new WebSocket('ws://192.168.5.137:****')
        vm.websocket.onopen = function() {
          console.log('websocket连接成功')
          if (vm.topDeptId && vm.topDeptId !== '') {
             ***发送请求***
            vm.subscribeTop(5, vm.topDeptId.substring(2))
            vm.subscribeTop(24, vm.topDeptId.substring(2))
            vm.subscribeExpend(4, 'online', vm.topDeptId.substring(2))
          }
        }
        vm.websocket.onmessage = function(evt) {
            ***接收数据***
          const obj = JSON.parse(evt.data)
          // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + JSON.stringify(obj))
          console.log('222222222222222222=>' + obj.Command)

            接收数据之后在这里做下判断,根据后端返回不同的Command指令,做不同的操作
            websocket.onmessage 是websocket接收数据的方法,这里不过是做了不同的判断而已

          switch (obj.Command) {
            case '15': // 取消订阅,删除在百度地图上渲染的marker图标
              vm.continuecycle=true
              const vehIds = obj.Body.VehIds // 当前订阅节点下的所有数据  vehIds为id数组
              // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + vehIds)
              for (const idx in vehIds) {
                vm.deleteArray(vm.vehicleList, vehIds[idx])
                vm.deleteArray(vm.vehicleIdTmpList, vehIds[idx])
                delete vm.vehicleTmpObj[vehIds[idx]]
              }
              vm.continuecycle=false
              setTimeout(function() {
                for (const idx in vehIds) {
                  vm.deleteArray(vm.vehicleIdTmpList, vehIds[idx])
                  vm.deleteArray(vm.vehicleList, vehIds[idx])
                  delete vm.vehicleTmpObj[vehIds[idx]]
                }
                // console.log('地图数据置空555555555')
              }, 1000)
              // debugger
              break
            case '26': // 订阅->轨迹数据,从返回数据中获取订阅车辆的经纬度,百度地图渲染数据
      
              // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + obj.vId)
             vm.continuecycle=true
             if (vm.vehicleIdTmpList.indexOf(obj.vId) === -1) {
                vm.vehicleIdTmpList.push(obj.vId)
              }
              // console.log('+++vehicleIdTmpList+++' + vm.vehicleIdTmpList)
              vm.vehicleTmpObj[obj.vId] = obj
              // console.log('+++vehicleTmpObj+++' + JSON.stringify(vm.vehicleTmpObj))
              vm.continuecycle=false

              break
            case '27': // 实时接收已展开过的节点下车辆上下线通知
              // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + JSON.stringify(obj))
              const offlineVeh = obj.Body.Offline
              const onlineVeh = obj.Body.Online

              offlineVeh.forEach(vid => {
                vm.setDataTotree(vm.treeData, vid+'', {online:'0'})
              });

              onlineVeh.forEach(vid => {
                vm.setDataTotree(vm.treeData, vid+'', {online:'1'})
              })
              break
            case '33': // 企业车辆总数,在线数,离线数统计
              // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + JSON.stringify(obj))
              vm.asideObj = obj.Body
              vm.treeData[0].onlineVehicle = obj.Body.onlineVehicle
              vm.treeData[0].allVehicle = obj.Body.allVehicle
              vm.treeData[0].offlineVehicle= obj.Body.allVehicle-obj.Body.onlineVehicle
              break
            case '32': // 获取企业所有节点车辆在线数
              // console.log('['+new Date().getHours()+':'+new Date().getMinutes()+':'+new Date().getSeconds()+'] receive command('+obj.Command+') message:' + JSON.stringify(obj))
              const nodeArr = []
              const data = obj.Body
              for (const key in data) {
                if (data.hasOwnProperty(key)) {
                  const obj1 = { id: key, count: data[key] }
                  nodeArr.push(obj1)
                }
              }
              //更新下级机构的车辆总数
              for (let i = 0; i < nodeArr.length; i++) {
                vm.setDataTotree(vm.treeData[0].children, nodeArr[i].id, nodeArr[i].count)
              }
              if (data) {
                vm.deptStatCache = data;
              }
              break
            default:
              break
          }
        }

        如果websocekt发生错误,再次进行连接***

        vm.websocket.onerror = function() {
          console.log('---------onerror--20-------')
          vm.initWebSocket()
        }
      }

 下面是不同的发送请求的方法,不同的请求类型,这里拼了一个不同的请求参数,其实这几个方法也是大同小异

subscribeTop(command, deptId) { // 获取企业节点车辆在线数
        const data = {
          Command: command,
          CommandType: 'online',
          Token: getToken(),
          Body: {
            TopDeptId: deptId
          }
        }
        if (this.websocket.readyState === 1) {
          this.websocket.send(JSON.stringify(data))
        } else {
          console.log('websocket信息发送失败')
        }
      },

subscribeExpend(command, commandType, deptId) { // 实时接收已展开过的节点下车辆上下线通知
        const data = {
          Command: command,
          CommandType: commandType,
          Token: getToken(),
          Body: {
            deptId: deptId
          }
        }
        if (this.websocket.readyState === 1) {
          this.websocket.send(JSON.stringify(data))
        } else {
          console.log('websocket信息发送失败')
        }
      },

以上两个方法会在websocket初始化后,连接成功之后触发,请求页面渲染需要的数据,

下面的方法会在用户点击树节点复选框时触发,会根据不同的请求参数(判断的当前的状态,勾选或取消勾选)

给服务端发送不同请求,服务端返回不同的数据,做不同的操作。

该方法会在用户点击树节点复选框时触发*******

subscribe(command, isdept, id) { // 发送websocket消息,获取车辆或者机构下车辆经纬度信息
        // console.log('-----------subscribe-------command -> ' + command + ' ; isdept -> '+ isdept + ' ; id -> ' + id);
        const data = {
          Command: command,
          CommandType: 'track',
          Token: getToken(),
          Body: {
            isdept: isdept,
            id: id,
            activeStatus: this.activeStatus === -1 ? null : this.activeStatus
          }
        }
        console.log('ws请求参数:', data)
        if (this.websocket.readyState === 1) {
          this.websocket.send(JSON.stringify(data))
          console.log('请求发送成功+++++++')
        } else {
          console.log('websocket信息发送失败')
        }
      },

这里奉上用户点击树节点复选框的方法

getCurrentKey(data, node) { // 获取当前选中节点的key 复选框点击 data数据为当前点击复选框的内容 id等
        const id = data.id.substring(2)
        this.checkedList = node.checkedKeys
        if (this.checkedList.indexOf(data.id) > -1) {
          if (data.type === '3') {
            this.clickVehId = id
            this.subscribe(1, 1, id)
          } else {
            this.subscribe(1, 0, id)
          }
        } else {
          if (data.type === '3') {
            this.clickVehId = id
            if (id === this.vehicleInfo.vId + '') {
              this.isShowDialog = false
            }
            this.subscribe(15, 1, id)
            this.deleteArray(this.vehicleList, data.id.substring(2))
          } else {
            this.subscribe(15, 0, id)
            const vehicleArray = []
            const arr = this.getSelectArr(vehicleArray, this.treeData[0].children, data.id)
            for (let i = 0; i < arr.length; i++) {
              this.deleteArray(this.vehicleList, arr[i].id.substring(2))
            }
          }
        }
      }

还有一个百度地图渲染的方法,该方法在页面挂载完成之后就会调用,另外还有两个方法在 methods 中定义,mounted中调用,为了方便查阅,我将它们放在了一起,如下

mounted() {
      getBaseTree() { // 树节点数据获取加载方法
        this.deptTreeQuery = { id: '', activeStatus: this.activeStatus==-1?'':this.activeStatus }
        
        getBaseDept(this.deptTreeQuery).then(res => { // 加载机构树顶级节点
          if (res.code === 0) {
            // console.log(res)
            if (this.websocket.readyState === 1) {
              this.subscribeTop(24, res.data[0].id.substring(2))
              this.subscribeTop(5, res.data[0].id.substring(2))
              this.subscribeExpend(4, 'online', res.data[0].id.substring(2))
            }
            this.topDeptId = res.data[0].id
            this.treeData = res.data
            // console.log('-----------getBaseDept---------' + JSON.stringify(this.treeData))
            this.$set(this.treeData[0], 'allVehicle', res.data.allCount)
            this.$set(this.treeData[0], 'onlineVehicle', res.data.onlineVehicle)
            this.$set(this.treeData[0], 'offlineVehicle', res.data.allCount-res.data.onlineVehicle)
            this.$set(this.treeData[0], 'children', [])
            this.treeData[0].children.push({})
          } else {
            this.$message({ message: res.msg, type: 'error' })
          }
        })
      },
      
      initLocation() { // 获取localStoragesh数据方法
        if (window.localStorage) {
          const storage = window.localStorage
          const address = storage.getItem('userDeptArea')
          // console.log(address)
          this.mapCenter = address
        }
      },      

      setInterval(() => {
        this.pushVehToMap() // 百度地图渲染方法,页面挂载完成调用,每0.5秒调用一次
      }, 500)
    },

// 地图渲染方法
pushVehToMap() {
        const vm = this
        let pushCount = vm.pushCount
        let pcount = 0
        let pushLimit = 10
        let count = 0
        for (const id in vm.vehicleTmpObj) { // 订阅的对象
          count++
        }
        // console.log('count -> ' + count)
        
        if (pushCount >= vm.vehicleIdTmpList.length || count < pushCount) {
          vm.pushCount = 0
          pushCount = 0
        }
        // console.log('--2--' + pushCount + '----11----' + vm.vehicleIdTmpList.length)
        for (let idx = pushCount; idx < vm.vehicleIdTmpList.length; idx++) {
        
          const id = vm.vehicleIdTmpList[idx]
          if (pcount >= pushLimit || count === 0) {
            return
          }
          if (!vm.vehicleTmpObj.hasOwnProperty(id)) {
            continue
          }
          pcount++
          vm.pushCount++
          const obj = vm.vehicleTmpObj[id]
          // console.log('idx -> ' + idx + ' ; id -> ' + id+ this.continuecycle)
            if( this.continuecycle){
            break
          }
          
          if (vm.clickVehId == obj.vId) {
            // 地图渲染
            vm.mapCenter = {
              lng: obj.currInfo.PosData.Longitude,
              lat: obj.currInfo.PosData.Latitude
            }
            vm.zoom = 18
            vm.clickVehId = ''
          }
          if (vm.vehicleList.length === 0) {
            vm.vehicleList.push(obj)
          } else {
            const arr = []
            for (let i = 0; i < vm.vehicleList.length; i++) {
              arr.push(vm.vehicleList[i].vId)
            }
            if (arr.indexOf(obj.vId) > -1) {
              const j = vm.contains(arr, obj.vId)
              vm.vehicleList[j] = obj
            } else {
              vm.vehicleList.push(obj)
            }
            if (vm.vehicleId && vm.vehicleId !== '') {
              if (vm.vehicleId === obj.vId) {
                vm.vehicleInfo = obj
              }
            }
          }
          delete this.vehicleTmpObj[id]
        }
      }

这里有一个localStorag,相关文档可以查看这里

具体的代码其实可以不用去看,感兴趣的当然也可以研究,主要是websocket的用法,

建立一个websocket连接,连接成功,发送数据,获取数据,连接出错等都是必要的步骤,发送数据时需要判断websocket连接

状态 websocket.readyState,具体概念性的可以查一下文档

页面样式基本是这样

猜你喜欢

转载自blog.csdn.net/lwx931449660/article/details/88541319