WebSocket详解:5分钟从入门到精通!!!
一.WebSocket 基本概念
-
WebSocket是什么?
WebSocket 是基于 TCP 的一种新的应用层网络协议。它提供了一个全双工的通道,允许服务器和客户端之间实时双向通信。因此,在 WebSocket 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,客户端和服务器之间的数据交换变得更加简单。
-
与 HTTP 协议的区别
与 HTTP 协议相比,WebSocket 具有以下优点:
- 更高的实时性能:WebSocket 允许服务器和客户端之间实时双向通信,从而提高了实时通信场景中的性能
- 更少的网络开销:HTTP 请求和响应之间需要额外的数据传输,而 WebSocket 通过在同一个连接上双向通信,减少了网络开销
- 更灵活的通信方式:HTTP 请求和响应通常是一一对应的,而 WebSocket 允许服务器和客户端之间以多种方式进行通信,例如消息 Push、事件推送等
- 更简洁的 API:WebSocket 提供了简洁的 API,使得客户端开发人员可以更轻松地进行实时通信
当然肯定有缺点的:
- 不支持无连接: WebSocket 是一种持久化的协议,这意味着连接不会在一次请求之后立即断开。这是有利的,因为它消除了建立连接的开销,但是也可能导致一些资源泄漏的问题
- 不支持广泛: WebSocket 是 HTML5 中的一种标准协议,虽然现代浏览器都支持,但是一些旧的浏览器可能不支持 WebSocket
- 需要特殊的服务器支持: WebSocket 需要服务端支持,只有特定的服务器才能够实现 WebSocket 协议。这可能会增加系统的复杂性和部署的难度
- 数据流不兼容: WebSocket 的数据流格式与 HTTP 不同,这意味着在不同的网络环境下,WebSocket 的表现可能会有所不同
-
WebSocket工作原理
- 握手阶段
WebSocket在建立连接时需要进行握手阶段。握手阶段包括以下几个步骤:
- 客户端向服务端发送请求,请求建立WebSocket连接。请求中包含一个Sec-WebSocket-Key参数,用于生成WebSocket的随机密钥
- 服务端接收到请求后,生成一个随机密钥,并使用随机密钥生成一个新的Sec-WebSocket-Accept参数
- 客户端接收到服务端发送的新的Sec-WebSocket-Accept参数后,使用原来的随机密钥和新的Sec-WebSocket-Accept参数共同生成一个新的Sec-WebSocket-Key参数,用于加密数据传输
- 客户端将新的Sec-WebSocket-Key参数发送给服务端,服务端接收到后,使用该参数加密数据传输
- 数据传输阶段
建立连接后,客户端和服务端就可以通过WebSocket进行实时双向通信。数据传输阶段包括以下几个步骤:
- 客户端向服务端发送数据,服务端收到数据后将其转发给其他客户端
- 服务端向客户端发送数据,客户端收到数据后进行处理
双方如何进行相互传输数据的 具体的数据格式是怎么样的呢?WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息。
发送方 -> 接收方:ping
接收方 -> 发送方:pong
ping 、pong 的操作,对应的是 WebSocket 的两个控制帧
- 关闭阶段
当不再需要WebSocket连接时,需要进行关闭阶段。关闭阶段包括以下几个步骤:
- 客户端向服务端发送关闭请求,请求中包含一个WebSocket的随机密钥
- 服务端接收到关闭请求后,向客户端发送关闭响应,关闭响应中包含服务端生成的随机密钥
- 客户端收到关闭响应后,关闭WebSocket连接
总的来说,WebSocket通过握手阶段、数据传输阶段和关闭阶段实现了服务器和客户端之间的实时双向通信。
二.WebSocket 数据帧结构和控制帧结构
-
数据帧结构
WebSocket 数据帧主要包括两个部分:帧头和有效载荷。以下是 WebSocket 数据帧结构的简要介绍:
- 帧头:帧头包括四个部分:fin、rsv1、rsv2、rsv3、opcode、masked 和 payload_length。其中,fin 表示数据帧的结束标志,rsv1、rsv2、rsv3 表示保留字段,opcode 表示数据帧的类型,masked 表示是否进行掩码处理,payload_length 表示有效载荷的长度
- 有效载荷:有效载荷是数据帧中实际的数据部分,它由客户端和服务端进行数据传输
-
控制帧结构
除了数据帧之外,WebSocket 协议还包括一些控制帧,主要包括 Ping、Pong 和 Close 帧。以下是 WebSocket 控制帧结构的简要介绍:
- Ping 帧:Ping 帧用于测试客户端和服务端之间的连接状态,客户端向服务端发送 Ping 帧,服务端收到后需要向客户端发送 Pong 帧进行响应
- Pong 帧:Pong 帧用于响应客户端的 Ping 帧,它用于测试客户端和服务端之间的连接状态
- Close 帧:Close 帧用于关闭客户端和服务端之间的连接,它包括四个部分:fin、rsv1、rsv2、rsv3、opcode、masked 和 payload_length。其中,opcode 的值为 8,表示 Close 帧
三. JavaScript 中 WebSocket 对象的属性和方法,以及如何创建和连接 WebSocket
**WebSocket 对象的属性和方法:**
WebSocket
对象:WebSocket 对象表示一个新的 WebSocket 连接。WebSocket.onopen
事件处理程序:当 WebSocket 连接打开时触发。WebSocket.onmessage
事件处理程序:当接收到来自 WebSocket 的消息时触发。WebSocket.onerror
事件处理程序:当 WebSocket 发生错误时触发。WebSocket.onclose
事件处理程序:当 WebSocket 连接关闭时触发。WebSocket.send
方法:向 WebSocket 发送数据。WebSocket.close
方法:关闭 WebSocket 连接。
**创建和连接 WebSocket:**
-
创建 WebSocket 对象:
var socket = new WebSocket('ws://example.com');
其中,
ws://example.com
是 WebSocket 的 URL,表示要连接的服务器。 -
连接 WebSocket:
使用
WebSocket.onopen
事件处理程序检查 WebSocket 是否成功连接。socket.onopen = function() { console.log('WebSocket connected'); };
-
接收来自 WebSocket 的消息:
使用
WebSocket.onmessage
事件处理程序接收来自 WebSocket 的消息。socket.onmessage = function(event) { console.log('WebSocket message:', event.data); };
-
向 WebSocket 发送消息:
使用
WebSocket.send
方法向 WebSocket 发送消息。socket.send(