HTTP长连接和Websocket的区别

发布时间 2023-12-08 11:57:50作者: 炎黄子孙,龙的传人

一、HTTP 和 WebSocket 都是基于 TCP 协议

TCP建立每个连接都需要三次握手。

二、HTTP 短连接

HTTP 1.0(短链接)就是浏览器和服务器每进行一次HTTP操作,就建立一次TCP连接,数据传输完成后,TCP连接就随之关闭,即:客户端与服务端的连接均必须被切断。

三、HTTP 长连接

HTTP 1.1(长连接)中使用持久连接,服务器在发送响应以后,并不关闭该TCP连接。后续的请求和响应报文仍能在该TCP连接上传输。

如果浏览器支持keep-alive,它会在请求的头字段中添加:

Connection: Keep-Alive

当服务器收到请求,作出回应的时候,它也在响应中添加如下HTTP头:

Connection: Keep-Alive

HTTP 长连接 response 报文:

HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache

(body)

HTTP长连接的优势

  • 减少了后续请求的延迟(无需再进行握手)
  • 降低拥塞控制 (TCP连接的数量减少了)
  • 较少的CPU和内存的使用(由于同时打开的连接的减少了)
  • 允许请求和应答的HTTP流水线
  • 无需关闭TCP连接即可报告错误

HTTP长连接的劣势

服务器可以建立的连接数量受到端口数与文件句柄数的限制。如需和客户端保持一个开启时间较长的连接,那么服务器可以同时服务的客户端数量则会减少。

为了应对这一问题,Apache 2.0 httpd的默认连接过期时间仅有15秒,而更新版本的Apache 2.2仅有5秒。
通过设置较短的过期时间,一个客户端能够在最开始时快速的传输多个web页组件,而不会长期占用服务器的进程或端口资源。但是,这样也会使得客户端在需要发起新请求时,原先建立的持久连接可能已经被服务端关闭。这直接削弱了持久连接带来的优势。

四、WebSocket 连接建立过程

WebSocket 建立连接需要先通过一个 http 请求进行和服务端握手。握手通过后连接就建立并保持了。

一个典型的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

服务端返回一个请求:

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

Websocket握手阶段是借助于HTTP协议,握手完成以后,仍在刚才的TCP连接上完成后续的传输。
此时这个连接并不会断掉,而浏览器和服务端可以用这个连接相互发消息。
但是这个时候连接就不是 http 连接而是升级成了 WebSocket 连接。浏览器和服务端相互发送的不是 http 请求。

HTTP长连接和Websocket的区别

概念:

  • 单工: 数据传输只允许在一个方向上的传输,只能一方来发送数据,另一方来接收数据并回发。例如:HTTP
  • 半双工:数据传输允许两个方向上的传输,但是同一时间内,只可以有一方发送或接受消息。例如:传呼机
  • 全双工:同时可进行双向传输。例如:websocket

HTTP长连接:单工通信

HTTP长连接还是基于HTTP协议,工作模式依旧是一问一答。
即:客户端发起一次请求,服务器回应最多一次响应。这个本质并没有得到改变,改变的只是在同一个TCP连接上可以进行多次请求和多次响应,不需要每次都进行三次重连握手了。

Websocket:全双工通信

Websocket客户端可以只请求一次服务器,连接建立后,双方可以互发消息。这点是HTTP做不到的,HTTP只能由客户端主动给服务端发消息,而服务端只能被动响应消息。
当然了,为了检查Websocket连接是否还在,前端会使用心跳检测,但这不影响当连接建立之后,服务器可以主动给客户端发送信息的本质。