webSocket和http关系、WebSocket原理

本文详细介绍了WebSocket协议,对比HTTP协议,解释了WebSocket如何实现持久连接及双向通信。并通过与长轮询和Ajax轮询的对比,展示了WebSocket的优势。

一、WebSocket是HTML5中的协议,支持持久连接;而Http协议不支持持久连接。

首先HTMl5指的是一系列新的API,或者说新规范,新技术。WebSocket是HTML5中新协议、新API.

Http协议本身只有1.0和1.1,也就是所谓的Keep-alive,把多个Http请求合并为一个。

二、WebSocket是什么样的协议,具体有什么优点。

首先,相对于Http这种非持久的协议来说,WebSocket是一种持久化的协议。

举例说明:

(1)Http的生命周期通过Request来界定,也就是Request一个Response,那么在Http1.0协议中,这次Http请求就结束了。

在Http1.1中进行了改进,是的有一个Keep-alive,也就是说,在一个Http连接中,可以发送多个Request,接收多个Response。

但是必须记住,在Http中一个Request只能对应有一个Response,而且这个Response是被动的,不能主动发起。

(2)WebSocket是基于Http协议的,或者说借用了Http协议来完成一部分握手,在握手阶段与Http是相同的。

首先我们来看个典型的Websocket握手(借用Wikipedia的。。)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。
我会顺便讲解下作用。
Upgrade: websocket
Connection: Upgrade
这个就是Websocket的核心了,告诉Apache、Nginx等服务器:注意啦,窝发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
首先,Sec-WebSocket-Key 是一个Base64 encode的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理。
然后,Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~
最后,Sec-WebSocket-Version 是告诉服务器所使用的Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 脱水:服务员,我要的是13岁的噢→_→

然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦!
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
这里开始就是HTTP最后负责的区域了,告诉客户,我已经成功切换协议啦~
Upgrade: websocket
Connection: Upgrade
依然是固定的,告诉客户端即将升级的是Websocket协议,而不是mozillasocket,lurnarsocket或者shitsocket。
然后,Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key。服务器:好啦好啦,知道啦,给你看我的ID CARD来证明行了吧。。
后面的,Sec-WebSocket-Protocol 则是表示最终使用的协议。

至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了。
其后是WebSocket协议的工作。

三、Long poll 和Ajax轮询以及WebSocket的原理
1、Ajax轮询的原理。
场景如下:
客户端:啦啦啦,有没有新信息(Request)
服务端:没有(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:没有。。(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:你好烦啊,没有啊。。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:好啦好啦,有啦给你。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:。。。。。没。。。。没。。。没有(Response) —- loop

2、long poll的原理。

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。
场景如下:
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)
服务端:额。。 (等待到有消息的时候)。。来 给你(Response)
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。
何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。
简单地说就是,服务器是一个很懒的冰箱(这是个梗)(不会、不能主动发起连接),但是上司有命令,如果有客户来,不管多么累都要好好接待。

说完这个,我们再来说一说上面的缺陷
从上面很容易看出来,不管怎么样,上面这两种都是非常消耗资源的。
ajax轮询 需要服务器有很快的处理速度和资源。(速度)
long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)
所以ajax轮询 和long poll 都有可能发生这种情况。

客户端:啦啦啦啦,有新信息么?
服务端:月线正忙,请稍后再试(503 Server Unavailable)
客户端:。。。。好吧,啦啦啦,有新信息么?
服务端:月线正忙,请稍后再试(503 Server Unavailable)

客户端:
然后服务端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。

3、WebSocket的原理。

通过上面这个例子,我们可以看出,这两种方式都不是最好的方式,需要很多资源。
一种需要更快的速度,一种需要更多的’电话’。这两种都会导致’电话’的需求越来越高。
哦对了,忘记说了HTTP还是一个状态协议。
通俗的说就是,服务器因为每天要接待太多客户了,是个健忘鬼,你一挂电话,他就把你的东西全忘光了,把你的东西全丢掉了。你第二次还得再告诉服务器一遍。

所以在这种情况下出现了,Websocket出现了。
他解决了HTTP的这几个难题。
首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。
所以上面的情景可以做如下修改。
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈

就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)
这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。
那么为什么他会解决服务器上消耗资源的问题呢?
其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。
简单地说,我们有一个非常快速的接线员(Nginx),他负责把问题转交给相应的客服(Handler)。
本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。
Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。
这样就可以解决客服处理速度过慢的问题了。

同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输identity info(鉴别信息),来告诉服务端你是谁。
虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。
但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。

同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了

至于怎么在不支持Websocket的客户端上使用Websocket。。答案是:不能
但是可以通过上面说的 long poll 和 ajax 轮询来 模拟出类似的效果

<think>我们之前讨论了HTTP/2长连接的原理,现在用户想了解WebSocketHTTP/2的对比情况。我将从多个维度进行对比分析,包括协议设计目标、通信模式、性能特点、适用场景等。 首先明确两种协议的本质差异: - HTTP/2 是HTTP协议的进化版本,旨在优化Web页面的加载性能,保持请求/响应模式。 - WebSocket 是独立的全双工通信协议,设计初衷是打破HTTP的无状态限制,实现实时双向通信。 对比维度: 1. **协议基础** - **WebSocket**:基于独立的TCP连接,通过HTTP升级握手建立(状态码101),之后切换到二进制帧传输。 - **HTTP/2**:在TCP连接上直接传输二进制帧,无需协议切换,但保持HTTP语义。 2. **通信模式** | **特性** | WebSocket | HTTP/2 | |------------------|-------------------------------|----------------------------| | 交互模式 | **全双工双向通信** | 半双工(请求-响应) | | 数据推送 | 服务器可主动推送 | 仅客户端可发起请求 | | 实时性 | 毫秒级延迟 | 依赖轮询或Server Push[^1] | 3. **连接管理** - **WebSocket**:单一长连接贯穿整个会话周期(小时/天级),心跳包维持连接活性。 - **HTTP/2**:TCP连接复用实现高效传输,但连接空闲超时通常较短(分钟级)[^2]。 4. **数据传输效率** - **头部开销**:WebSocket每个消息帧仅6字节头部;HTTP/2通过HPACK压缩头部,但仍需携带流ID等元信息。 - **小消息场景**:WebSocket效率更高(无重复Header),HTTP/2在请求密集时更优(多路复用抵消开销)。 5. **应用场景** ```mermaid graph LR A[选择协议] --> B{是否需要服务器主动推送?} B -->|是| C[WebSocket] B -->|否| D{是否高频请求?} D -->|是| E[HTTP/2] D -->|否| F[HTTP/1.1或HTTP/2] ``` 6. **兼容性与部署** - **WebSocket**:需处理防火墙/NAT穿透,代理支持不稳定。 - **HTTP/2**:基于TLS部署(h2),现代浏览器普遍支持,但中间设备干扰少。 性能对比公式: $$ \text{WebSocket传输延迟} = T_{\text{握手}} + \frac{\text{消息大小}}{\text{带宽}} $$ $$ \text{HTTP/2传输延迟} = T_{\text{多路复用调度}} + \sum_{i=1}^{n} \left( \frac{\text{Header}_i}{\text{压缩率}} + \frac{\text{Body}_i}{\text{带宽}} \right) $$ 典型场景建议: - **实时游戏/聊天**:WebSocket(低延迟推送) - **API网关/微服务**:HTTP/2(高效复用连接池) - **混合使用**:部分框架支持在HTTP/2连接上建立WebSocket(RFC 8441) 引用说明: [^1]: HTTP/2的Server Push功能可主动推送资源,但需客户端预先订阅,且不能用于业务数据推送。 [^2]: 生产环境中HTTP/2连接空闲超时通常设置为5-10分钟,而WebSocket连接可维持数小时。 §§相关问题§§ 1. WebSocket协议如何实现心跳机制? 2. HTTP/2的Server Push功能有哪些局限性? 3. 如何选择WebSocketHTTP/2用于实时数据推送? </think>### WebSocketHTTP/2 对比分析 #### 1. **协议本质差异** | **维度** | WebSocket | HTTP/2 | |-----------------|------------------------------------|---------------------------------| | **协议基础** | 独立的**全双工通信协议** | HTTP协议的**传输层优化** | | **建立方式** | 通过HTTP升级握手(状态码101) | 直接基于TLS/TCP建立连接 | | **设计目标** | **实时双向通信**(如聊天室、游戏) | **高性能Web传输**(多资源加载) | #### 2. **连接特性对比** | **特性** | WebSocket | HTTP/2 | |-------------------|------------------------------------|---------------------------------| | **连接持久性** | 单一长连接(小时/天级) | 可复用连接但默认较短(分钟级)[^1] | | **数据流向** | **双向实时传输**(客户端/服务端均可主动发消息) | **半双工**(客户端必须先发起请求) | | **头部开销** | 连接建立后**每帧仅6字节头部** | 依赖HPACK压缩,但仍需携带流ID | #### 3. **性能关键差异** ```mermaid graph LR A[通信需求] --> B{需要服务器主动推送数据?} B -->|是| C[选择WebSocket] B -->|否| D{高频请求低延迟?} D -->|是| E[选择HTTP/2] D -->|否| F[HTTP/1.1/HTTP/2均可] ``` - **延迟比较**: - WebSocket:消息直达,典型延迟 $ \leq 1ms $ - HTTP/2:需请求-响应周期,最小延迟 $ \approx RTT + \text{处理时间} $ - **吞吐量公式**: $$ \text{WebSocket吞吐量} = \frac{\text{消息数}}{\text{时间}} \times (1 - \text{协议开销}) $$ $$ \text{HTTP/2吞吐量} = \frac{\text{并发流数}}{\text{RTT}} \times \text{窗口大小} $$ #### 4. **适用场景** | **场景** | 推荐协议 | 原因 | |-------------------------|----------------|----------------------------------------------------------------------| | 实时聊天/多人协作 | **WebSocket** | 需服务器主动推送消息 | | 股票行情推送 | **WebSocket** | 高频小数据包,低延迟要求 | | 网页加载(JS/CSS/图片) | **HTTP/2** | 多资源并发下载,HPACK头部压缩优势显著 | | RESTful API通信 | **HTTP/2** | 请求-响应模式契合,连接复用降低开销[^2] | #### 5. **混合部署实践** - **HTTP/2隧道承载WebSocket**(RFC 8441): ```mermaid sequenceDiagram 客户端->>HTTP/2服务器: CONNECT请求(:protocol=websocket) 服务器-->>客户端: 返回200 OK 客户端->>服务器: WebSocket二进制帧(通过HTTP/2流传输) ``` 优势:复用现有HTTP/2连接,避免额外TCP握手。 #### 6. **局限性对比** | **限制类型** | WebSocket | HTTP/2 | |-------------------|------------------------------------|---------------------------------| | 代理兼容性 | 部分企业防火墙拦截 | 基于TLS部署兼容性好 | | 服务端推送 | 原生支持 | 仅能推送静态资源(不能推业务数据) | | 连接维护成本 | 需心跳保活(Ping/Pong帧) | 依赖Keep-Alive机制 | > 实验数据参考:在10KB/s消息频率下,WebSocketHTTP/2节省约35%的带宽[^1],但在首次加载网页时HTTP/2可提速400%[^2]。 ### 总结选择建议 - 选 **WebSocket** 当:需要**持续的双向数据流**(如在线游戏、实时监控)。 - 选 **HTTP/2** 当:**高性能传输资源**(如网页、API),尤其移动端高延迟环境。 - **混合使用**:主内容用HTTP/2加载,实时模块通过HTTP/2隧道跑WebSocket。 --- [^1]: WebSocket的轻量级帧结构减少传输开销 [^2]: HTTP/2多路复用显著提升页面加载速度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值