Websocket由来
WebSocket协议是08年诞生,11年成为国际标准,他出现的原因自然是因为以前的http请求不足以满足用户需求,HTTP请求的性能不够用,因为HTTP的协议上的限制,但基于 HTTP 的 Web 浏览器的使用环境已遍布全球,因此无法完全抛弃 HTTP
举一个例子,在Facebook等网站上,某一时刻有几百万人发布了内容,服务器上需要更新很多内容,还想要直接把内容反馈给客户端,HTTP协议就无法妥善的处理好这项任务。因为HTTP是单项通信,他想知道服务端有没有更新,就必须去发起请求确认,但如果服务端没有更新,那么这次请求就是徒劳的。
- ● ●●一条连接上只可发送一个请求。
- ● ●●请求只能从客户端开始。客户端不可以接收除响应以外的指令。
- ● ●●请求 / 响应首部未经压缩就发送。首部信息越多延迟越大。
- ● ●●发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
- ● ●●可任意选择数据压缩格式。非强制压缩发送。
WebSocket发展历史
前端轮询(Ajax局部刷新)
:简单理解就是比如 前端每隔1s就去服务端发一次请求,查看服务端是否有更新情况,有更新状态就把更新的内容返回响应,没有就不返回响应,但这样还是会导致大量请求产生,而且协议本身问题也没有解决
Comet解决方法(延迟应答,模拟实现服务器端向客户端推送功能)
即Comet会先将响应置于挂起状态 ,当服务器端有内容更新时,再返回该响应 ,但是为了保持相应一次连接的时间太长,一直维持http请求连接也会消耗很多资源。
这些技术,一定程度上使HTTP得到了改善,但是HTTP本身的协议限制令人束手无策,为了根本性改善,必须要有一些协议层面上的改动。
SPDY 协议
SPDY尝试在TCP/IP的应用层和运输层之间通过新添加会话层形式运作,同时考虑安全性问题,SPDY规定通信中使用SSL。
通过会话层可以控制对数据的流动,但是采用HTTP建立连接,所以HTTP有的,SPDY也有。并且获得了额外的功能、
-
多路复用流 SPDY允许在同一个TCP连接上并行传输多个HTTP请求和响应,避免了HTTP1.1中的"队头阻塞"问题。
-
请求优先级 SPDY允许客户端为不同的HTTP请求设置优先级,这样服务器可以优先处理重要的请求。
-
数据压缩 SPDY使用HPACK算法对HTTP头部信息进行压缩传输,可以大幅减少网络传输的数据量。
-
服务器推送 SPDY允许服务器主动向客户端推送资源,而不需要客户端明确请求。
-
连接持久化 SPDY使用长连接,避免了频繁建立和关闭TCP连接的开销
但是SPDY真的消除了Web瓶颈了吗?
使用SPDY的时候需要Web浏览器以及Web服务器为对应的SPDY做出一定程度的改动 。相对说比较麻烦。
还有单域名限制 ,SPDY是基于单个域名(IP地址)的多路复用,也就是说它只能优化单个域名下资源的传输。当客户端需要从不同域名加载资源时,仍然需要建立新的TCP连接。和安全性问题SPDY使用单一的TCP连接进行多个HTTP请求的传输,这在某种程度上增加了安全隐患
使用浏览器进行全双工通信的WebSocket
因为HTTP的限制,所以想要彻底解决瓶颈问题,必须要实现一套新协议及API。
WebSocket 协议由 IETF 定为标准,WebSocket API 由 W3C 定为标准。
WebSocket 的工作流程大致如下:
-
由于是建立在 HTTP 基础上的协议,借用了 HTTP 协议来完成一部分握手。因此连接的发起方仍是客户端,客户端(通常是浏览器)发起 WebSocket 连接请求,连接到服务器的 WebSocket 端点。这个过程称为"WebSocket 握手"。
-
握手成功后,客户端和服务器建立了一个持久的 TCP 连接。这个连接会一直保持打开状态,直到任意一方主动关闭它。之后通信时可以省略部分状态信息;
-
在这个连接上,双方可以随时发送和接收数据帧。WebSocket 协议定义了数据帧的格式,支持文本和二进制数据。而HTTP则需要进行文本编码和解码
-
与 HTTP 不同,WebSocket 连接是全双工的,双方可以同时发送和接收数据,没有请求-响应的限制。
-
WebSocket 连接支持自定义子协议,客户端和服务器可以协商使用特定的子协议进行通信。
-
WebSocket 还提供了心跳机制,用于检测连接是否中断,以及自动重连机制。
HTTP 协议的握手请求中,多了这么几个东西,意思是告诉服务器,我要用websocket协议
首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:用来验证对方是不是真的是 WebSocket 在回复。
最后, Sec-WebSocket-Version 是告诉服务器所使用的 WebSocket Draft (协议版本)
当服务器返回如下响应,表示已经接收请求,并成功建立websocket了然后, Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key 。 可以将 Sec-WebSocket-Key
和 Sec-WebSocket-Accept
之间的关系理解为一种"签名"的机制。用来证明双方连接的是websocket连接。
至此,HTTP 已经完成它所有工作了,接下来就是完全按照 WebSocket 协议进行了。
WebSocket 的主要优势包括:
-
实时双向通信:可以实现服务端主动向客户端推送数据。
-
较低的通信延迟:WebSocket 连接是持久的,不需要重复的握手过程。
-
更小的通信开销:WebSocket 协议头部较 HTTP 更小。
-
支持跨域通信:WebSocket 连接不受同源策略的限制。
我在学习websocket的时候遇到的一些疑惑以及解答
我们知道http发送请求报文的时候是要有多种协议进行封装自己,然后传输到很远的地方,中间要经过路由器、交换机等,最后服务端才能够接收到请求,并用相同的方式返回,那ws既然也是符合osi七层模型,同时它也需要传输的过程中经过路由器、交换机等,路由器和路由器之间又没有实质连接,ws是怎么在完成连接后的发送消息时,路由器们怎么确认每次发送的都是同一个人?也就是怎么保持长连接的?
答:
ws和http一样,在从客户端发出去的时候也是要经过多层协议封装的
-
WebSocket 数据帧:
-
WebSocket 协议定义了一系列的数据帧格式,用于封装应用层的实际数据。
-
这些数据帧包含了诸如消息类型、长度、负载数据等信息。
-
-
TCP 报文段:
-
WebSocket 数据帧会被进一步封装到 TCP 报文段中进行传输。
-
TCP 报文段包含了源端口、目标端口、序号、确认号等信息。
-
-
IP 数据报:
- TCP 报文段会被再次封装到 IP 数据报中,加入源 IP 地址和目标 IP 地址等信息。
-
数据链路层帧:
-
IP 数据报最终会被封装到数据链路层的帧结构中,添加MAC地址等信息。
-
这样数据就可以在物理网络中进行传输了。
-
当封装好之后交换机和路由器只需要关注前3层(数据链路层、网络层、传输层),根据目的地址信息完成数据包的转发。对于应用层的 WebSocket 数据帧,它们是无感知的。所以,中间的网络设备不需要实时检测 TCP 连接状态,也不需要理解 WebSocket 协议的细节。它们只需要按照常规的网络数据包转发机制工作即可。直到接收端接收到ws的信息,然后用ws的协议去解析它,然后获取数据,因为之前已经建立过ws连接,此时在客户端和服务端成功建立 WebSocket 连接之后,双方都会保存相关的 TCP 连接状态信息。
-
客户端保存状态信息:
-
客户端会保存与服务端建立的 TCP 连接的各种状态信息,包括连接 ID、IP 地址、端口号等。
-
这些信息有利于客户端后续通过这个现有连接发送和接收 WebSocket 数据帧。
-
-
服务端保存状态信息:
-
服务端同样会保存与客户端建立的 TCP 连接的各种状态信息。
-
这些信息有利于服务端识别客户端,并通过这个现有连接发送和接收 WebSocket 数据帧。
-
-
双向维护连接状态:
-
客户端和服务端都需要维护 WebSocket 连接的状态信息,确保连接的持续和稳定。
-
如果任何一方的连接状态丢失,都可能导致 WebSocket 通信失败。
-
-
心跳机制维护连接:
-
为了防止 TCP 连接因长时间不活跃而被中间设备断开,WebSocket 协议会定期发送"心跳"消息。
-
心跳消息有助于双方持续维护 TCP 连接的状态信息,保证 WebSocket 通信的可靠性。
-
而http因为它的无状态性,无法主动推送数据等无法实现ws的功能。
关于ws的全双工,它是建立在TCP的基础上的,TCP本就支持全双工通道,而且ws的数据帧格式支持双向传输,尽管HTTP也是建立在TCP协议上的,但是为什么http也是建立在TCP基础的,它为什么不能实现全双工功能?
-
HTTP 的请求-响应模式:
-
HTTP 采用了经典的请求-响应模型,客户端发起请求,服务端返回响应。
-
这种模式下,服务端只能被动地响应客户端的请求,无法主动向客户端推送数据。
-
-
HTTP 的短连接特性:
-
HTTP 通常使用短暂的 TCP 连接,即一个请求-响应后就关闭连接。
-
这种短连接模式下,无法保持长期的双向通信状态。
-
-
HTTP 头部设计:
-
HTTP 的头部设计主要面向请求-响应模式,缺乏支持双向通信的字段。
-
例如,HTTP 头部没有定义服务端主动推送数据的机制。
-
-
HTTP 语义定位:
- HTTP 最初是为了浏览网页而设计的,其语义定位在于文档传输,而非实时双向通信。
也就是http是被协议内容约束了。
为什么说ws发送数据比http要快?仅仅是因为它传输的是二进制数据吗?http也能够传输二进制数据,那么他快在哪里?
-
连接方式不同:
- WebSocket 使用持久性的 TCP 连接,一旦建立连接就可以双向传输数据。
- HTTP 是基于请求-响应模式的短连接,每次传输数据都需要重新建立连接。
-
报文头部开销减少:
- WebSocket 的数据帧结构更加精简,只包含必要的元数据信息。
- HTTP 的报文头部相对较大,需要在每次请求时都传输。!
-
数据传输模式不同:
- WebSocket 采用"推"模式,服务器可以主动向客户端推送数据。
- HTTP 是"拉"模式,客户端必须主动发起请求才能获取数据。
-
网络开销减少:
- WebSocket 复用 TCP 连接,避免了 HTTP 中频繁的 TCP 三次握手过程。
- 这减少了网络往返时延和连接建立的开销。