WebSocket是什么?为什么能持久连接?

一、WebSocket是什么

WebSocket,是一种网络传输协议,位于 OSI 模型的应用层。可在单个 TCP 连接上进行全双工通信,能更好的节省服务器资源和带宽并达到实时通迅 客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输

59ee24af265de29ba995c6e8fe1573a9.png

二、特点

全双工 通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合 例如指 A→B 的同时 B→A ,是瞬时同步的 二进制帧 采用了二进制帧结构,语法、语义与 HTTP 完全不兼容,相比 http/2,WebSocket 更侧重于“实时通信”,而 HTTP/2 更侧重于提高传输效率,所以两者的帧结构也有很大的区别 不像 HTTP/2 那样定义流,也就不存在多路复用、优先级等特性 自身就是全双工,也不需要服务器推送 协议名 引入 ws 和 wss 分别代表明文和密文的 websocket 协议,且默认端口使用 80 或 443,几乎与 http 一致

ws://www.chrono.com
ws://www.chrono.com:8080/srv
ws://www.chrono.com:445/im?user=user_id=xxxx

握手 WebSocket 也要有一个握手过程,然后才能正式收发数据 客户端发送数据格式如下:

GET /chat HTTP/1.1  Host: server.example.com Upgrade: websocket Connection:  Upgrade  Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==  Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version:  13
  • Connection:必须设置 Upgrade,表示客户端希望连接升级

  • Upgrade:必须设置 Websocket,表示希望升级到 Websocket 协议

  • Sec-WebSocket-Key:客户端发送的一个 base64 编码的密文,用于简单的认证秘钥。要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept 应答,否则客户端会抛出错误,并关闭连接

  • Sec-WebSocket-Version :表示支持的 Websocket 版本

服务端返回的数据格式: 

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat

HTTP/1.1 101 Switching Protocols:表示服务端接受 WebSocket 协议的客户端连接

  • Sec-WebSocket-Accep:验证客户端请求报文,同样也是为了防止误连接。具体做法是把请求头里“Sec-WebSocket-Key”的值,加上一个专用的 UUID,再计算摘要

优点

  • 较少的控制开销:数据包头部协议较小,不同于 http 每次请求需要携带完整的头部

  • 更强的实时性:相对于 HTTP 请求需要等待客户端发起请求服务端才能响应,延迟明显更少

  • 保持创连接状态:创建通信后,可省略状态信息,不同于 HTTP 每次请求需要携带身份验证

  • 更好的二进制支持:定义了二进制帧,更好处理二进制内容

  • 支持扩展:用户可以扩展 websocket 协议、实现部分自定义的子协议

  • 更好的压缩效果:Websocket 在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率

HTTP 协议的“缺陷”

了解http的人都知道,HTTP 协议有一个缺陷:通信只能由客户端发起。例如,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息的, 这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦,客户端只能使用”轮询”的方式,即每隔一段时间,就发出一个请求,请求服务器有没有状态变化 。可见轮询的效率低,非常浪费资源。

在http1.1中,默认开启了一个叫Keep-alive的参数,官方的说法是可以用这个来作为长连接。你是否以为既然客户端与服务器保持了长连接,服务器就能主动给客户端推送消息呢?

关于Keep-alive的缺点

Keep-alive的确可以实现长连接,但是这个长连接是有问题的,本质上依然是客户端主动发起-服务端应答的模式,是没法做到服务端主动发送通知给客户端的。也就是说,在一个HTTP连接中,客户端可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,一个request只能有一个response。而且这个response也是被动的,不能主动发起。放上一张图,图左为没开启Keep-alive,图右为开启了Keep-alive,可以看出依然是一问一答的模式,向较左边只是省略了每次的关闭和打开操作。

ef6d434c14c1a68baebc27df95ea2269.png

需要注意的是Keep-alive是指不需要多次建立连接,而非http2.0里面的多路复用,多路复用的意思是客户端可以同时向服务器端发送多个请求,服务器端也可以同时响应多个Response.

b2465849037075d82b51aff41a01ce69.png

关于websocket

那么如果我们需要服务器状态变化的时候能够主动通知客户端,我们有没有什么办法呢?这就要用到websocket。

f7d34ab7ad97867f68f51723bf0f4536.png

上图对比可以看出,相对于传统 HTTP每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

WebSocket API 是 HTML5 标准的一部分, 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览器的应用程序中使用。

在WebSocket中,只需要服务器和浏览器通过TCP协议进行一个握手的动作,然后单独建立一条TCP的通信通道进行数据的传送。WebSocket同HTTP一样也是应用层的协议,但是它是一种双向通信协议,是建立在TCP之上的。websocket的流程大概是以下几步:

1、浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。2、TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手) 3、服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。4、当收到了连接成功的消息后,通过TCP通道进行传输通信。

也就是说WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要TCP协议的。

看看一次websocket的握手请求与应答的报文

WebSocket 客户端连接报文

GET /webfin/websocket/ HTTP/1.1  Host: localhost Upgrade: websocket Connection:  Upgrade  Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==  Origin: http://localhost :8080  Sec-WebSocket-Version:  13

可以看到,客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,“Sec-WebSocket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。

服务端收到报文后返回的数据格式类似:

WebSocket 服务端响应报文

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: 
http://localhost
:8080
Sec-WebSocket-Version: 13

“Sec-WebSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1 101 Switching Protocols”表示服务端接受 WebSocket 协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的 WebSocket 连接握手成功, 后续就可以进行 TCP 通讯了。

WebSocket与Socket的关系

Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。

WebSocket则是一个典型的应用层协议。

WebSocket 与 HTTP

WebSocket 协议在2008年诞生,2011年成为国际标准。现在所有浏览器都已经支持了。WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。

HTTP 有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个 HTTP 请求合并为一个,但是 Websocket 其实是一个新协议,跟 HTTP 协议基本没有关系,只是为了兼容现有浏览器,所以在握手阶段使用了 HTTP 。

下面一张图说明了 HTTP 与 WebSocket 的主要区别:

383affb826591b85aa25355294c20a9b.png

WebSocket 的其他特点:

  • 建立在 TCP 协议之上,服务器端的实现比较容易。

  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

  • 数据格式比较轻量,性能开销小,通信高效。

  • 可以发送文本,也可以发送二进制数据。

  • 没有同源限制,客户端可以与任意服务器通信。

  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

WebSocket原理及如何实现长连接

websocket相当于HTTP的一个补充协议,通过http request建立连接,不需要再发送request,之后保持一端与另外一端的TCP连接。

在实际应用中,一个socket与另外一端的连接可能会经过千山万水(多个路由、多个中间服务器),中间有各种转发、过滤。

所以后来更新了,添加了Ping/Pong Frame(RFC 6455 - The WebSocket Protocol),可以说这是一个特殊的数据包,

这个数据包只有简单的一些的元数据,不涉及数据传输。维持连接的活跃性与持久性。

参考文献

  • httpss://zh.wikipedia.org/wiki/WebSocket

  • httpss://www.oschina.net/translate/9-killer-uses-for-websockets

  • httpss://vue3js.cn/interview

  • httpss://www.cnblogs.com/Javi/p/9303020.html

  • httpss//blog.csdn.net/qq_35447305/article/details/52966105

 
 

end

 
 

BAT等大厂Java面试经验总结

68812f52371bd74cdf950c369b97dcfc.png

想获取 Java大厂面试题学习资料

扫下方二维码回复「BAT」就好了

回复 【加群】获取github掘金交流群
回复 【电子书】获取2020电子书教程
回复 【C】获取全套C语言学习知识手册
回复 【Java】获取java相关的视频教程和资料
回复 【爬虫】获取SpringCloud相关多的学习资料
回复 【Python】即可获得Python基础到进阶的学习教程
回复 【idea破解】即可获得intellij idea相关的破解教程
关注我gitHub掘金,每天发掘一篇好项目,学习技术不迷路!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值