15 WebSocket
12 WebSocket
WebSocket
WebSocket 是一种网络通信协议,它提供了一种在单个 TCP 连接上进行全双工通信的方式。WebSocket 允许服务器主动向客户端发送数据,而不需要客户端不断发送请求来轮询服务器。这种特性使得 WebSocket 非常适合需要实时数据传输的应用,如在线聊天、实时游戏、股票行情更新等。
WebSocket 的特点
- 全双工通信:WebSocket 连接允许服务器和客户端之间同时进行数据的发送和接收,而不需要像 HTTP 请求那样等待对方的响应。
- 持久连接:一旦 WebSocket 连接建立,它会保持打开状态,直到客户端或服务器显式地关闭连接。这避免了频繁地建立和关闭连接的开销。
- 基于 HTTP 的握手:WebSocket 连接的建立是通过 HTTP 请求完成的,称为 WebSocket 握手。服务器在接收到 WebSocket 握手请求后,会将连接升级为 WebSocket 连接。
- 二进制数据传输:WebSocket 支持传输二进制数据,如 Blob 或 ArrayBuffer,这使得 WebSocket 能够高效地传输图像、音频、视频等二进制文件。
WebSocket 的工作流程
- 握手:客户端通过发送一个特殊的 HTTP 请求来请求 WebSocket 连接。这个请求包含一个
Upgrade头,表明客户端希望将连接升级为 WebSocket 连接。服务器如果同意升级,则会返回一个响应,将连接升级为 WebSocket 连接。 - 数据传输:一旦 WebSocket 连接建立,客户端和服务器就可以通过该连接自由地发送和接收数据。数据可以是文本数据,也可以是二进制数据。
- 关闭连接:WebSocket 连接可以由客户端或服务器关闭。关闭连接时,需要发送一个关闭帧,对方收到后也会关闭连接。
WebSocket API
在 JavaScript 中,可以通过 WebSocket 对象来使用 WebSocket 协议。以下是一些常用的属性和方法:
- 属性
readyState:表示 WebSocket 连接的状态。可能的值有:0:连接尚未建立(CONNECTING)1:连接已建立(OPEN)2:正在关闭连接(CLOSING)3:连接已关闭(CLOSED)
bufferedAmount:表示已发送但尚未被浏览器传输的数据量(以字节为单位)。extensions:表示服务器选择的 WebSocket 扩展。protocol:表示服务器选择的子协议。url:表示 WebSocket 连接的 URL。
- 方法
constructor(url, [protocols]):创建一个新的 WebSocket 对象。url是 WebSocket 服务器的地址,protocols是可选的,可以指定一个或多个子协议。send(data):向服务器发送数据。data可以是字符串、Blob 或 ArrayBuffer。close([code], [reason]):关闭 WebSocket 连接。code是关闭连接的状态码,reason是关闭连接的原因。
- 事件
open:当 WebSocket 连接成功建立时触发。error:当 WebSocket 连接发生错误时触发。message:当从服务器接收到数据时触发。close:当 WebSocket 连接关闭时触发。
示例代码
以下是一个简单的 WebSocket 客户端示例:
1 | // 创建WebSocket连接 |
WebSocket 协议的出现极大地简化了实时通信的开发,使得开发者可以更方便地实现各种实时交互功能。
WebSocket心跳机制
WebSocket心跳机制是用于维持客户端与服务器之间长连接的一种保活机制,通过定时发送心跳包来保持连接的活跃状态,防止因长时间无通讯而导致的自动断开。以下是心跳机制的详细说明:
一、心跳机制的实现方式
- 客户端定时向服务器发送心跳数据包
- 客户端每隔一定时间(通常小于60秒)向服务器发送一个心跳数据包,服务器收到后返回一个响应。这种方式可以保持连接的活跃状态,防止连接因长时间无活动而被关闭。
- 示例代码:
1
2
3this.heartbeatTimer = setInterval(() => {
ws.send('{"event":"ping","content":"ping heartbeat"}');
}, originData.ping_interval); // originData.ping_interval 是心跳间隔时间
- 服务器定时向客户端发送心跳数据包
- 服务器每隔一定时间向客户端发送一个心跳数据包,客户端收到后返回一个响应。这种方式可以检测客户端连接是否正常。
- 示例代码(服务端配置):
1
2
3
4$gateway = new Gateway("websocket://0.0.0.0:8783");
$gateway->pingInterval = 55; // 心跳检测时间间隔,单位:秒
$gateway->pingNotResponseLimit = 0; // 客户端连续多少次不响应心跳时关闭连接
$gateway->pingData = '{"type":"ping"}'; // 服务端发送的心跳数据
- 双向发送心跳数据包
- 客户端和服务器都定时发送心跳数据包,这种方式可以更全面地检测连接状态。
二、心跳机制的原理
- 客户端建立WebSocket连接
- 客户端通过
new WebSocket(url)建立连接。
- 客户端通过
- 客户端向服务器发送心跳数据包
- 客户端定时发送心跳数据包,服务器接收并返回响应。
- 服务器没有及时接收到心跳数据包
- 如果服务器在设定时间内没有收到客户端的心跳数据包,会发送一个关闭连接的请求。
- 服务器定时向客户端发送心跳数据包
- 服务器定时发送心跳数据包,客户端接收并返回响应。
- 客户端没有及时接收到心跳数据包
- 如果客户端在设定时间内没有收到服务器的心跳数据包,会重新连接WebSocket。
三、心跳机制的作用
- 保持WebSocket连接不被断开
- 通过定时发送心跳数据包,可以防止连接因长时间无活动而被关闭。
- 检测WebSocket连接状态
- 可以及时发现连接是否异常断开,从而进行重连等操作。
- 减少资源消耗
- 通过心跳机制,可以减少因连接异常断开而重新建立连接的次数,从而减少资源消耗。
四、心跳机制的必要性
WebSocket心跳机制是必要的,它可以使WebSocket连接保持长连接,避免断开连接的情况发生。同时,心跳机制也可以检查WebSocket连接的状态,及时处理异常情况。
五、心跳机制的实现示例
客户端实现
1 | let ws = new WebSocket("ws://127.0.0.1:8783"); |
服务端实现(以Node.js为例)
1 | const WebSocket = require('ws'); |
通过以上实现,可以有效地保持WebSocket连接的活跃状态,及时发现并处理连接异常。