HTTP 的瓶颈:
- 一条连接上只可发送一个请求。
- 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
- 请求、响应首部未经压缩就发送。首部信息越多延迟越大。
- 发冗长的首部。每次相互发送相同的首部造成的浪费较多。
- 可任意选择数据压缩格式。非强制压缩发送。
SPDY
SPDY 的出现正是为了解决这些问题,SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与传输层之间通过插入会话层的形式运作。同时,SPDY 规定通信中使用 SSL。
- HTTP - 应用层
- SPDY - 会话层
- SSL - 表示层
- TCP - 传输层
使用 SPDY 后,HTTP 协议额外获得以下功能:
- 多路复用流。一个 TCP 连接上,处理所有的 HTTP 请求。
- 赋予请求优先级。
- 压缩 HTTP 首部。
- 推送功能。这样服务器可直接发送数据,而不必等待客户端请求。
- 服务器提示功能。服务器可以主动提示客户端请求所需的资源。由于在客户端发现资源之前就可以获知资源的存在,因此在资源已缓存等情况下,可以避免发送不必要的请求。
然而 SPDY 也不是完美的,也还有一些未解决的问题:
- 只是将单个域名(IP 地址)的通信多路复用,所以当使用多个域名下的资源时,效果将受到限制。
- 还有一些不是 HTTP 协议导致的问题,如 web 内容的编写方式。
WebSocket
WebSocket是Web浏览器与Web服务器之间全双工通信。
这是一套独立协议,一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可相互发送 JSON、XML、HTML 或图片等任意格式的数据。
但由于是建立在 HTTP 基础上的协议,连接的发起方仍是客户端,而一旦 WebSocket 通信连接后,不论服务器还是客户端,任意一端都可直接向对方发送报文。
建立连接时还是用HTTP协议请求、响应完成握手,后续就不再发送HTTP数据帧,而是WebSocket独立数据帧。
特点:
- 推送功能。服务器可直接发送数据,不必等客户端的请求。
- 减少通信量。只要建立起 WebSocket 连接,就希望一直保持连接状态。而且 WebSocket 的首部信息也少,连接次数、通信量都相应减少。
- 建立在TCP协议之上,服务端实现比较容易。
- 与HTTP协议有良好兼容性,默认端口相同,握手阶段也是用HTTP协议,不容易被屏蔽。
- 可以发送文本,也可以发送二进制。
- 没有同源限制,客户端可以与任意服务器通信。
HTTP/2.0
新的概念
帧:数据通信的最小单位,以二进制压缩格式存放内容。来自不同数据流的帧可以交错发送,然后根据每个帧头的数据流标识符重新组装。帧信息包含:类型、长度、标记、流标识、palyload。
消息:HTTP/2.0中逻辑上的HTTP消息,如请求和响应,消息由一个或多个帧组成。
流:连接中的虚拟信道,可以承载双向消息传输,包含1或多条消息。每个流有唯一整数标识符。为了防止两端双向流标识符冲突,客户端发起的流具有奇数ID,服务端发起的流具有偶数ID。特点:
- 双向性:同一流内,可以同时发送和接收数据。
- 有序性:流中传输二进制帧,帧在流上的被发送和被接收都是按序进行的。
- 并行性:流中的二进制帧都并行传输的,无需按序等待。帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。
- 流的创建和关闭可以被客户端或服务端任意一方执行。
连接:包含1或多个流,所有通信都在一个TCP连接上完成。该连接可以承载任意数量的双向数据流。
二进制分帧
把传输信息分为Header帧和Data帧,对应HTTP/1.x的首部信息和实体信息。
多路复用/共享连接
HTTP/1.x中虽然可以通过长连接在一个连接中发起多个请求,并处理每个请求的响应。但客户端在同一域名下的请求会有一定数量限制,超出会被阻塞,要实现多流并行,只能开启多个TCP连接。
HTTP/2.0单个TCP连接可以承载任意数量的双向数据流,并且可以并处请求和响应,实现单个连接的多路复用、共享连接。
首部压缩
HTTP/2.0在客户端和服务端使用首部表来跟踪和存储之前发送的键值对,对于相同的数据,不在重复发送。
首部表在HTTP/2.0连接期间始终存在,由客户端和服务端共同渐进更新。
请求优先级
每个流都可以带上一个31 bit的优先值。服务器可以根据流的优先级,控制资源分配。
服务端推送
服务端可以对客户端请求发送多个响应,服务端向客户端推送资源无需明确发起请求。这可以让在遵循同源的情况下,不同的页面可以共享缓存资源。