理解 WebSocket 协议

111 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情




WebSocket 是基于单个 TCP 的双向计算机通信协议。

你可以在简单的谷歌、百度搜索中找到许多类似的定义,但是我想通过一些简单和明显的例子来说明这这些。

什么是 WebSocket ?

作为 HTML5 计划的一部分,开发的 WebSocket 规范引入了 WebSocket JavaScript 接口,该接口定义了一个全双工单套接字连接,通过该连接可以在客户端和服务器之间发送消息。

WebSocket 标准简化了双向 Web 通信和连接管理的大部分复杂性。

CometAjax 相比,WebSocket 代表了 Web 通信的下一个进化步骤。当然每种技术都有其独特的功能。

WebSocketws://wss:// 开始。它是一个有状态的协议,这意味着客户端和服务器之间的连接将保持活动状态,直到它被任何一方(客户端或服务器)终止。客户端和服务器中的任何一个关闭连接后,连接都会从两端终止。 

让我们举一个客户端与服务器通信的例子,客户端是一个网络浏览器,每当我们启动客户端和服务器之间的连接时,客户端与服务器进行握手并决定创建一个新的连接和这个连接将保持活动状态,直到被其中任何一个终止。当连接建立并处于活动状态时,通信将使用相同的连接通道进行,直到终止。

以下就是 WebSocket 连接所涉及的步骤。

  1. 客户端(浏览器)向服务器发送 HTTP 请求。
  2. 通过 HTTP 协议建立连接。
  3. 如果服务器支持 WebSocket 协议,则同意升级连接。(握手)
  4. 现在握手已经完成,初始 HTTP 连接被使用相同底层 TCP/IP 协议的 WebSocket 连接替换。
  5. 此时,数据可以在 ClientServer 之间自由来回流动。


WebSocket 应用场景?

首先,在不使用 WebSocket 的情况下访问网站。 网页通常通过 HTTP 连接在 Internet 上传输。为此客户端会为您执行的每个操作向服务器发出请求。使用 HTTP 访问网站时,客户端必须先向服务器提交请求。然后服务器通过发送请求的连接来响应。换句话说,HTTP 在基本的请求和响应架构上运行,会导致大量延迟。

我举一个实在点的例子:

我们平时点外卖

0秒:食物到了吗?(客户)
0秒:正在配送。(外卖小哥) 1秒:食物到了吗?(客户)
1秒:正在配送。(外卖小哥)
2秒:食物到了吗?(客户)
2秒:正在配送。(外卖小哥)
3秒:食物到了吗?(客户)
3秒:是的,先生,这是您的外卖。(外卖小哥)

这就是我们常见的所说的 HTTP 轮询

客户端向服务器重复请求并检查是否有任何消息要接收。

如您所见,这不是很有效。我们正在使用不必要的资源,失败的请求数量也很麻烦。

有没有办法克服这个问题?

是的,有一种轮询技术可以用来克服这个缺陷,它被称为 长轮询。即:长轮询基本上涉及向服务器发出 HTTP 请求,然后保持连接打开以允许服务器稍后响应(由服务器确定)。

长轮询版本:

0秒:食物到了吗?(客户)
3秒:是的,先生,这是您的外卖。(外卖小哥)

尽管长轮询有效,但它在 CPU、内存和带宽方面消耗的非常高(因为我们在保持连接打开时阻塞了资源)。

那么我们的救星就是:WebSocket

WebSocket 协议的情况有所不同,可以使用动态调用方法实时调用。客户端所要做的就是通过传输 WebSocket 协议的握手来与服务器建立连接。这种握手提供了数据传输所需的所有识别信息。

客户端(Web 浏览器)初始化连接,并定期发送“心跳”以告诉服务器连接始终处于活动状态,一旦建立连接,客户端和服务器(与 http 规范相反)可以向对方发送信息(也称为服务器推送)。

这也与客户端驱动的 xmlhttprequest (ajax) 不同:客户端询问服务器它的状态是否是最新的,如果不是则更新,握手后通道保持打开状态,以实现近乎恒定的通信。

这意味着服务器可以自行传递数据,而无需客户端请求。因此,如果服务器接收到新数据,它会将其传递给客户端,而无需客户端发出特殊请求。

是不是特别好?所以应用场景也就很明显了

  • 聊天程序
  • 社交平台
  • 网络游戏
  • .... 所有凡是需要客户端与服务端实时通信的场景都可以使用


代码中的 WebSocket

对于 WebSocket 代码的实现,我们只需要 (编程语言或者框架名 + WebSocket) 关键词搜索引擎检索一下 就可以实现

以下为不完整统计!仅供参考~

WebSocket 目前支持以下浏览器:

  • Internet Explorer:版本 10 或更高版本
  • Firefox:版本 6 或更高版本
  • Chrome:版本 14 或更高版本
  • Opera:版本 12.10 或更高版本
  • Safari:版本 6 或更高版本

在服务器端,WebSocket 可以与以下编程语言和框架一起使用:

  • Node.js
    • Socket.IO
    • WebSocket-Node
    • ws
  • Java
    • Jetty
  • Python
    • pyWebSocket
    • Tornado
  • C++
    • Libwebsockets