目录

2024-07-31-前端WebSocket入门,看这篇就够啦

前端WebSocket入门,看这篇就够啦!!

在HTML5 的早期开发过程中,由于意识到现有的 HTTP 协议在实时通信方面的不足,开发者开始探索能够在 Web 环境下实现 双向实时通信 的新的通信协议,提出了 WebSocket 协议的概念。

一、什么是 WebSocket?

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。与 HTTP 协议不同的是,WebSocket 允许服务器和客户端在连接建立后能够在不需要重新请求的情况下,相互发送数据。即浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。这个特性使得 WebSocket 特别适合于需要实时数据交换的应用场景。

二、WebSocket 的使用场景

即时聊天应用、多人在线游戏、股票行情及天气预报等实时数据更新、在线白板工具、协同开发平台、在线协同绘图工具、设计协作平台等

三、简要介绍WebSocket 的工作原理
  1. 握手过程

    WebSocket 连接的建立始于客户端的 HTTP 请求。服务器接收到请求后,会进行确认 并切换为 WebSocket 协议,从而建立连接。

    握手成功后,HTTP 连接切换为 WebSocket 连接,此时客户端和服务器之间可以进行全双工通信。

  2. 数据传输

    一旦 WebSocket 连接建立,客户端和服务器之间就可以进行双向的数据传输。

  3. 连接关闭

    WebSocket 连接可以由客户端或服务器任意一方发起关闭。包括以下步骤:

  • 发送关闭帧 :一方发送一个关闭帧,表明希望关闭连接。
  • 确认关闭请求 :接收方回应一个关闭帧,确认关闭请求。
  • 完成关闭 :在双方都发送关闭帧后,连接正式关闭。客户端和服务器随后释放相关资源。
四、WebSocket 的连接建立过程
  1. 客户端发送 WebSocket 握手请求,请求头包含 UpgradeConnection 字段,指定协议升级和建立连接。
  2. 服务器收到握手请求后,验证请求头的字段,并返回握手响应,响应头包含 Upgrade 和 Connection 字段,以及一个随机的 Sec-WebSocket-Key 字段。
  3. 客户端收到握手响应后,验证响应头的字段,并生成一个 Sec-WebSocket-Accept 值进行验证。
  4. 验证通过后,WebSocket 连接建立成功,客户端和服务器可以开始进行实时通信。
五、WebSocket 在前端的实现
  1. 创建 WebSocket 连接

使用 WebSocket 构造函数并传入服务器的 URL。URL 通常以 ws://wss:// (用于安全连接)开头。

// 创建 WebSocket 连接
const socket = new WebSocket('wss://example.com/socket');
  1. 处理 WebSocket 事件

WebSocket 对象提供了几个事件处理器,可以通过这些处理器来处理连接的各种状态和数据传输。

  • onopen :连接成功打开时触发。
  • onmessage :接收到消息时触发。
  • onerror :连接发生错误时触发。
  • onclose :连接关闭时触发。
// 创建 WebSocket 连接
const socket = new WebSocket('wss://localhost:8080');

// 连接成功打开时的处理
socket.onopen = function(event) {
    console.log('WebSocket 连接已打开');
    // 发送一条消息到服务器
    socket.send('halo啊哈哈哈哈哈哈(*´▽`)ノノ!');
};

// 接收到消息时的处理
socket.onmessage = function(event) {
    // 处理接收到的消息
  const message = event.data;
  console.log('接收到消息咯O(∩_∩)O:', message);
};

// 连接关闭时的处理
socket.onclose = function(event) {
  console.log('啊喔…… WebSocket连接已关闭(`・ω・´)');
};

// 连接发生错误时的处理
socket.onerror = function(error) {
  console.error('WebSocket发生错误啦:', error);
};
  1. 发送消息

使用 send 方法向服务器发送文本消息。

// 发送文本消息
socket.send('Hello Server!');

WebSocket 除了发送和接收文本消息外,还支持发送和接收二进制数据。对于发送二进制数据,可以使用 send() 方法传递一个 ArrayBufferBlob 对象 ,例如:

// 发送二进制数据
const buffer = new ArrayBuffer(8);// 创建一个 8 字节的 ArrayBuffer 对象
//ArrayBuffer 是一个表示通用、固定长度原始二进制数据缓冲区的对象。

//本身不提供操作数据的直接方法,而是通过 TypedArray 或 DataView 对其进行读写操作。
const view = new DataView(buffer);// 创建一个 DataView 对象,以便操作 ArrayBuffer 中的数据
//DataView 提供了一种对 ArrayBuffer 中数据进行读取和写入的方式,支持多种数据类型(如整数、浮点数等)的读取和写入。
//创建 DataView 对象时,传入了之前创建的 ArrayBuffer,这使得 DataView 可以操作这个缓冲区中的数据。
view.setUint8(0, 255);
//setUint8(offset, value) 方法将 8 位无符号整数值写入 ArrayBuffer 的指定位置。
//offset 是偏移量(从缓冲区的起始位置),value 是要写入的值。
//0 表示数据将写入 ArrayBuffer 的第一个字节位置,255 是要写入的值。由于 Uint8 是 8 位无符号整数,范围从 0 到 255。

socket.send(buffer);
//send(data) 方法将指定的数据发送到 WebSocket 服务器。
//在这里,发送的是 ArrayBuffer 对象,即我们之前 创建并修改的 数据缓冲区。

在接收二进制数据时,可以通过 event.data 获取到 ArrayBuffer 对象 ,然后进行处理。

  1. 关闭连接

可以调用 close 方法关闭 WebSocket 连接。可以传递一个关闭状态码和可选的原因描述。

// 关闭 WebSocket 连接
socket.close(1000, 'Normal closure');
六、WebSocket的安全性和跨域问题处理

WebSocket 支持通过 wss:// 前缀 建立 加密的安全连接 ,使用 TLS / SSL 加密通信 ,确保数据的安全性。在使用加密连接时, 服务器 需要配置相应的 证书

对于跨域问题,WebSocket 遵循 同源策略 ,只能与 同源的服务器 建立连接。 如果需要与不同域的服务器通信,可以使用 CORS 跨域资源共享 来进行跨域访问控制。

七、WebSocket 协议和 HTTP 协议的区别
  • 连接方式 :WebSocket 提供持久的连接,通过握手过程建立连接后保持打开状态,直到主动关闭,而 HTTP 是无状态的,每次请求都需要重新建立连接。
  • 数据格式 :WebSocket 支持文本和 二进制 数据的传输,而 HTTP 主要是传输文本数据。
  • 数据传输方式 :WebSocket 实现了全双工通信,数据传输是双向的,客户端和服务器 可以 同时发送和接收 数据 ,数据通过帧(frame)进行传输,减少了传输开销。而 HTTP 数据传输是单向的,客户端发起请求,服务器响应数据。每个请求都包含完整的 HTTP 头部。
  • 协议标识 :WebSocket 使用 ws:// 或 wss:// 前缀标识,而 HTTP 使用 http:// 或 https://
  • 协议切换 :WebSocket 使用 HTTP 协议进行初始的握手,之后切换到 WebSocket 协议进行通信。握手过程包括协议升级的请求和响应。HTTP 协议在每次请求时都是独立的,不涉及协议切换。
  • 应用场景 :WebSocket适用于实时交互的场景,如即时聊天、在线游戏、实时数据推送等,需要快速且频繁的数据交换。HTTP适用于传统的 Web 请求和响应场景,如静态资源加载、表单提交等。
八、WebSocket 相对于传统 HTTP 请求的优势
  • 实时性 :WebSocket 提供了低延迟的实时通信能力,能够在服务器端有新数据时立即推送给客户端。
  • 双向通信 :WebSocket 支持客户端和服务器之间的双向通信,可以实现实时聊天、实时数据更新等场景。
  • 较低的网络开销 :WebSocket 使用长连接,连接保持持久,减少了频繁建立和关闭连接的开销和服务器资源消耗。
  • 更高的性能 :由于减少了 HTTP 请求的开销(WebSocket 在建立连接后不再需要重复的 HTTP 请求头),数据通过 进行传输,支持文本和二进制数据,灵活性高,使WebSocket 在性能上更高效。
  • 跨域支持 :WebSocket 具备跨域通信的能力,可以跨域进行实时通信。
九、WebSocket 的性能优化
  • 减少数据量 :合理控制发送的数据量大小,避免不必要的数据传输。
  • 心跳机制 :通过定时发送心跳消息,保持连接的 活跃 状态,防止连接被关闭。
  • 数据压缩 :可以使用压缩算法对数据进行压缩,减少网络传输的数据量。
  • 服务器端优化 :合理配置服务器端的连接数和资源管理,以支持更多的并发连接。
参考:

68747470733a2f2f626c:6f672e6373646e2e6e65742f4f52414e47455f3369494e472f:61727469636c652f64657461696c732f313430383139333234