Skip to content
导航栏

WebSocket 常见面试题

WebSocket 是一种在单个 TCP 连接上进行全双工通信应用层网络传输协议。

WebSocket 的特点

  • 全双工通信:允许服务端主动向客户端推送数据,使得客户端和服务器之间的数据交换变得更加简单。
  • 建立链接:一次握手,两者之间就直接可以创建持久性的连接。
  • 与 HTTP 协议有着良好的兼容性:默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  • 开销:数据格式比较轻量,性能开销小,通信高效。
  • 传输数据:可以发送文本,也可以发送二进制数据。
  • 没有同源限制:客户端可以与任意服务器通信。
  • 协议标识符是 ws(如果加密,则为 wss),服务器网址就是 URL。

为什么需要 WebSocket

因为 HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力。

举例来说,我们想了解查询今天的实时数据,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

这种 单向请求 的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

造成的问题:

  • 轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。
  • 服务端被迫维持来自每个客户端的大量不同的连接。
  • 大量的轮询请求会造成高开销,比如会带上多余的 header,造成了无用的数据传输。

WebSocket 协议由此而生,并且在 HTML5 标准中增加了有关 WebSocket 协议的相关 api,所以只要实现了 HTML5 标准的客户端,就可以与支持 WebSocket 协议的服务器进行全双工的持久通信了。

WebSocket 连接的过程

1、客户端发起 HTTP 请求,经过 3 次握手后,建立起 TCP 连接;HTTP 请求里存放 WebSocket 支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version 等。

2、服务器收到客户端的握手请求后,同样采用 HTTP 协议回馈数据;

3、客户端收到连接成功的消息后,开始借助于 TCP 传输信道进行全双工通信。

websocket 如何解决断线问题?

websocket 超时没有消息自动断开连接

这时候我们就需要知道服务端设置的超时时长是多少,在小于超时时间内发送心跳包。

心跳检测步骤:

  1. 客户端每隔一个时间间隔发生一个探测包给服务器

  2. 客户端发包时启动一个超时定时器

  3. 服务器端接收到检测包,应该回应一个包

  4. 如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器

  5. 如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了

websocket 服务端或客户端异常中断

客户端需要断开连接,通过 onclose 关闭连接。

服务端再次上线时则需要清除之间存的数据,若不清除 则会造成只要请求到服务端的都会被视为离线。

处理重连:引入 reconnecting-websocket.min.js,ws 建立链接方法使用 js 库 api 方法:

断网监测:使用 js 库:offline.min.js

websocket 和 HTTP 有哪些不同

相同点: 都是一样基于 TCP 的,都是可靠性传输协议。都是应用层协议。

联系: WebSocket 在建立握手时,数据是通过 HTTP 传输的。但是建立之后,在真正传输时候是不需要 HTTP 协议的。

区别

  1. WebSocket 是双向通信协议,模拟 Socket 协议,可以双向发送或接受信息,而 HTTP 是单向的。

  2. WebSocket 是需要浏览器和服务器握手进行建立连接的,而 HTTP 是浏览器发起向服务器的连接。

  3. 虽然 HTTP/2 也具备服务器推送功能,但 HTTP/2 只能推送静态资源,无法推送指定的信息。

Websocket 的优缺点

优点:

  • WebSocket 协议一旦建立后,互相沟通所消耗的请求头是很小的
  • 服务器可以向客户端推送消息了

缺点:

少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)

WebSocket 的应用场景

如果我们需要通过网络传输的任何实时更新或连续数据流,则可以使用 WebSocket。如果我们要获取旧数据,或者只想获取一次数据供应用程序使用,则应该使用 HTTP 协议,不需要很频繁或仅获取一次的数据可以通过简单的 HTTP 请求查询,因此在这种情况下最好不要使用 WebSocket。

常见的应用场景:

  • 即时聊天通信
  • 多玩家游戏
  • 文档在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 实时地图位置
  • 等等需要信息即时推送的 web 应用程序