本文主要是介绍大厂面试官:你真的了解WebSocket么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
希望大家能关注点赞,创作不易且没收益,您的小小举动却能给予我大大的鼓励,会激励我继续创作出高质量文章😘,更多内容可看我主页~
WebSocket的基本原理
前言:之前一直用HTTP,调URL的时候都是http开头, 但最近接触了websocket,遇见ws开头的url就懵逼了,所以就好好学习了一番,这篇文章应该能帮你很快了解什么是websocket。
点击这里学习springBoot下使用websocket
1、什么是WebSocket?
- WebSocket协议是一个网络协议,允许两个相连的端在一个单一TCP连接上进行全双工消息通信。
- WebSocket是一种与HTTP不同的协议。它与HTTP协议两者都位于OSI模型的应用层,并且都依赖于传输层的TCP协议。虽然它们不同,但是RFC 6455中规定:
it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries
(WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介),从而使其与HTTP协议兼容。 为了实现兼容性,WebSocket握手使用HTTP Upgrade头[1]从HTTP协议更改为WebSocket协议。 - WebSocket协议支持Web浏览器(或其他客户端应用程序)与Web服务器之间的交互,具有较低的开销,便于实现客户端与服务器的实时数据传输。 服务器可以通过标准化的方式来实现,而无需客户端首先请求内容,并允许消息在保持连接打开的同时来回传递。通过这种方式,可以在客户端和服务器之间进行双向持续对话。
- WebSocket协议规范将
ws(WebSocket)和
wss(WebSocket Secure)
定义为两个新的统一资源标识符(URL),分别对应明文和加密连接。
2、我们使用WebSocket去解决什么问题?
在一般情况下,我们使用HTTP协议就可以完成我们的数据传输,如果需要加密,大不了使用HTTPS协议进行加密传输,那么我们为什么还需要WebSocket?因为HTTP协议下的通信只能由客户端发起,不能由服务端发起,这也就是Http协议的单向请求特点,
(这里的单向请求,是指我们在前端经常使用的GET、PUT、POST、HEAD等请求方法,这些是只能由客户端方进行发送请求)
当我们需要让服务器推送给客户端消息的时候,也就是服务器向客户端发起请求的时候,Http协议就会显得有些吃力,只能让客户端采用轮询的方法不断发出请求进行连接从而达到同样的效果,但需要消耗大量的资源。
因此,我们需要一个可以允许服务器主动向客户端发送消息的协议,WebSocket也因此诞生。
3、WebSocket协议沟通流程
WebSocket经过一次握手就可以跟WebSocket服务器建立全双工通信的连接,接着在建立成功之后,客户端就可以向服务端发送数据,服务端也可以主动向客户端推送数据。
WebSocket的握手协议:
- WebSocket 是独立的、创建在TCP上的协议。
- Websocket 通过 HTTP/1.1 协议的101状态码进行握手。
- 为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(Handshaking)
整体的流程
在WebSocket协议中,整体的流程,大致可以分为两部分:
第一阶段:握手建立连接过程
需要建立客户端与服务端的连接,这里使用了进行了”握手”。
- 首先客户端会发送一个握手包。这里就体现出了WebSocket与Http协议的联系,握手包的报文格式必须符合HTTP报文格式的规范。其中:
-
方法必须位GET方法
-
HTTP版本不能低于1.1
-
必须包含Upgrade头部,值必须为websocket
-
必须包含Sec-WebSocket-Key头部,值是一个Base64编码的16字节随机字符串。
-
必须包含Sec-WebSocket-Version头部,值必须为13
-
其他可选首部可以参考:https://tools.ietf.org/html/rfc6455#section-4.1
- 服务端验证客户端的握手包符合规范之后也会发送一个握手包给客户端。格式如下:
- 必须包含Connection头部,值必须为Upgrade
- 必须包含一个Upgrade头部,值必须为websocket
- 必须包含一个Sec-Websocket-Accept头部,值是根据如下规则计算的:
- 首先将一个固定的字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接到Sec-WebSocket-Key对应值的后面。
- 对拼接后的字符串进行一次SHA-1计算
- 将计算结果进行Base-64编码
- 客户端收到服务端的握手包之后,验证报文格式时候符合规范,以2中同样的方式计算Sec-WebSocket-Accept并与服务端握手包里的值进行比对。
这三步中的每一步都要完成并且通过,否则不能建立WebSocketl连接。这就是第一阶段的握手。
这一部分说明了HTTP与WebSocket是存在交集的两个不同的协议,在建立连接后,接下来一阶段,两个消息便没有了相同内容。
第二阶段:自由通信过程
在建立连接之后,两端就可以进行自由的通信,客户端可以给服务端发送消息,服务端也可以给客户端发送消息,这一部分也是webSocket不同于HTTP协议的部分,该部分为全双工通信,正是webSocket的优势所在。
第三阶段: 断开连接过程
在结束通信后,进行连接的关闭。连接关闭的过程,并不是简单的一方直接断开连接,而是双方均遵守一定规则去断开连接,下面有两个正常情况:
-
服务端主动断开连接。服务器会向客户端发送状态码code和客户端在收到服务器的这个断连请求后应该调用close方法来关闭,否则连接会先入停滞状态等待客户端响应。
-
**客户端主动断开连接。**客户端先要调用close方法,这个操作会发送一个断连请求到服务器上,服务器收到这个请求后把TCP连接断开即可。但是服务器程序是自己写的,这个请求也需要自己解析。
若不是正常情况进行断开连接,则websocket对象则会调动应急方法给未断开的某一方发送状态码,从而激发未断开一方的close事件进行关闭连接。当然状态码有很多种,不同状态码代表着不同的状态。
4、websocket的特点以及Http协议进行对比
4.1 WebSocket协议的特点
-
较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
-
更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
-
保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
-
更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
-
可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
-
**更好的压缩效果。**相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
-
建立在 TCP 协议之上,服务器端的实现比较容易。
-
与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
-
Websocket与HTTP和HTTPS使用相同的TCP端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。
4.2 对比
同时 ,两者的URL分别为
WebSocket协议的url:ws://example.com:80/some/path
加密 :wss://example.com:80/some/path
Http协议的url: http://example.com:80/some/path
加密:https://example.com:80/some/path
应用场景
根据websocket的特点,适用于一些服务端需要发送消息的场景,以下只是简单举例:
- 弹幕
- 媒体聊天
- 协同编辑
- 基于位置的应用
- 体育实况更新
- 股票基金报价实时更新
参考
阮一峰的网络日志 WebSocket教程
维基百科
WebSocket协议部分内容
这篇关于大厂面试官:你真的了解WebSocket么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!