websocket教程

提纲
1、websocket协议概述
包括基本功能,提出时间,标准文档
2、websocket的连接建立过程和报文结构
3、websocket的消息帧结构
4、web前端对websocket的支持方案
5、java后端的websocket技术方案



1、websocket协议概述

websocket协议是对http协议的扩充, 是使用的TCP协议实现全双工通信的一种应用层协议。
websocket协议允许服务端向客户端主动推送消息,而http是需要浏览器主动请求服务器,服务器才会给浏览器回送消息。在websocket协议中,服务器不需要浏览器主动请求它,它就会给浏览器发送数据。
websocket协议中,最初建立连接的时候,浏览器和服务端只需要进行一次基于http协议的握手,不必像http协议一样,每次连接都要新建立连接。
使用ws协议的客户端和服务端之间创建的是持久性的连接,并进行双向的数据交互。
也就是说一旦浏览器和服务器之间建立起来websocket连接,那么浏览器可以给服务器发送消息,服务器也可以给浏览器发送消息。

http/1.1 是 请求-响应设计的,后来支持了更多的传输类型 图片,但都是基于请求响应。

http的不足:
传输数据为文本,且请求头与响应头冗长重复。
请求-响应模式,只能客户端发送请求给服务端,服务端才可以发送响应数据给客户端。

WebSocket为Web应用程序提供了TCP风格的网络能力。寻址仍然是单向的,服务器可以异步发送客户端数据,但是只在WebSocket连接打开时才能做到。在客户端和服务器之间WebSocket连接始终打开。WebSocket服务器也可以作为WebSocket客户端。但是,利用WebSocket,Web客户端不能接受不是由它们建立的连接。



2、websocket连接建立过程和报文结构

每个WebSocket连接都始于一个HTTP请求。该请求和其他请求很相似,但是包含一个特殊的首标-Upgrade。Upgrade首标表示客户端将把连接升级到其他的协议。在这种情况下,这个其他协议就是WebSocket。

上图就是浏览器和服务器之间建立websocket连接的过程。
websocket首次请求服务端建立连接,也是客户端发起的,基于http请求的,这个请求称为websocket的握手请求。请求头中多携带消息

请求报文
GET /test HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: tFGdnEL/5fXMS9yKwBjllg==
Origin: http://example.com
Sec-WebSocket-Protocol: v10.stomp, v11.stomp, v12.stomp
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Version: 13

  • Connection必须设置Upgrade,表示客户端希望连接升级。
  • Upgrade: websocket表明协议升级为websocket。
  • Sec-WebSocket-Key字段内记录着握手过程中必不可少的键值,由客户端(浏览器)生成,可以尽量避免普通HTTP请求被误认为Websocket协议。
  • Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13。
  • Origin字段是必须的。如果缺少origin字段,WebSocket服务器需要回复HTTP 403 状态码(禁止访问),通过Origin可以做安全校验。
响应报文
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HaA6EjhHRejpHyuO0yBnY4J4n3A=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Sec-WebSocket-Protocol: v12.stomp

Sec-WebSocket-Accept的字段值是由握手请求中的Sec-WebSocket-Key的字段值生成的。成功握手确立WebSocket连接之后,通信时不再使用HTTP的数据帧,而采用WebSocket独立的数据帧。

上图展示了从客户端发往服务器升级为WebSocket的HTTP请求,也称作WebSocket初始握手(opening handshake)。有些首标是必需的,必需存在并且要精确才能保证WebSocket连接成功。这一握手中的其他首标是可选的,但因为握手是一次HTTP请求和响应,所以也是允许的。在成功升级后,连接的语法切换为用于表示WebSocket消息的数据帧格式。除非服务器响应101代码、Upgrade首标和Sec-WebSocket-Accept首标,否则WebSocket连接不能成功。Sec-WebSocket-Accept响应首标的值从Sec-WebSocket-Key请求首标继承而来,包含一个特殊的响应键值,必需与客户端的预期精确匹配。

计算响应键值
为了成功地完成握手,WebSocket服务器必须响应一个计算出来的键值。这个响应说明服务器理解WebSocket协议。响应函数从客户端发送的Sec-WebSocket-Key首标中取得键值,并在Sec-WebSocket-Accept首标中返回根据客户端预期计算的键值。



3、websocket的消息帧结构

WebSocket使用二进制消息帧作为双向通信的媒介。何为消息帧?发送方将每个应用程序消息拆分为一个或多个帧,通过网络将它们传输到目的地,并重新组装解析出一个完整消息。

有别于HTTP/1.1文本消息格式(冗长的消息头和分隔符等),WebSocket消息帧规定一定的格式,以二进制传输,更加短小精悍。二者相同之处就是都是基于TCP/IP流式协议(没有规定消息边界)


WebSocket帧化代码负责:操作码、长度、解码文本、屏蔽、多帧消息
操作码:每条WebSocket消息都有一个指定消息载荷类型的操作码。操作码由帧头的第一个字节中最后4bit组成。4bit的操作码有16种可能取值,WebSocket协议只定义了5种操作码,剩余的操作码保留用于未来的扩展。

  • FIN: 1 bit,表示该帧是否为消息的最后一帧。1-是,0-否。
  • RSV1,RSV2,RSV3: 1 bit each,预留(3位),扩展的预留标志。一般情况为0,除非协商的扩展定义为非零值。如果接收到非零值且不为协商扩展定义,接收端必须使连接失败。
  • Opcode: 4 bits,定义消息帧的操作类型,如果接收到一个未知Opcode,接收端必须使连接失败。(0x0-延续帧,0x1-文本帧,0x2-二进制帧,0x8-关闭帧,0x9-PING帧,0xA-PONG帧(在接收到PING帧时,终端必须发送一个PONG帧响应,除非它已经接收到关闭帧),0x3-0x7保留给未来的非控制帧,0xB-F保留给未来的控制帧)
  • Mask: 1 bit,表示该帧是否为隐藏的,即被加密保护的。1-是,0-否。Mask=1时,必须传一个Masking-key,用于解除隐藏(客户端发送消息给服务器端,Mask必须为1)。
  • Payload length: 7 bits, 7+16 bits, or 7+64 bits,有效载荷数据的长度(扩展数据长度+应用数据长度,扩展数据长度可以为0)。
  • Masking-key: 0 or 4 bytes,用于解除帧隐藏(加密)的key,Mask=1时不为空,Mask=0时不用传。
  • Payload data: (x+y) bytes,有效载荷数据包括扩展数据(x bytes)和应用数据(y bytes)。有效载荷数据是用户真正要传输的数据。

参考资料:
1、https://www.cnblogs.com/flydean/p/15341443.html#websocketserverhandshaker,主力参考资料,通过仔细阅读这篇文章,我搞懂了王冬车俩推送的主体逻辑。
2、https://blog.csdn.net/mahao25/article/details/127418543,补充文档。
3、https://blog.csdn.net/fffvdgjvbsfkb123456/article/details/116465394,重要参考,从协议数据包角度讲了websocket和http的区别。
4、https://baijiahao.baidu.com/s?id=1706643919026404240&wfr=spider&for=pc,协议数据包详细讲解
5、https://blog.csdn.net/asmartkiller/article/details/102623132,对websocket的报文做了详细讲解
6、https://www.ruanyifeng.com/blog/2017/05/websocket.html,前端websocket api



posted @   zhangzl419  阅读(230)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示