Enterprise UI
指南组件面试复习GitHub
开始
介绍快速开始主题定制Changeset 版本管理Turborepo + Changesets 发包方案
基础组件
Button 按钮Input 输入框Calendar 日历VirtualList 虚拟列表FileUploader 大文件上传Theme 全局换肤
SSE 实时行情与汇率推送(亮点难点与百问百答)useSSEQuotes Hook 说明SSE 重构汇率轮询 APIWebWorker 交易场景面试深挖指南百万级并发 WebSocket 前端系统WebSocket 面试全攻略
FCP 的优化LCP 的优化INP 的优化FPS 的优化Service Worker 面试题Service WorkerCPU 密集型与 IO 密集型任务preload / prefetch / async / defer
CI/CD 优化
I18N 技术总结Next.js SSR 国际化优化 P7Next.js SSR 国际化优化 P7 详细版国际化 I18N 面试版本本地启动拉最新 json清理 LRU 缓存方法SSR 国际化 - 翻译缺失检查脚本

Released under the MIT License.

Copyright © 2026 Enterprise UI

目录
  • WebSocket 面试全攻略(含核心用法+高频面试题+SSE对比·贴合你的项目场景)
  • 文档说明
  • 一、WebSocket 核心速记(面试开场一句话总结)
  • 二、WebSocket 核心用法(生产级·贴合你的项目)
  • 1. 核心基础API(面试必记)
  • 2. 生产级最小实现(你扫码登录/交易项目可直接复用)
  • 3. 你项目中的核心落地场景(面试可直接讲)
  • 4. 重点:WebSocket vs SSE 核心对比(你项目用了SSE,面试必问)
  • 三、面试高频问题+标准答案(直接背诵)
  • 基础概念类
  • 1. WebSocket和HTTP有什么关系和区别?
  • 2. WebSocket的握手过程是怎样的?
  • 3. WebSocket的readyState有哪几种状态?分别代表什么?
  • 生产实践类(资深岗重点考察)
  • 4. 怎么防止WebSocket连接假死?
  • 5. WebSocket断线了怎么办?怎么保证高可用?
  • 6. WebSocket怎么保证消息的顺序和可靠性?
  • 7. 海量用户同时在线,WebSocket服务端怎么优化?
  • 安全类(大厂必问)
  • 8. WebSocket有哪些安全风险?怎么防护?
  • 场景对比类
  • 9. WebSocket、HTTP长轮询、SSE怎么选型?
  • 10. 单页应用中,WebSocket在路由切换时怎么处理?
  • 四、面试专属话术模板(直接背)
  • 30秒精简版(快问快答)
  • 2分钟完整版(二面深挖·资深岗)

WebSocket 面试全攻略(含核心用法+高频面试题+SSE对比·贴合你的项目场景)

文档说明

本文档完全贴合你9年前端架构岗面试定位,结合你落地过的扫码登录、币安实时交易、DEX行情推送等项目场景,精简核心用法、重点强化面试高频考点,同时补充你项目中用到的SSE与WebSocket的核心对比,可直接背诵用于面试。


一、WebSocket 核心速记(面试开场一句话总结)

WebSocket是HTML5提供的全双工、持久化TCP通信协议,基于HTTP完成握手后,客户端与服务端可双向实时推送数据,无需客户端重复发起请求,彻底解决了HTTP轮询的延迟高、资源浪费问题,是实时交易、扫码登录、行情推送、实时通知等场景的工业级标准方案。


二、WebSocket 核心用法(生产级·贴合你的项目)

1. 核心基础API(面试必记)

API核心作用面试重点
new WebSocket(url)创建WebSocket连接生产环境必须用wss://(加密协议,基于HTTPS 443端口),开发环境用ws://
ws.onopen连接建立成功的回调连接成功后启动心跳保活、刷新断线消息队列
ws.onmessage接收服务端推送消息的回调统一处理消息分发、二进制数据解析
ws.send(data)向服务端发送消息支持字符串、ArrayBuffer、Blob,发送前必须校验连接状态
ws.onclose连接关闭的回调非正常关闭触发断线重连逻辑
ws.onerror连接错误的回调捕获异常,触发重连
ws.readyState当前连接状态4种状态:0=连接中、1=已连接、2=关闭中、3=已关闭,发送消息前必须判断状态为1

2. 生产级最小实现(你扫码登录/交易项目可直接复用)

class WebSocketClient {
  private ws: WebSocket | null = null;
  private readonly url: string;
  private reconnectCount = 0;
  private maxReconnect = 5; // 最大重连次数
  private reconnectDelay = 2000; // 重连延迟
  private heartbeatTimer: NodeJS.Timeout | null = null;
  private heartbeatInterval = 30000; // 30秒心跳
  private messageQueue: any[] = []; // 断线消息队列

  constructor(url: string) {
    this.url = url;
  }

  // 初始化连接
  connect() {
    try {
      this.ws = new WebSocket(this.url);
      this.bindEvents();
    } catch (err) {
      console.error('连接创建失败', err);
      this.reconnect();
    }
  }

  // 绑定核心事件
  private bindEvents() {
    if (!this.ws) return;

    // 连接建立成功
    this.ws.onopen = () => {
      console.log('WebSocket连接成功');
      this.reconnectCount = 0;
      this.startHeartbeat(); // 启动心跳
      this.flushQueue(); // 发送断线期间的消息
    };

    // 接收服务端消息
    this.ws.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        // 心跳响应
        if (data.type === 'pong') return;
        // 业务消息分发(如扫码状态、交易行情)
        this.handleMessage(data);
      } catch (err) {
        console.error('消息解析失败', err);
      }
    };

    // 连接关闭
    this.ws.onclose = (event) => {
      console.log('连接关闭', event.code, event.reason);
      this.stopHeartbeat();
      // 非正常关闭触发重连
      if (!event.wasClean) this.reconnect();
    };

    // 连接错误
    this.ws.onerror = (err) => {
      console.error('连接错误', err);
    };
  }

  // 发送消息(断线自动入队)
  send(data: any) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    } else {
      this.messageQueue.push(data);
    }
  }

  // 业务消息处理(适配你的项目场景)
  private handleMessage(data: any) {
    switch (data.type) {
      case 'qrcode_scanned':
        // 扫码登录-已扫码回调
        updateQRCodeStatus('scanned');
        break;
      case 'qrcode_confirmed':
        // 扫码登录-已确认回调
        loginWithTempToken(data.tempToken);
        break;
      case 'trade_ticker':
        // 交易行情推送
        updateTicker(data.data);
        break;
      default:
        break;
    }
  }

  // 心跳保活(防止连接假死,生产必备)
  private startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send(JSON.stringify({ type: 'ping' }));
      }
    }, this.heartbeatInterval);
  }

  private stopHeartbeat() {
    if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
  }

  // 断线重连(生产必备)
  private reconnect() {
    if (this.reconnectCount >= this.maxReconnect) {
      console.error('重连次数超限');
      alert('连接已断开,请刷新页面重试');
      return;
    }
    this.reconnectCount++;
    setTimeout(() => this.connect(), this.reconnectDelay * this.reconnectCount); // 延迟递增
  }

  // 刷新消息队列(连接成功后发送断线消息)
  private flushQueue() {
    while (this.messageQueue.length) {
      const msg = this.messageQueue.shift();
      this.send(msg);
    }
  }

  // 关闭连接
  close() {
    this.stopHeartbeat();
    this.ws?.close();
  }
}

// 项目中使用示例
// 1. 扫码登录场景
const qrcodeWs = new WebSocketClient('wss://api.your-domain.com/qrcode/ws?uuid=xxx');
qrcodeWs.connect();

// 2. 交易行情场景
const tickerWs = new WebSocketClient('wss://api.your-domain.com/trade/ticker');
tickerWs.connect();

3. 你项目中的核心落地场景(面试可直接讲)

  1. 扫码登录:服务端扫码状态变化后,毫秒级推送给PC端,替代轮询,无延迟、无资源浪费;
  2. 交易系统实时行情:币安/Crypto.com的K线数据、订单簿深度、成交记录实时推送,保证交易数据的毫秒级同步;
  3. DEX实时交易通知:订单成交、链上交易确认、资产变动实时推送;
  4. 系统实时公告/风控通知:全平台用户的紧急公告、风险预警实时推送。

4. 重点:WebSocket vs SSE 核心对比(你项目用了SSE,面试必问)

你项目中写了SSE,面试官一定会问「为什么用SSE不用WebSocket?」「两者有什么区别?」,下表直接背:

对比维度WebSocketSSE(Server-Sent Events)
通信模式全双工,客户端<->服务端双向通信单工,仅服务端向客户端单向推送
协议基础独立的TCP协议,基于HTTP握手升级纯HTTP协议,无需升级
数据格式支持字符串、二进制数据(图片/音频/流数据)仅支持UTF-8字符串
适用场景双向通信场景:实时聊天、扫码登录、在线协作、交易下单、游戏纯服务端推送场景:新闻推送、行情播报、日志实时输出、公告通知
断线重连需要手动实现心跳+重连逻辑浏览器原生支持自动断线重连,自带last-event-id实现断点续传
兼容性所有现代浏览器支持,IE10+所有现代浏览器支持,IE/Edge Legacy不支持(可通过polyfill兼容)
资源占用长连接常驻,双向通信无额外开销基于HTTP长连接,单向推送开销更低
防火墙穿透部分老旧企业防火墙会拦截WebSocket协议纯HTTP协议,无拦截问题

【面试专属回答】为什么你项目里用了SSE,而不是WebSocket?
我在项目中会根据业务场景做技术选型:

  1. 对于纯服务端单向推送的场景,比如系统公告、行情数据播报、日志实时输出,我会优先用SSE。因为它基于纯HTTP协议,无需处理双向通信的复杂度,浏览器原生支持自动重连和断点续传,开发和维护成本更低,开销也更小;
  2. 对于需要双向通信的场景,比如扫码登录、交易下单、在线协作,我会用WebSocket。因为它支持全双工通信,客户端可以实时向服务端发送消息,延迟更低,更适合双向交互的场景;
  3. 两者不是互斥的,我在币安的交易系统里,就是两者结合使用:行情推送用SSE,扫码登录、交易交互用WebSocket,最大化发挥两者的优势。

三、面试高频问题+标准答案(直接背诵)

基础概念类

1. WebSocket和HTTP有什么关系和区别?

精简版:WebSocket基于HTTP完成握手,握手成功后升级为TCP长连接,和HTTP再无关系;HTTP是单向通信,WebSocket是全双工双向通信。

完整版:

  1. 关联:WebSocket的连接建立依赖HTTP协议,客户端先发送一个带Upgrade: websocket头的HTTP请求,服务端同意后完成握手,连接升级为WebSocket协议,后续通信不再使用HTTP。
  2. 核心区别:
    • 通信模式:HTTP是单向通信,只能客户端发起请求,服务端被动响应;WebSocket是全双工通信,连接建立后双方可随时互相发送消息;
    • 连接状态:HTTP是无状态的短连接,每次请求都要重新建立TCP连接;WebSocket是持久化长连接,一次握手后连接一直保持,直到主动关闭;
    • 开销:HTTP每次请求都携带完整的请求头,冗余开销大;WebSocket连接建立后,数据传输仅需极小的帧头,开销极低;
    • 实时性:HTTP轮询有2-3秒延迟,WebSocket是毫秒级实时推送。

2. WebSocket的握手过程是怎样的?

  1. 客户端向服务端发送一个HTTP GET请求,携带核心请求头:
    • Upgrade: websocket:表示要升级为WebSocket协议;
    • Connection: Upgrade:表示要升级连接;
    • Sec-WebSocket-Key:随机生成的Base64字符串,用于服务端校验;
    • Sec-WebSocket-Version: 13:WebSocket协议版本。
  2. 服务端收到请求后,校验通过后返回HTTP 101 Switching Protocols响应,携带Sec-WebSocket-Accept头(由客户端的Key加密生成),表示同意升级协议。
  3. 握手完成,TCP连接保持,客户端和服务端开始双向传输WebSocket数据帧,后续通信不再使用HTTP。

3. WebSocket的readyState有哪几种状态?分别代表什么?

有4种核心状态,是面试必背的基础考点:

  1. 0 (CONNECTING):连接正在建立中,尚未完成握手;
  2. 1 (OPEN):连接已建立并打开,双方可以正常通信;
  3. 2 (CLOSING):连接正在关闭中,正在进行关闭握手;
  4. 3 (CLOSED):连接已关闭或连接建立失败,无法再通信。
    【面试加分】发送消息前必须判断readyState === OPEN,否则会抛出JS异常,这是生产环境的基础容错处理。

生产实践类(资深岗重点考察)

4. 怎么防止WebSocket连接假死?

这是生产环境必做的处理,也是面试高频考点,核心方案是心跳保活机制:

  1. 客户端心跳:连接建立成功后,客户端每30秒向服务端发送一个ping心跳包;
  2. 服务端响应:服务端收到ping后,立即回复一个pong包;
  3. 超时判断:如果客户端60秒内没有收到服务端的pong响应,判定连接已假死,主动关闭连接并触发断线重连;
  4. 服务端兜底:服务端如果90秒内没有收到客户端的任何消息,主动关闭连接,释放资源,避免无效连接占用服务器资源。
    【场景贴合】我在币安的交易系统和扫码登录功能中,都落地了这套心跳机制,彻底解决了路由器、防火墙长时间无数据传输自动断开连接的问题。

5. WebSocket断线了怎么办?怎么保证高可用?

我在生产环境落地了完整的断线重连+消息兜底方案,核心分为4步:

  1. 断线监听:监听onclose事件,通过event.wasClean判断是否为正常关闭,非正常关闭(网络波动、服务端重启)自动触发重连;
  2. 指数退避重连:设置最大重连次数(比如5次),重连延迟按2秒、4秒、8秒递增,避免频繁重连给服务端造成压力;
  3. 消息队列兜底:断线期间,用户发送的消息先存入本地内存队列,连接重新建立成功后,立即批量发送队列中的消息,防止消息丢失;
  4. 降级兜底:重连次数超限后,自动降级为HTTP轮询方案,保证核心业务(如扫码登录、行情推送)不中断,同时提示用户网络异常。

6. WebSocket怎么保证消息的顺序和可靠性?

这是交易系统场景的高频考点,核心分为3点:

  1. 协议层面保证顺序:WebSocket基于TCP协议,TCP本身就保证了数据包的顺序传输和可靠交付,不会出现乱序问题;
  2. 应用层消息确认:对于交易下单、扫码确认等关键业务,我会设计应用层ACK机制:客户端发送关键消息后,服务端必须返回ACK确认包,客户端超时未收到ACK则自动重发,同时给消息加唯一ID,避免服务端重复处理;
  3. 断线重传兜底:连接断开后,未收到ACK的消息会存入本地队列,重连成功后自动重发,保证关键消息不丢失。

7. 海量用户同时在线,WebSocket服务端怎么优化?

这是资深架构岗的考点,我在币安的千万级用户交易系统中,落地过对应的优化方案:

  1. 服务端集群化+负载均衡:用Nginx做四层负载均衡,将WebSocket连接均匀分发到多个服务节点,避免单节点压力过大;
  2. 连接池化管理:服务端对连接做池化管理,定期清理无效连接、假死连接,释放服务器资源;
  3. 消息广播优化:全平台公告等广播消息,用Redis发布订阅模式实现集群广播,避免单节点遍历所有连接的性能损耗;
  4. 协议优化:高频行情推送用二进制数据传输,减少数据体积,降低传输和解析开销;
  5. 内核参数优化:调整服务器TCP内核参数,提升最大连接数上限,优化长连接的保持时间。

安全类(大厂必问)

8. WebSocket有哪些安全风险?怎么防护?

这是字节、阿里等大厂必问的考点,核心风险和防护方案我在金融交易系统中都落地过,分为6点:

  1. 未授权访问风险:恶意用户非法连接WebSocket服务,推送/接收敏感数据。
    防护:连接建立后,客户端必须在5秒内发送Token完成身份认证,服务端校验Token无效直接断开连接;同时校验请求的Cookie/Session,保证和登录态一致。
  2. 跨域WebSocket劫持(CSWSH):恶意网站诱导用户访问,在用户不知情的情况下建立WebSocket连接,窃取敏感数据。
    防护:服务端严格校验请求的Origin头,只允许白名单内的可信域名建立连接,拒绝非法Origin的请求。
  3. 明文传输风险:ws://是明文传输,中间人可以窃听、篡改数据。
    防护:生产环境必须使用wss://加密协议,基于TLS/SSL加密,和HTTPS一致,防止中间人攻击。
  4. 消息注入/越权操作:恶意用户发送恶意消息,越权操作其他用户的数据。
    防护:服务端对每条消息都做权限校验,校验消息发送者的身份和操作权限,禁止越权操作;同时对消息内容做严格的格式校验和XSS过滤,防止注入攻击。
  5. DOS/DDOS攻击:恶意用户建立大量无效连接,耗尽服务器资源。
    防护:限制单个IP的最大连接数;限制单连接的消息发送频率,高频发送直接断开连接;设置连接认证超时,5秒内未完成认证直接断开。
  6. 数据泄露风险:WebSocket传输敏感数据,被窃取后造成泄露。
    防护:敏感数据即使在wss://下,也要做业务层加密;绝对禁止通过WebSocket传输用户密码、私钥等核心敏感信息。

场景对比类

9. WebSocket、HTTP长轮询、SSE怎么选型?

我会严格根据业务场景做选型,核心判断标准如下:

  1. 优先用WebSocket的场景:需要客户端和服务端双向实时通信,比如扫码登录、实时聊天、在线协作、交易下单、游戏,对实时性要求高,有双向交互需求;
  2. 优先用SSE的场景:仅需要服务端单向推送,无客户端上行需求,比如新闻公告、行情播报、日志实时输出,开发成本低,浏览器原生支持重连,纯HTTP协议无防火墙拦截问题;
  3. 仅用HTTP长轮询的场景:需要兼容极端老旧浏览器,或者企业防火墙严格拦截WebSocket/SSE,作为兜底方案,缺点是延迟高、资源开销大。

10. 单页应用中,WebSocket在路由切换时怎么处理?

这是React/Vue项目的高频考点,我在项目中的处理方案是:

  1. 全局复用连接:对于全应用通用的WebSocket连接(如公告通知、用户资产推送),我会把WebSocket实例放在全局状态管理(Redux/Zustand)中,路由切换时不关闭连接,全应用复用,避免重复建立连接的开销;
  2. 页面级连接随路由销毁:对于单页面专用的连接(如交易页行情、K线推送),我会在路由组件的useEffect/onMounted中建立连接,在组件卸载/路由离开时,主动关闭连接,释放资源,避免无效连接占用服务器资源;
  3. 路由切换状态保持:路由切换时,保留消息队列和重连状态,切换回来后无需重新初始化,保证用户体验的连贯性。

四、面试专属话术模板(直接背)

30秒精简版(快问快答)

WebSocket是全双工的持久化TCP通信协议,基于HTTP握手建立连接,支持客户端和服务端双向实时推送,相比HTTP轮询延迟更低、资源开销更小,我在扫码登录、币安实时交易行情推送等项目中都深度落地过,同时也会根据业务场景和SSE做选型搭配。

2分钟完整版(二面深挖·资深岗)

关于WebSocket,我从核心原理、生产落地、安全防护、业务选型四个维度来讲,这套方案也是我在币安和Crypto.com的交易系统中深度落地过的生产级方案。

首先,核心原理上,WebSocket基于HTTP完成握手,升级为TCP长连接后,实现全双工双向通信,彻底解决了HTTP轮询延迟高、资源浪费的问题,核心优势就是毫秒级实时性、极低的传输开销。

然后是生产落地,我在项目中封装了完整的WebSocket客户端,核心做了四个生产级处理:一是心跳保活机制,防止连接假死;二是指数退避的断线重连,保证高可用;三是本地消息队列,防止断线期间消息丢失;四是连接状态管理,适配SPA路由切换的场景。这套方案支撑了扫码登录、交易行情实时推送等核心业务,线上连接可用性达到99.99%。

安全方面,金融交易场景对安全要求极高,我落地了完整的防护方案:生产环境强制使用wss加密协议;服务端严格校验Origin白名单,防止跨域劫持;连接建立后必须做Token身份认证,未认证直接断开;限制单IP连接数和消息频率,防止DOS攻击;所有关键消息都做权限校验,防止越权操作。

最后是选型,我不会盲目用WebSocket,会根据业务场景做选型:双向通信的场景用WebSocket,纯服务端推送的场景用SSE,极端场景用轮询兜底。比如在交易系统中,行情推送用SSE,扫码登录、交易交互用WebSocket,最大化发挥两者的优势。