HTTP/WebSocket详解
Http详解
HTTP定义
HTTP是一个客户端和服务器端请求和响应的标准TCP,其实建立在TCP之上的
HTTP 请求格式
HTTP请求格式主要有四部分组成,分别是:请求行、请求头、空行、消息体,每部分内容占一行
<request-line> <general-headers> <request-headers> <entity-headers> <empty-line> [<message-body>]
请求行:请求行是请求消息的第一行,由三部分组成:分别是请求方法(GET/POST/DELETE/PUT/HEAD)、请求资源的URI路径、HTTP的版本号
GET /index.html HTTP/1.1
请求头:请求头中的信息有和缓存相关的头(Cache-Control,If-Modified-Since)、客户端身份信息(User-Agent)等等
Cache-Control:max-age=0 Cookie:gsScrollPos=; _ga=GA1.2.329038035.1465891024; _gat=1 If-Modified-Since:Sun, 01 May 2016 11:19:03 GMT User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
消息体:请求体是客户端发给服务端的请求数据,这部分数据并不是每个请求必须的
HTTP 响应格式
服务器接收处理完请求后返回一个HTTP相应消息给客户端,HTTP响应消息的格式包括:状态行、响应头、空行、消息体。每部分内容占一行
<status-line> <general-headers> <response-headers> <entity-headers> <empty-line> [<message-body>]
状态行:状态行位于相应消息的第一行,有HTTP协议版本号,状态码和状态说明三部分构成
HTTP/1.1 200 OK
响应头:响应头是服务器传递给客户端用于说明服务器的一些信息,以及将来继续访问该资源时的策略
Connection:keep-alive Content-Encoding:gzip Content-Type:text/html; charset=utf-8 Date:Fri, 24 Jun 2016 06:23:31 GMT Server:nginx/1.9.12 Transfer-Encoding:chunked
响应体:响应体是服务端返回给客户端的HTML文本内容,或者其他格式的数据,比如:视频流、图片或者音频数据
HTTP协议补充
请求行-请求方法
GET 请求获取Request-URI所标识的资源
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
响应行-状态码
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
附加
Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response,而且这个response也是被动的,不能主动发起
WebSocket
WebSocket是HTML5下一种新的协议,它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的,它与HTTP一样通过已建立的TCP连接来传输数据
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错误,并关闭连接
服务器端回复
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=
附:Sec-WebSocket-Accept的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,HTTP/1.1 101 Switching Protocols表示服务端接受WebSocket协议的客户端连接,经过这样的请求-响应处理后,两端的WebSocket连接握手成功, 后续就可以进行TCP通讯了
数据传输
1.以帧形式传输(大数据分片/支持实时生成传递)
2.客户端到服务端的数据帧必须进行掩码处理,服务端拖接收到未经掩码处理的数据帧,须主动关闭连接/服务端到客户端的数据一定不能加掩码,客户端接收到经过掩码的实际帧,须主动关闭连接/发现错误的一方可以发送close帧,关闭连接
帧类型
帧类型是由一个4位长的叫Opcode的值表示
1.Opcode = 0 继续
表示此帧是一个继续帧,需要拼接在上一个收到的帧之后,来组成一个完整的消息,由于这种解析特性,非控制帧的发送和接收必须是相同的顺序
2.Opcode = 1 文本帧
3.Opcode = 2 二进制帧
4.Opcode = 3 – 7 未来使用(非控制帧)
5.Opcode = 8 关闭连接(控制帧)
此帧可能会包含内容,以表示关闭连接的原因
通信的某一方发送此帧来关闭WebSocket连接,收到此帧的一方如果之前没有发送此帧,则需要发送一个同样的关闭帧以确认关闭,如果双方同时发送此帧,则双方都需要发送回应的关闭帧
理想情况服务端在确认WebSocket连接关闭后,关闭相应的TCP连接,而客户端需要等待服务端关闭此TCP连接,但客户端在某些情况下也可以关闭TCP连接
6.Opcode = 9 Ping
类似于心跳,一方收到Ping,应当立即发送Pong作为响应
7.Opcode = 10 Pong
如果通信一方并没有发送Ping,但是收到了Pong,并不要求它返回任何信息,Pong帧的内容应当和收到的Ping相同,可能会出现一方收到很多的Ping,但是只需要响应最近的那一次就可以了
8.Opcode == 11 – 15 未来使用(控制帧)
已存问题
缺陷:HTTP/WebSocket 连接往往要经过无数的路由,防火墙等中间网络链路,易进入某种半死不活状态
* 解决方案*:服务器和客户端能够发送 Ping/Pong Frame,该 Frame 是一种特殊的数据包,只包含一些元数据而不需要真正的 Data Payload,可以在不影响 Application 的情况下维持住中间网络的连接状态
相比HTTP长连接,WebSocket优势
1.真正的全双工方式,建立连接后客户端与服务器端是完全平等的,可以互相主动请求,而HTTP长连接基于HTTP,是传统的客户端对服务器发起请求的模式;
2.HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,信息交换效率很低,Websocket协议通过第一个request建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现(主流浏览器都已支持HTML5),此外还有 multiplexing、不同的URL可以复用同一个WebSocket连接等功能
补充区分
真伪长连接
keep-alive ,一种为了达到复用tcp连接的“协商”行为,双方并没有建立正真的连接会话,服务端也可以不认可,也可以随时(在任何一次请求完成后)关闭掉;
WebSocket ,它本身就规定了是正真的、双工的长连接,两边都必须要维持住连接的状态,另外,http协议决定了浏览器端总是主动发起方,http的服务端总是被动的接受、响应请求,从不主动,而WebSocket协议,在连接之后,客户端、服务端是完全平等的,不存在主动、被动之说
HTTP&WebSocket联系
客户端开始建立 WebSocket 连接时要发送一个 header 标记了 Upgrade 的 HTTP 请求,表示请求协议升级,因此服务器响应,直接在现有的 HTTP 服务器软件和现有的端口上实现 WebSocket 协议,重用现有代码,然后再回一个状态码为 101 的 HTTP 响应完成握手,再往后发送数据时撇开HTTP,简而言之,WebSocket需要HTTP负责建立WebSocket连接,然后独立运行在TCP协议传输层上的应用协议
补充异同
相同点
1.基于TCP的应用层协议。
2都使用Request/Response模型进行连接的建立。
3.在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码。
4.都可以在网络中传输数据。
不同点
1.WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用。
2.WS的连接不能通过中间人来转发,它必须是一个直接连接。
3.WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
4.WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息。
5.WS的数据帧有序