WebSocket在node端和客户端的使用

摘要

如果想要实现一个聊天的功能,就会想到使用WebSocket来搭建。那如果没有WebSocet的时候,我们会以什么样的思路来实现聊天功能呢?

假如有一个A页面 和 B页面进行通信,当A发送信息后,我们可以将信息存储在文件或者数据库里。

但是B页面并不知道A发送了信息,所以如果想要让B 页面实时的去展示A发送的信息,我们只能在B页面设置一个定时器,在定时器中一直去查询文件或者数据库的信息,如果有新的消息,那么就在B页面进行展示,同理,在A页面也要以相同的方法去实现。

对于这个方法,需要不停的去轮训,耗费了大量的空间和时间,那如果在A 发送消息后,B页面可以主动的接收到对应的消息,就不需要在定时器中去不停的查找了。

WebSocket,就是为了解决这个问题出现的。WebSocket支持双向通信,服务器和客户端之间可以随时互相发送信息,实时性更强。

1. ws模块

在node中,大家对于fs模块,http模块应该已经不陌生了。这里我们需要引入的模块是ws模块,需要通过npm install进行安装。

WS模块是一个WebSocket协议的实现,它允许客户端(一般是浏览器)和服务器之间建立持久连接,进行实时双向通信。这种持久连接可以使得数据传输更加高效,适用于需要实时交互的应用场景,如在线聊天室、游戏等。

现在我们简单的使用一下:

新建一个文件夹,npm init初始化,再npm install ws

在文件夹下新建一个index.js

javascript 复制代码
const WebSocket = require('ws')

const wss = new WebSocket.Server({port: 3004});

wss.on('connection', (ws) => {
  //如果有客户端连接,就会进入这个回调
  console.log('Client connected');
  ws.on('message', (message) => {
    // 如果有客户端发送消息,就会进入这个回调
    console.log(message.toString());
  })
})

这样一个简单的ws的node端就实现了。现在我们新建一个html文件:

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div style="width: 200px;height:300px;background: #e2e2e2;margin-bottom: 20px;">
    <span></span>
  </div>
  <input type="text">
  <button>发送</button>

  <script>
  	// 创建ws模块
    var ws = new WebSocket(`ws://localhost:3004`);
    // 建立连接
    ws.onopen = function () {
      // 客户端向服务端发送消息
      ws.send('hello word');
      console.log('已连接');
    }
  </script>
</body>
</html>

这样就是一个简单的客户端向服务端发送消息的模型。

2.从服务端发往客户端

上面的代码主要实现了从客户端到服务端,但这也是正常思路。我们肯定是希望从服务端到客户端。

所以我们要在服务端接受到消息后,也往客户端发送消息:

javascript 复制代码
const WebSocket = require('ws')

const wss = new WebSocket.Server({port: 3004});

wss.on('connection', (ws) => {
  console.log('Client connected');
  ws.on('message', (message) => {
    console.log(message.toString());
    // 服务端向客户端发送消息
    ws.send('hello word too')
  })
})

在客户端里,我们通过onmessage的回调来进行接受:

javascript 复制代码
  <script>
    var ws = new WebSocket(`ws://localhost:3004`);
    ws.onopen = function () {
      ws.send('hello word');
      console.log('已连接');
    }
    ws.onmessage = async function(mes) {
      // 接受服务端发送的消息
      console.log(mes.data)
    }
  </script>

3.对于不同的客户端,返回不同的信息

那如果想实现出一个聊天的功能,服务端接受到A的消息,要给B发送消息。

上面的代码似乎只能,谁给服务端发,服务端就给谁返回。

所以在node的代码里,我们需要每次建立连接的时候,将对应的ws保存起来,然后根据客户端的信息,用指定的ws去返回信息。

现在我们如果有两个html,每个html在初始化页面的时候,给服务端发送一个消息,代表自己已经连接的信息。

点击按钮的时候,给服务端发送的信息,要携带希望传递的客户端的信息。

页面1:

javascript 复制代码
  <script>
    var ws = new WebSocket(`ws://localhost:3004`);
    ws.onopen = function () {
      ws.send(JSON.stringify({name: 'zhangsan', message: 'init'}));
      console.log('已连接');
    }
    ws.onmessage = async function(mes) {
      console.log(mes.data)
    }
    
    function click() {
      const value = input.value;
      ws.send(JSON.stringify({name: 'lisi', message: '你好lisi'}))
    }
  </script>

页面2:

javascript 复制代码
  <script>
    var ws = new WebSocket(`ws://localhost:3004`);
    ws.onopen = function () {
      ws.send(JSON.stringify{name: 'lisi', message: 'init'}));
      console.log('已连接');
    }
    ws.onmessage = async function(mes) {
      console.log(mes.data)
    }
    
    function click() {
      const value = input.value;
      ws.send(JSON.stringify({name: 'zhangsan', message: '你好zhangsan'}))
    }
  </script>

在node端中,我们要根据message是否为init,进行判断。

javascript 复制代码
const WebSocket = require('ws')

const wss = new WebSocket.Server({port: 3004});
const wsList = {}

wss.on('connection', (ws) => {
  ws.on('message', (message) => {
    const result = JSON.parse(message);
    // 页面初始化的时候,使用wsList将ws进行缓存
    if(result.message === 'init') {
      wsList[result.name] = ws;
    }else {
      // 根据name的值来给指定的客户端发送信息
      const ws = wsList[result.name];
      ws.send(result.message)
    }
  })

  ws.on('close', () => {
    Object.keys(wsList).forEach(item => {
      // 当websoket关闭的时候,要清空对应的ws
      if(wsList[item].readyState !== 1) {
        delete wsList[item]
      }
    })
  })
})

以上就是对应ws模块,和WebSocket的简单阐述。

相关推荐
模型时代3 分钟前
思科发布2026年1月最新动态与AI基础设施布局进展
网络·智能路由器
飞雪20075 分钟前
我有一台旧的mac mini 如何设置成为NAS(网络附加存储)?
网络·macos·网络存储·家庭影院·局域网·nas
WJ.Polar9 分钟前
华为OSPF配置实战详解
运维·网络
咕咕嘎嘎102410 分钟前
Socket编程
linux·服务器·网络
吴秋霖14 分钟前
某网站WebSocket协议逆向分析
网络·websocket·网络协议
Godspeed Zhao1 小时前
现代智能汽车中的无线技术39——V2X(11)
网络·汽车
Irene19911 小时前
手机SIM卡 4G 5G 信号强度 和 移动网络 WIFI 之间的关系或区别
网络·5g·4g·sim卡
深信达沙箱2 小时前
SDC沙箱能够满足哪些场景需求?
网络·加密·软件·源代码·沙盒
郝学胜-神的一滴2 小时前
深入理解网络IP协议与TTL机制:从原理到实践
linux·服务器·开发语言·网络·网络协议·tcp/ip·程序人生
松涛和鸣2 小时前
DAY61 IMX6ULL UART Serial Communication Practice
linux·服务器·网络·arm开发·数据库·驱动开发