vue中用webworker子线程连接websocket并实现数据自动更新

 

  第一步

先在store中声明好需要存储的数据。

 state: {
    testName: 'hello',
   
  },
mutations: {
    setTestName(state, name) {
      state.testName = name
    }
}

创建一个worker文件,连接websocket



let WS
let lockReconnect = false // 避免重复连接
const webWorkerSelf = self
const HeartBeat = {
  msgType: 'U',
  msgData: {
    ip: '127.0.0.1',
  },
  dataType: 'keepAlive',


}
//主线程
self.addEventListener(
  'message',
  function(e) {
    const data = e.data
    switch (data.cmd) {
      case 'sendOnline':
        heartCheck.sendOnline()
        break
      case 'config':
        Object.assign(HeartBeat.msgData)
        break
      case 'start':
        self.postMessage({
          type: 'webWorker',
          data: '启动webWorker'
        })
        createWebSocket()
        break
      case 'stop':
        WS.close()
        self.postMessage({
          type: 'webWorker',
          data: '停止webWorker'
        })
        // 服务器断开链接
        self.postMessage({
          type: 'keepalive',
          data: 'close' + new Date().toTimeString()
        })
        self.close() // 终止worker
        break
      default:
    }
  },
  false
)


const createWebSocket = function() {
  if (!WS) {
    WS = new WebSocket(url)
    WS.onerror = function(event) {
      reconnect(url)
    }
    WS.onclose = function(event) {
      reconnect(url)
    }
    WS.onopen = event => {
      // 服务器开启链接
      webWorkerSelf.postMessage({
        type: 'keepalive',
        data: 'start' + new Date().toTimeString()
      })
      heartCheck.reset().start() // 传递信息
    }
    WS.onmessage = e => {
      // 如果获取到消息,发送给主线程
      const data = JSON.parse(e.data)
      self.postMessage({
        type: 'webSocket',
        data
      })
      heartCheck.reset().start()
    }
  }
}
/***
 * 心跳检查
 * @type {{timeoutObj: null, start: heartCheck.start, reset: heartCheck.reset, timeout: number}}
 */
const heartCheck = {
  timeout: 30 * 1000, // 检查时间
  timeoutObj: null,
  serverTimeoutObj: null,
  reset: function() {
    clearTimeout(this.timeoutObj)
    clearTimeout(this.serverTimeoutObj)
    return this
  },
  // 发送在线信息
  sendOnline: function() {
    if (WS.readyState === 1) {
      WS.send(JSON.stringify(HeartBeat))
    }
  },
  close: function() {
    this.serverTimeoutObj = setTimeout(() => {
      // 如果超过一定时间还没重置,说明后端主动断开了
      // 服务器断开链接
      webWorkerSelf.postMessage({
        type: 'keepalive',
        data: 'close' + new Date().toTimeString()
      })
      WS.close() // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
    }, this.timeout)
  },
  start: function() {
    this.timeoutObj = setTimeout(() => {
      // 这里发送一个心跳,返回一个心跳消息
      // onmessage拿到返回的心跳就说明连接正常
      this.sendOnline()
      this.close()
    }, this.timeout)
  }
}

/**
 * websocket重连
 */
function reconnect(url) {
  if (lockReconnect) return
  lockReconnect = true
  // 没连接上会一直重连,设置延迟避免请求过多
  setTimeout(function() {
    WS = null
    createWebSocket()
    lockReconnect = false
  }, 2000)
}

新建一个websocket文件将worker文件引入

<template>
  <div></div>
</template>

<script>
import Worker from './min.worker.js'



export default {
  name: 'socketView',
  data() {
    return {
      webSocket: null
    }
  },
  created() {
 
    this.initWebSocket()

  },

  methods: {
    initWebSocket() {
      const that = this
      // 用webworker子线程去连接webSocket
      this.webSocket = new Worker()
 
      this.webSocket.postMessage({ cmd: 'start' })
      this.webSocket.onmessage = function(event) {
        const { type, data } = event.data
        if (type === 'webSocket') {
             //这里调用store中的dispath或者commite储存数据
    
        } else if (type === 'keepalive') {
          //console.log('keepalive')
         
          if (data === 'close') {
            //
            //console.log('close')
          }
        }
      }
    },
    
  },
  beforeUnmount() {
    this.webSocket.postMessage({ cmd: 'stop' })
    setTimeout(() => {
      this.webSocket.terminate()
      this.webSocket = undefined
    })
  }
}
</script>

<style scoped></style>

再在页面中用computed监听数据,就能实现实时更新了!

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
你可以使用 Vue.js 的 v-for 指令来渲染列表,并结合 v-scroll 指令来实现列表的自动滚动。同时,你可以通过定时器或者 WebSocket 等方式实时更新数据。 下面是一个简单的示例: ```html <template> <div class="list-container" v-scroll="scrollToBottom"> <ul> <li v-for="(item, index) in list" :key="index">{{ item }}</li> </ul> </div> </template> <script> export default { data() { return { list: [], // 列表数据 // 假设你有一种方式可以实时获取数据更新 }; }, methods: { scrollToBottom() { // 滚动到底部 const container = document.querySelector('.list-container'); container.scrollTop = container.scrollHeight; }, // 假设你有一种方式可以实时获取数据更新 // 例如,每隔一段时间调用 updateData 方法更新数据 updateData() { // 假设这里通过异步请求获取最新的数据 // 并将新数据追加到 list 数组 const newData = await fetchData(); this.list = [...this.list, ...newData]; }, }, mounted() { // 假设你在组件挂载后开始更新数据 setInterval(this.updateData, 5000); // 每隔5秒更新一次数据 }, }; </script> <style> .list-container { height: 300px; overflow-y: auto; } </style> ``` 在上面的示例,v-scroll 指令绑定了 scrollToBottom 方法,当列表容器滚动时,会触发该方法,实现自动滚动到底部。通过定时器或者其他方式,你可以实时更新数据并将新数据追加到 list 数组,从而实现列表的实时更新。 希望对你有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值