摘要:页面1:当点击更新按钮时,页面1的数值加1,同时页面2的数值变为页面1数值的10倍。页面2:当点击清空按钮时,页面1和页面2的数值都会清零。页面2:定时获取页面1的数值,并展示出来。
最近,我遇到了一个需求:有两个页面,每个页面各自连接到一个独立的Websocket。这两个页面能够通过WebSocket相互影响。
为了更好地理解需求,以下是两个页面的简化版本:
页面1和页面2的需求:
页面1:当点击更新按钮时,页面1的数值加1,同时页面2的数值变为页面1数值的10倍。页面2:当点击清空按钮时,页面1和页面2的数值都会清零。页面2:定时获取页面1的数值,并展示出来。效果演示:
实现这个需求并不复杂,核心思路是通过Node.js创建两个WebSocket连接,并通过一个count变量来同步页面的数据。
首先,安装ws库:
npm install ws如何实现两个WebSocket之间的通信呢?其实就是维护两个全局变量来存储这两个WebSocket实例。
然后,在前端页面通过 WebSocket 通信来实现数据同步。
页面1
页面2
通过这种方式,基本实现了需求,效果如下:
上述方法虽能实现需求,但维护起来可能会很麻烦,尤其是当多个WebSocket连接实例增加时,代码可能变得难以管理。
我有一个想法:能否让每个WebSocket连接管理自己的状态?
问题在于,尽管每个连接管理自己的状态,它们仍然需要依赖一个共同的变量(即count)。当某个实例更新了count,另一个实例如何被通知并作出反应呢?
想到这里,我就联想到了 Vue3 的响应式机制。Vue3 提供了一套非常优秀的响应式 API,当数据变化时,它能够自动通知相关的组件进行更新。
能否将 Vue3 的响应式 API 移植到Node.js环境中呢?
答案是:可以!Vue3 将响应式 API 拆分成了一个独立的库@vue/Reactivity,即使在 Node.js 环境下,也可以使用这个库来实现响应式功能。
通过安装这个包:
npm install @vue/reactivity我们可以使用ref、computed 和 watch来让每个WebSocket 实例独立管理自己的状态。
最终的效果展示:
可以将@vue/reactivity作为一个响应式工具库使用,它不仅可以在Node.js环境下使用,甚至可以在 React 项目中使用。
Node.js 端:index.js
// 引入 WebSocket 库const WebSocket = require('ws');// 引入 Vue3 响应式 APIconst reactivity = require('@vue/reactivity');const { ref, computed, watch } = reactivity;// 创建 WebSocket 服务器const wss1 = new WebSocket.Server({ port: 8001 });const wss2 = new WebSocket.Server({ port: 8002 });// 记录数字const count = ref(0);// 计算数值的 10 倍const sum = computed( =>10 * count.value);// 处理连接1wss1.on('connection', (ws) => {ws.on('message', (message) => {// 更新 count 的值count.value = Number(message);});// 监听 count 变化,并发送到页面1watch(count, (newValue) => {ws.send(newValue);});});// 处理连接2wss2.on('connection', (ws) => {ws.on('message', => {// 清空 count 和 sumcount.value = 0;});// 监听 sum 变化,并发送到页面2watch(sum, (newValue) => {ws.send(newValue);});// 模拟定时任务,定期发送 sumsetTimeout( => {ws.send(sum.value);}, 3600 * 12); // 12小时后发送});页面1:Page1.vue
页面1点击更新数据当前数值:{{ count }}import { Button } from'ant-design-vue';import { ref } from'vue';const count = ref(0);// 创建 WebSocket 客户端const socket = new WebSocket('ws://localhost:8001');const click = => {count.value++;// 发送更新后的 count 到服务器socket.send(`${count.value}`);};// 接收来自服务端的消息socket.addEventListener('message', (e) => {count.value = e.data;});页面2:Page2.vue
页面2清空数据当前数值:{{ count }}import { Button } from'ant-design-vue';import { ref } from'vue';const count = ref(0);// 创建 WebSocket 客户端const socket = new WebSocket('ws://localhost:8002');const click = => {// 向服务器发送清空命令socket.send('Hello, server!');};// 接收来自服务端的消息socket.addEventListener('message', (e) => {count.value = e.data;});最终效果
这样,通过 Vue3 的响应式 API 和WebSocket的结合,我们可以轻松地实现两个页面间的实时数据同步,并使代码更加易于维护和扩展。
来源:不秃头程序员一点号