Web Socket
Web Socket
WebSocket是一种基于TCP的网络通信协议,允许客户端和服务器之间建立全双工(双向)通信通道。WebSocket通过HTTP协议进行握手,建立连接后,客户端和服务器可以在同一个连接上同时发送和接收数据,无需频繁重新建立连接。这种机制与传统的HTTP请求-响应模式不同,后者在每次请求后都会断开连接。
官网地址:
WebSockets 手册 |WebSocket.orghttps://websocket.org/
简言之:浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输
概念理解:
(1)全双工:意思就是服务器向浏览器发送数据的同时,浏览器也可以向服务器传递数据,即同时进行信息的双向传递.
(2)半双工:允许通信双方互相传递数据,但是在一方 A 向另一方 B 传递数据时,B 不能向 A 传,类比独木桥.
(3)单工:即只允许一方 A 向另一方 B 传递数据,B 永远都不能向 A 传递数据,类比单行道.
HTTP协议 VS Web Socket协议
-
HTTP是短连接(在每次数据传输完成后立即关闭的连接。这意味着每次客户端向服务器发送请求并接收响应后,连接都会被断开。)
-
Web Socket是长连接(在数据传输完成后保持连接打开,以便后续的数据传输可以重用该连接。这减少了建立新连接的开销,提高了通信效率。)
-
HTTP通信是单向的,基于请求响应模式
-
WebSocket支持双向通信
-
HTTP和WebSocket底层都是使用TCP连接
工作原理
WebSocket的建立过程称为“握手”(handshaking),客户端通过HTTP协议向服务器发送一个特殊格式的请求,服务器响应后,连接升级为WebSocket。握手过程类似于标准的HTTP请求,但包含了一些特定的头部信息,如Upgrade: websocket
和Connection: Upgrade
等。一旦握手成功,客户端和服务器就可以通过这个持久连接进行双向通信,直到一方主动关闭连接。
WebSocket工作流程
①握手阶段
WebSocket在建立连接时需要进行握手阶段。握手阶段包括以下几个步骤:
- 客户端向服务端发送请求,请求建立WebSocket连接。请求中包含一个Sec-WebSocket-Key参数,用于生成WebSocket的随机密钥。
- 服务端接收到请求后,生成一个随机密钥,并使用随机密钥生成一个新的Sec-WebSocket-Accept参数。
- 客户端接收到服务端发送的新的Sec-WebSocket-Accept参数后,使用原来的随机密钥和新的Sec-WebSocket-Accept参数共同生成一个新的Sec-WebSocket-Key参数,用于加密数据传输。
- 客户端将新的Sec-WebSocket-Key参数发送给服务端,服务端接收到后,使用该参数加密数据传输。
===============客户端发起请求======================================================
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket // 请求升级协议
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 随机生成的key
Sec-WebSocket-Version: 13 // WebSocket版本==============服务端响应请求(进行协议升级)=========================================
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kZZ7TdQihdUh-8= // 根据key计算出的值
②数据传输阶段
建立连接后,客户端和服务端就可以通过WebSocket进行实时双向通信。数据传输阶段包括以下几个步骤:
- 客户端向服务端发送数据,服务端收到数据后将其转发给其他客户端。
- 服务端向客户端发送数据,客户端收到数据后进行处理。
双方如何进行相互传输数据的 具体的数据格式是怎么样的呢?WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息。
发送方 -> 接收方:ping。
接收方 -> 发送方:pong。
ping 、pong 的操作,对应的是 WebSocket 的两个控制帧
③关闭阶段
当不再需要WebSocket连接时,需要进行关闭阶段。关闭阶段包括以下几个步骤:
- 客户端向服务端发送关闭请求,请求中包含一个WebSocket的随机密钥。
- 服务端接收到关闭请求后,向客户端发送关闭响应,关闭响应中包含服务端生成的随机密钥。
- 客户端收到关闭响应后,关闭WebSocket连接。
总的来说,WebSocket通过握手阶段、数据传输阶段和关闭阶段实现了服务器和客户端之间的实时双向通信。
特点
-
全双工通信:客户端和服务器都可以随时发送和接收数据,无需等待对方发起请求。
-
低延迟和高效率:由于连接持久,减少了每次数据传输的延迟和开销,适合实时应用。
-
支持二进制传输:WebSocket定义了二进制帧,可以发送文本和二进制数据。
-
广泛支持:主流浏览器和服务器技术都支持WebSocket,便于开发者使用。
-
与HTTP兼容:WebSocket的握手过程基于HTTP协议,因此可以通过HTTP代理服务器。
应用场景
-
实时聊天应用:构建高效、低延迟的聊天室和即时消息应用。
-
实时数据推送:用于股票报价、新闻推送、系统通知等应用场景。
-
在线协作工具:实现多人协同编辑文档、在线白板、多人游戏等功能。
-
物联网应用:实现设备实时监控、远程控制等功能
入门案例
实现步骤:
①使用WebSocket.html页面作为WebSocket客户端
②导入WebSocket的maven坐标
③导入WebSocket服务端组件WebSocketServer,用于和客户端通信
④导入配置类WebSocketConfiguration,注册WebSocket的服务端组件
⑤导入定时任务WebSockeyTask,定时向客户端发送数据
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}
@Component
public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5秒向客户端发送消息*/@Scheduled(cron = "0/5 * * * * ?")public void sendMessageToClient() {webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}
}