← 返回题目列表

长轮询是什么?它和普通轮询、SSE、WebSocket 有什么区别?

中等 第 24 / 26 题 更新于 2026/07/29
前端网络长轮询实时通信HTTP

简化版

长轮询是客户端发起请求后,服务端如果暂时没有新数据就先挂起连接,等有数据或超时再返回;客户端收到响应后立刻发起下一次请求。它比普通轮询更实时、更少空响应,但仍基于 HTTP 请求响应模型。相比 SSE,长轮询每次消息都要重新建请求;相比 WebSocket,它不是全双工,适合兼容性要求高、消息频率不太高的场景。

详细版

长轮询常用于旧浏览器兼容、简单通知和消息状态更新。

方案连接方式方向特点
普通轮询定时短请求客户端拉简单但延迟和浪费高
长轮询请求挂起等待客户端拉较实时,兼容好
SSE长连接服务端推单向推送
WebSocket长连接双向实时双向通信
async function longPoll() {
  while (true) {
    const res = await fetch('/api/messages/wait')
    const data = await res.json()
    handle(data)
  }
}

长轮询是“服务端先别急着回答”,不是 WebSocket 的替代品。

完整版教学

一、普通轮询的问题

普通轮询每隔几秒请求一次。如果没有新消息,服务端也要返回空结果。间隔短会浪费资源,间隔长又不够实时。

长轮询试图解决这个折中问题。

二、长轮询的工作流程

流程是:

  • 客户端发请求。
  • 服务端没有数据就暂时不返回。
  • 有数据或达到超时时间后返回。
  • 客户端收到后马上发起下一次请求。

这样只要有消息,服务端就能较快返回。

三、前端实现注意点

长轮询要处理错误、超时、取消和重连间隔。

let stopped = false

async function startLongPolling() {
  while (!stopped) {
    try {
      const res = await fetch('/api/wait', { signal })
      handle(await res.json())
    } catch (e) {
      await sleep(1000)
    }
  }
}

失败后不要立刻疯狂重连。

四、服务端压力

长轮询会让服务端保持大量挂起连接。服务端需要异步 IO、连接超时、队列管理和限流。

如果并发用户很多,长轮询对服务端连接资源有要求。

五、和 SSE 的区别

SSE 是服务端通过一个 HTTP 长连接持续推送文本事件。浏览器提供 EventSource 自动重连。

长轮询每次返回后要重新请求;SSE 则在同一个连接上持续发送。

六、和 WebSocket 的区别

WebSocket 是双向通信,适合聊天室、协作编辑、实时游戏等。长轮询仍是 HTTP 请求响应,只是响应延迟返回。

场景更适合
偶尔有通知长轮询或 SSE
服务端单向推送SSE
双向高频互动WebSocket
老环境兼容长轮询

七、常见误区与追问

  • 误区:长轮询就是把普通轮询间隔调长。 长轮询是服务端挂起请求等待数据,不是客户端少问几次。
  • 误区:长轮询没有服务端成本。 大量挂起连接会占资源,需要异步模型和限流。
  • 误区:长轮询能完全替代 WebSocket。 高频双向通信仍更适合 WebSocket。
  • 追问:长轮询失败后怎么办? 做退避重连,并在页面关闭或切路由时取消。
  • 追问:为什么要设置服务端超时? 避免连接无限挂起,也让客户端能维持循环。
  • 追问:长轮询适合移动端吗? 可用但要考虑电量、网络切换和后台限制。

八、加强记忆

长轮询记成“客户端问,服务端等有消息再答”。它比普通轮询少空转,比 SSE/WebSocket 更兼容,但实时性和连接成本要权衡。