Web Worker 和 WebSocket的区别

Web Worker(消息传递机制)

  1. 定义:是为了在浏览器中提供多线程支持,允许 JavaScript 在后台线程运行,而不阻塞主线程。它非常适合执行耗时的计算任务或处理大量数据,避免主线程(通常是 UI 线程)被阻塞,从而保证用户界面的流畅性。

  2. 应用:运行后台任务,执行长时间运行的计算或操作,诸如图像处理、文件处理、大数据分析等。它并不直接与网络通信或实时消息传递相关。

  3. 原理:创建Web Worker分配一个新的线程(即后台线程),它一个独立的执行上下文,和主线程相互隔离,且不能直接操作 DOM 或访问主线程中的变量,它和主线程之间的通信是异步的,通常是通过 postMessageonmessage 方法进行数据传输。

    javascript 复制代码
    // 创建一个 Worker
    const worker = new Worker('worker.js');
    
    // 发送消息到 Worker
    worker.postMessage({ type: 'start', data: 1000 });  // 1000ms 的间隔
    
    // 接收 Worker 返回的消息
    worker.onmessage = (event) => {
      console.log(event.data);  // 输出 Worker 返回的数据
    };
    
    // 停止 Worker
    worker.postMessage({ type: 'stop' });

应用计时器:

javascript 复制代码
// worker.js
let setIntervaler = null
let count = 0

// 启动定时器
function start(timeout) {
  setIntervaler = setInterval(() => {
    postMessage({
      type: 'next',
      data: ++count
    })
  }, timeout)
}

// 停止定时器并关闭 Worker
function stop() {
  clearInterval(setIntervaler)
  count = 0 // 重置计数
  self.close() // 关闭 Worker
}

// 监听来自主线程的消息
self.addEventListener('message', (e) => {
  let { type, data } = e.data // 解构消息数据
  switch (type) {
    case 'start':
      start(data) // 启动定时器
      break
    case 'stop':
      stop() // 停止定时器
      break
    default:
      break
  }
})
javascript 复制代码
<template>
  <div>
    <h1>Web Worker 定时器</h1>
    <p>计数: {{ count }}</p>
    <button @click="startTimer" :disabled="isRunning">启动定时器</button>
    <button @click="stopTimer" :disabled="!isRunning">停止定时器</button>
  </div>
</template>

<script setup>
import { ref, onUnmounted } from 'vue';

// 定义 Vue 组件的状态
const count = ref(0);
const isRunning = ref(false);

// 创建 Worker 实例
// src\utils\worker.js
const worker = new Worker(new URL('../utils/worker.js', import.meta.url));

// 监听 Worker 返回的数据
worker.onmessage = (e) => {
  const { type, data } = e.data;
  switch (type) {
    case 'ready':
      console.log(data); // Worker 已准备好
      break;
    case 'next':
      count.value = data; // 更新计数器
      break;
    default:
      break;
  }
};

// 启动定时器
const startTimer = () => {
  worker.postMessage({ type: 'start', data: 1000 }); // 1000 毫秒(1秒)为定时器间隔
  isRunning.value = true; // 更新状态为运行中
};

// 停止定时器
const stopTimer = () => {
  worker.postMessage({ type: 'stop' });
  isRunning.value = false; // 更新状态为停止
};

// 清理 Worker 实例
onUnmounted(() => {
  worker.terminate(); // 组件销毁时终止 Worker
});
</script>

<style scoped>
button {
  margin: 10px;
  padding: 10px;
  font-size: 16px;
}
</style>

WebSocket(握手连接通信)

  1. 定义:是一种在客户端和服务器之间建立持久连接的协议,它允许双方在连接建立后进行双向实时通信。WebSocket 主要用于需要实时数据更新的应用场景,如实时聊天、在线游戏、股票行情、推送通知等

  2. 应用:客户端和服务器之间可以保持一个长连接,允许实时交换数据,适合实时应用程序的场景。

  3. 原理:用 HTTP 协议进行握手建立连接,通信将转为基于 TCP 的实时双向通信(全双工通信),可以随时从客户端或服务器端通过 send 方法发送数据,通过 onmessage 监听接收到的消息。

    javascript 复制代码
    // 创建 WebSocket 连接
    const socket = new WebSocket('ws://example.com/socket');
    
    // 连接成功后发送消息
    socket.onopen = () => {
      socket.send('Hello, server!');
    };
    
    // 接收来自服务器的消息
    socket.onmessage = (event) => {
      console.log('Message from server:', event.data);
    };
    
    // 发送消息给服务器
    socket.send('Another message');
    
    // 关闭连接
    socket.close();

总结:

|------|---------------------------------------|----------------------|
| 特性 | Web Worker | WebSocket |
| 主要目的 | 后台线程处理计算任务,避免阻塞主线程 | 双向实时通信,实时数据交换 |
| 通信方式 | 主线程与 Worker 通过消息传递 | 客户端与服务器之间的持久连接,双向通信 |
| 适用场景 | 长时间运行的计算任务,数据处理 | 实时应用程序,如聊天、推送通知、在线游戏 |
| 通信延迟 | 主要用于计算任务,没有即时通信需求 | 适合低延迟、高实时性的双向通信 |
| 关闭方式 | worker.terminate()self.close() | socket.close() |


追更:

Web Worker 是一个独立的线程,当你调用 self.close() 时,Worker 被终止,所有的状态(如定时器)也会丢失。

因此,想要再次启动定时器则不关闭Worker直到组件被销毁!!!

javascript 复制代码
// worker.js
let setIntervaler = null;
let count = 0;
let isRunning = false; // 标志定时器是否正在运行

// 启动定时器
function start(timeout) {
  if (!isRunning) {
    isRunning = true; // 标记定时器已启动
    setIntervaler = setInterval(() => {
      postMessage({
        type: 'next',
        data: ++count
      });
    }, timeout);
  }
}

// 停止定时器
function stop() {
  if (isRunning) {
    clearInterval(setIntervaler);
    isRunning = false; // 标记定时器已停止
  }
}

// 监听来自主线程的消息
self.addEventListener('message', (e) => {
  const { type, data } = e.data;
  switch (type) {
    case 'start':
      start(data); // 启动定时器
      break;
    case 'stop':
      stop(); // 停止定时器
      break;
    default:
      break;
  }
});
javascript 复制代码
<template>
  <div>
    <h1>Web Worker 定时器</h1>
    <p>计数: {{ count }}</p>
    <button @click="startTimer" :disabled="isRunning">启动定时器</button>
    <button @click="stopTimer" :disabled="!isRunning">停止定时器</button>
  </div>
</template>

<script setup>
import { ref, onUnmounted } from 'vue';

// 定义 Vue 组件的状态
const count = ref(0);
const isRunning = ref(false);

// 创建 Worker 实例,保持 Worker 持续存在
const worker = new Worker(new URL('../utils/worker.js', import.meta.url));

// 监听 Worker 返回的数据
worker.onmessage = (e) => {
  const { type, data } = e.data;
  switch (type) {
    case 'ready':
      console.log(data); // Worker 已准备好
      break;
    case 'next':
      count.value = data; // 更新计数器
      break;
    default:
      break;
  }
};

// 启动定时器
const startTimer = () => {
  if (!isRunning.value) {
    worker.postMessage({ type: 'start', data: 1000 }); // 1000 毫秒(1秒)为定时器间隔
    isRunning.value = true; // 更新状态为运行中
  }
};

// 停止定时器
const stopTimer = () => {
  if (isRunning.value) {
    worker.postMessage({ type: 'stop' });
    isRunning.value = false; // 更新状态为停止
  }
};

// 清理 Worker 实例
onUnmounted(() => {
  worker.terminate(); // 组件销毁时终止 Worker
});
</script>

<style scoped>
button {
  margin: 10px;
  padding: 10px;
  font-size: 16px;
}
</style>
相关推荐
liu****1 小时前
27.epoll(三)
服务器·开发语言·网络·tcp/ip·udp
云飞云共享云桌面1 小时前
如何降低非标自动化工厂的研发软件采购成本
运维·服务器·网络·数据库·性能优化·自动化
时代新威powertime3 小时前
等保三级|安全通信网络自评估指南
网络·安全·等保测评
国服第二切图仔3 小时前
检测隧道HTTP代理的可用性的几种方法
网络·网络协议·http
托尼吴3 小时前
REST RPC dubbo,HSF 协议总结
网络协议·rpc·dubbo
JH30734 小时前
引依赖包和对这个包发起rpc调用有什么区别
网络·网络协议·rpc
tan180°4 小时前
Linux网络TCP(上)(11)
linux·网络·c++·后端·tcp/ip
席万里4 小时前
关于Go的init函数执行顺序#黑魔法
开发语言·网络·golang
Evand J5 小时前
【TCN与LSTM例程】TCN(时间卷积网络)与LSTM(长短期记忆)训练单输入单输出,用于拟合一段信号,便于降噪。MATLAB
网络·人工智能·matlab·lstm
程序员小单5 小时前
WebSocket 与 Spring Boot 整合实践
spring boot·websocket·网络协议