WebSocket详解

Websocket由来

WebSocket协议是08年诞生,11年成为国际标准,他出现的原因自然是因为以前的http请求不足以满足用户需求,HTTP请求的性能不够用,因为HTTP的协议上的限制,但基于 HTTP 的 Web 浏览器的使用环境已遍布全球,因此无法完全抛弃 HTTP

举一个例子,在Facebook等网站上,某一时刻有几百万人发布了内容,服务器上需要更新很多内容,还想要直接把内容反馈给客户端,HTTP协议就无法妥善的处理好这项任务。因为HTTP是单项通信,他想知道服务端有没有更新,就必须去发起请求确认,但如果服务端没有更新,那么这次请求就是徒劳的。

  1. ● ●●一条连接上只可发送一个请求。
  2. ● ●●请求只能从客户端开始。客户端不可以接收除响应以外的指令。
  3. ● ●●请求 / 响应首部未经压缩就发送。首部信息越多延迟越大。
  4. ● ●●发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
  5. ● ●●可任意选择数据压缩格式。非强制压缩发送。

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 的工作流程大致如下:

  1. 由于是建立在 HTTP 基础上的协议,借用了 HTTP 协议来完成一部分握手。因此连接的发起方仍是客户端,客户端(通常是浏览器)发起 WebSocket 连接请求,连接到服务器的 WebSocket 端点。这个过程称为"WebSocket 握手"。

  2. 握手成功后,客户端和服务器建立了一个持久的 TCP 连接。这个连接会一直保持打开状态,直到任意一方主动关闭它。之后通信时可以省略部分状态信息;

  3. 在这个连接上,双方可以随时发送和接收数据帧。WebSocket 协议定义了数据帧的格式,支持文本和二进制数据。而HTTP则需要进行文本编码和解码

  4. 与 HTTP 不同,WebSocket 连接是全双工的,双方可以同时发送和接收数据,没有请求-响应的限制。

  5. WebSocket 连接支持自定义子协议,客户端和服务器可以协商使用特定的子协议进行通信。

  6. WebSocket 还提供了心跳机制,用于检测连接是否中断,以及自动重连机制。

HTTP 协议的握手请求中,多了这么几个东西,意思是告诉服务器,我要用websocket协议

首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:用来验证对方是不是真的是 WebSocket 在回复。

最后, Sec-WebSocket-Version 是告诉服务器所使用的 WebSocket Draft (协议版本)

当服务器返回如下响应,表示已经接收请求,并成功建立websocket了然后, Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key 。 可以将 Sec-WebSocket-KeySec-WebSocket-Accept 之间的关系理解为一种"签名"的机制。用来证明双方连接的是websocket连接。

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

WebSocket 的主要优势包括:

  1. 实时双向通信:可以实现服务端主动向客户端推送数据。

  2. 较低的通信延迟:WebSocket 连接是持久的,不需要重复的握手过程。

  3. 更小的通信开销:WebSocket 协议头部较 HTTP 更小。

  4. 支持跨域通信:WebSocket 连接不受同源策略的限制。

我在学习websocket的时候遇到的一些疑惑以及解答

我们知道http发送请求报文的时候是要有多种协议进行封装自己,然后传输到很远的地方,中间要经过路由器、交换机等,最后服务端才能够接收到请求,并用相同的方式返回,那ws既然也是符合osi七层模型,同时它也需要传输的过程中经过路由器、交换机等,路由器和路由器之间又没有实质连接,ws是怎么在完成连接后的发送消息时,路由器们怎么确认每次发送的都是同一个人?也就是怎么保持长连接的?

答:

ws和http一样,在从客户端发出去的时候也是要经过多层协议封装的

  1. WebSocket 数据帧:

    • WebSocket 协议定义了一系列的数据帧格式,用于封装应用层的实际数据。

    • 这些数据帧包含了诸如消息类型、长度、负载数据等信息。

  2. TCP 报文段:

    • WebSocket 数据帧会被进一步封装到 TCP 报文段中进行传输。

    • TCP 报文段包含了源端口、目标端口、序号、确认号等信息。

  3. IP 数据报:

    • TCP 报文段会被再次封装到 IP 数据报中,加入源 IP 地址和目标 IP 地址等信息。
  4. 数据链路层帧:

    • IP 数据报最终会被封装到数据链路层的帧结构中,添加MAC地址等信息。

    • 这样数据就可以在物理网络中进行传输了。

当封装好之后交换机和路由器只需要关注前3层(数据链路层、网络层、传输层),根据目的地址信息完成数据包的转发。对于应用层的 WebSocket 数据帧,它们是无感知的。所以,中间的网络设备不需要实时检测 TCP 连接状态,也不需要理解 WebSocket 协议的细节。它们只需要按照常规的网络数据包转发机制工作即可。直到接收端接收到ws的信息,然后用ws的协议去解析它,然后获取数据,因为之前已经建立过ws连接,此时在客户端和服务端成功建立 WebSocket 连接之后,双方都会保存相关的 TCP 连接状态信息。

  1. 客户端保存状态信息:

    • 客户端会保存与服务端建立的 TCP 连接的各种状态信息,包括连接 ID、IP 地址、端口号等。

    • 这些信息有利于客户端后续通过这个现有连接发送和接收 WebSocket 数据帧。

  2. 服务端保存状态信息:

    • 服务端同样会保存与客户端建立的 TCP 连接的各种状态信息。

    • 这些信息有利于服务端识别客户端,并通过这个现有连接发送和接收 WebSocket 数据帧。

  3. 双向维护连接状态:

    • 客户端和服务端都需要维护 WebSocket 连接的状态信息,确保连接的持续和稳定。

    • 如果任何一方的连接状态丢失,都可能导致 WebSocket 通信失败。

  4. 心跳机制维护连接:

    • 为了防止 TCP 连接因长时间不活跃而被中间设备断开,WebSocket 协议会定期发送"心跳"消息。

    • 心跳消息有助于双方持续维护 TCP 连接的状态信息,保证 WebSocket 通信的可靠性。

而http因为它的无状态性,无法主动推送数据等无法实现ws的功能。

关于ws的全双工,它是建立在TCP的基础上的,TCP本就支持全双工通道,而且ws的数据帧格式支持双向传输,尽管HTTP也是建立在TCP协议上的,但是为什么http也是建立在TCP基础的,它为什么不能实现全双工功能?
  1. HTTP 的请求-响应模式:

    • HTTP 采用了经典的请求-响应模型,客户端发起请求,服务端返回响应。

    • 这种模式下,服务端只能被动地响应客户端的请求,无法主动向客户端推送数据。

  2. HTTP 的短连接特性:

    • HTTP 通常使用短暂的 TCP 连接,即一个请求-响应后就关闭连接。

    • 这种短连接模式下,无法保持长期的双向通信状态。

  3. HTTP 头部设计:

    • HTTP 的头部设计主要面向请求-响应模式,缺乏支持双向通信的字段。

    • 例如,HTTP 头部没有定义服务端主动推送数据的机制。

  4. HTTP 语义定位:

    • HTTP 最初是为了浏览网页而设计的,其语义定位在于文档传输,而非实时双向通信。

也就是http是被协议内容约束了。

为什么说ws发送数据比http要快?仅仅是因为它传输的是二进制数据吗?http也能够传输二进制数据,那么他快在哪里?
  1. 连接方式不同:

    • WebSocket 使用持久性的 TCP 连接,一旦建立连接就可以双向传输数据。
    • HTTP 是基于请求-响应模式的短连接,每次传输数据都需要重新建立连接。
  2. 报文头部开销减少:

    • WebSocket 的数据帧结构更加精简,只包含必要的元数据信息。
    • HTTP 的报文头部相对较大,需要在每次请求时都传输。!
  3. 数据传输模式不同:

    • WebSocket 采用"推"模式,服务器可以主动向客户端推送数据。
    • HTTP 是"拉"模式,客户端必须主动发起请求才能获取数据。
  4. 网络开销减少:

    • WebSocket 复用 TCP 连接,避免了 HTTP 中频繁的 TCP 三次握手过程。
    • 这减少了网络往返时延和连接建立的开销。
所以http还是比较笨重的。
相关推荐
Spring_java_gg11 分钟前
如何抵御 Linux 服务器黑客威胁和攻击
linux·服务器·网络·安全·web安全
方方怪1 小时前
与IP网络规划相关的知识点
服务器·网络·tcp/ip
weixin_442643422 小时前
推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案
服务器·网络·安全·filelink数据摆渡系统
阑梦清川3 小时前
JavaEE初阶---网络原理(五)---HTTP协议
网络·http·java-ee
半桶水专家3 小时前
用go实现创建WebSocket服务器
服务器·websocket·golang
阿尔帕兹3 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
FeelTouch Labs3 小时前
Netty实现WebSocket Server是否开启压缩深度分析
网络·websocket·网络协议
千天夜5 小时前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
长弓三石6 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
xianwu5436 小时前
反向代理模块
linux·开发语言·网络·git