第185题:http header 怎么判断协议是不是 Websocket?

发布于 2022-08-06 20:39:09 字数 120 浏览 145 评论 2

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 通信协议于 2011 年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。WebSocket API 也被 W3C 定为标准。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如果没有你 2022-05-04 13:19:40

引言

首先,解答本题, http 通过判断 header 中是否包含 Connection: UpgradeUpgrade: websocket 来判断当前协议是否要升级到 websocket ,下面我们了解一下 WebSocket 协议与由来

WebSocket 由来

WebSocket 之前,如果需要在客户端和服务之间双向通信,需要通过 HTTP 轮询来实现, HTTP 轮询分为轮询与长轮询:

其中,轮询是指浏览器通过 JavaScript 启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息,缺点:

  • 实时性不够
  • 频繁的请求会给服务器带来极大的压力

长轮询是指浏览器发送一个请求时,服务器先拖一段时间,等到有消息了再回复。这个机制暂时地解决了实时性问题,但是它带来了新的问题:

  • 以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源
  • 一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的

因此,HTML5 新增了 WebSocket 协议,能够在浏览器和服务器之间建立一个不受限的双向通信的通道。

为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?
实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。

WebSocket 的优点:

  • 较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小
  • 更强的实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据
  • 保持连接状态:与 HTTP 不同的是,WebSocket 需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息
  • 更好的二进制支持:WebSocket 定义了二进制帧,相对 HTTP,可以更轻松地处理二进制内容
  • 可以支持扩展:WebSocket 定义了扩展,用户可以扩展协议、实现部分自定义的子协议

WebSocket 协议

WebSocket 使用 wswss 的统一资源标志符(URI),其中 wss 表示使用了 TLS 的 WebSocket。

ws:// 数据不是加密的,对于任何中间人来说其数据都是可见的。

wss:// 是基于 TLS 的 WebSocket,类似于 HTTPS 是基于 TLS 的 HTTP),传输安全层在发送方对数据进行了加密,在接收方进行解密

http 通过判断 header 中是否包含 Connection: UpgradeUpgrade: websocket 来判断当前是否需要升级到 websocket 协议,除此之外,还有其它 header:

  • Sec-WebSocket-Key :浏览器随机生成的安全密钥
  • Sec-WebSocket-Version :WebSocket 协议版本
  • Sec-WebSocket-Extensions :用于协商本次连接要使用的 WebSocket 扩展
  • Sec-WebSocket-Protocol :协议

当服务器同意进行 WebSocket 连接时,返回响应码 101

测试地址:https://www.websocket.org/echo.html

一旦 socket 被建立,我们就应该监听 socket 上的事件。一共有 4 个事件:

  • open :连接已建立
  • message :接收到数据
  • error :WebSocket 错误
  • close :连接已关闭

如果我们想发送消息,可以使用 socket.send(data)

let socket = new WebSocket("wss://echo.websocket.org")

socket.onopen = function(e) {
  console.log("[open] Connection established")
  // 发送消息
  socket.send("My name is an")
}

socket.onmessage = function(event) {
  console.log(`[message] Data received from server: ${event.data}`)
}

socket.onclose = function(event) {
  // ...
}

socket.onerror = function(error) {
  console.log(`[error] ${error.message}`)
}

总结

WebSocket 使用 wswss 的统一资源标志符,通过判断 header 中是否包含 Connection: UpgradeUpgrade: websocket 来判断当前是否需要升级到 websocket 协议,除此之外,它还包含 Sec-WebSocket-KeySec-WebSocket-Version 等header,当服务器同意 WebSocket 连接时,返回响应码 101 ,它的 API 很简单。

方法:

  • socket.send(data)
  • socket.close([code], [reason])

事件:

  • open
  • message
  • error
  • close

原文

假装爱人 2022-05-03 23:29:39

看下request header有没有
Upgrade: websocket

同时,服务端返回101状态码表示升级成功。Status Code: 101 Web Socket Protocol Handshake

websocket.org上面可以测试发送ws连接
https://www.websocket.org/echo.html

~没有更多了~

关于作者

追风人

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文