1. 什么是 websocket

1.1 什么是 websocket

WebSocket是一种在单个 TCP 连接上进行全双工通信的协议。
WebSocket 使得浏览器(客户端)和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据

1.2 websocket 与 http 的区别

常规的 http 协议的网站与应用中,一般都是浏览器(客户端)主动发送请求到服务端获取数据,服务端无法主动推送数据到浏览器(客户端)。

服务端想要发送数据到浏览器(客户端),都是使用http轮询的方式实现,即浏览器(客户端)主动发送请求到服务端,服务端将数据返回浏览器(客户端)中。

http轮询模式有很大的缺点,需要浏览器(客户端)一直向服务端发送请求,以获取服务器中的最新数据到浏览器(客户端)中,当服务器数据又不一定一直变化,这就造成了很多的浏览器(客户端)发送的请求是无效请求,造成了资源的严重浪费。

Websocket 协议和 HTTP 协议主要有以下区别:

  • 连接方式
    • HTTP 协议:基于请求-响应模式,客户端发起请求,服务器响应。每次请求和响应都需要建立和关闭连接。
    • Websocket 协议:建立一次连接后,保持连接状态,允许双向通信,无需频繁建立和关闭连接。
  • 数据传输方向
    • HTTP 协议:通常是客户端向服务器发送请求,服务器返回响应,数据传输方向主要是客户端到服务器。
    • Websocket 协议:支持服务器主动向客户端推送数据,实现双向实时通信。
  • 开销
    • HTTP 协议:每次请求和响应都包含较多的头部信息,造成一定的开销。
    • Websocket 协议:建立连接后的通信开销相对较小。
  • 实时性
    • HTTP 协议:不太适合实时数据的传输,实时性相对较差。
    • Websocket 协议:能够实现实时的数据交互,实时性强。
  • 应用场景
    • HTTP 协议:适用于大多数一般性的网页浏览、数据获取等。
    • Websocket 协议:常用于在线聊天、实时游戏、金融行情实时推送等需要实时交互的场景。

2. 为什么需要 websocket

为了解决使用 http 协议的浏览器(客户端)无法快速获取服务器端的数据,websocket 就被发明了出来。

websocket 协议有如下优点:

  1. 双向通信:允许服务器主动向客户端推送数据,实现实时交互,无需客户端频繁请求。
  2. 低延迟:建立连接后,数据传输的延迟相对较低,能够快速响应。
  3. 更少的开销:相比传统的 HTTP 请求-响应模式,减少了连接建立和关闭的开销。
  4. 高效的数据传输:可以发送二进制数据,提高了数据传输的效率。
  5. 保持连接:连接一旦建立,除非出现异常,否则会一直保持,节省了重新建立连接的时间和资源。
  6. 实时性强:适用于需要实时更新数据的应用,如在线游戏、实时监控等。

3. websocket 如何使用

websocket 具体使用需要客户端与服务器端的双重支持。

3.1 websocket 服务器端代码是使用

// 引入 websocket 库;可以使用 npm install ws 安装库
const WebSocket = require('ws');
// 创建一个 WebSocket 服务器,并监听 8080 端口
const wss = new WebSocket.Server({ port: 8080 });

// 当有客户端连接成功时触发此事件
wss.on('connection', (ws) => {
  // 当接收到客户端发送的消息时触发此事件
  ws.on('message', (message) => {
    // 打印接收到的消息
    console.log(`Received: ${message}`);
    // 向客户端发送一条消息
    ws.send(`You sent: ${message} , 这是一个服务器返回的消息`);
  });
  // 向刚连接的客户端发送一条欢迎消息
  ws.send('Welcome to the WebSocket server!');
});

在目录里新建一个名为 app.js 的文件,将上述代码拷贝进去保存;之后在当前目录中打开终端,在终端中输入 node app.js 即可运行一个 websocket 测试版服务端。

3.2 浏览器(客户端)代码与使用

3.2.1 浏览器端使用一

浏览器端可以使用第三方网站来测试与 3.1 中的 websocket 服务器端是否通联成功。
测试网址为:http://www.websocket-test.com/

打开网址后在左上角输入 websocket 服务端地址与端口号,示例为:ws://127.0.0.1:8080

之后即可发送内容测试。

3.2.2 浏览器使用二

<!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>WebSocket Test</title>
</head>

<body>
  <h2>WebSocket 测试</h2>
  <div id="message"></div>

  <script>
    // 创建 WebSocket 连接
    var socket = new WebSocket("ws://localhost:8080");

    // 连接打开时触发
    socket.onopen = function (event) {
      var p = document.createElement('p');
      p.textContent = '连接已打开';
      document.getElementById('message').appendChild(p);
      socket.send('Hello, WebSocket!');
    };

    // 接收到消息时触发
    socket.onmessage = function (event) {
      var p = document.createElement('p');
      p.textContent = '收到消息: '+ event.data;
      document.getElementById('message').appendChild(p);
    };

    // 连接关闭时触发
    socket.onclose = function (event) {
      var p = document.createElement('p');
      p.textContent = '连接已关闭';
      document.getElementById('message').appendChild(p);
    };

    // 发生错误时触发
    socket.onerror = function (error) {
      var p = document.createElement('p');
      p.textContent = '错误: '+ error.message;
      document.getElementById('message').appendChild(p);
    };
  </script>
</body>

</html>

在目录中新建一个文件 index.html ,将上述代码复制到 index.html 中,然后使用浏览器打开该文件。

4. 总结

本文档是本人学习使用 websocket 的一点记录,文中的代码片段仅为最基础的测试代码,仅用于测试 websocket 双向通联是否成功。

写于:2024.07.01


参考文档:

  1. https://zhuanlan.zhihu.com/p/690282564
  2. https://www.cnblogs.com/chyingp/p/websocket-deep-in.html
  3. https://www.runoob.com/html/html5-websocket.html
  4. http://www.websocket-test.com/
  5. https://www.doubao.com/