从 WebSocket 到 SSE:更轻量的实时通信选择

更新日期: 2025-08-29阅读: 101标签: 通信

在实时 Web 应用开发中,WebSocket 一直被认为是“黄金标准”。无论是聊天软件、在线游戏,还是多人协作编辑工具,WebSocket 都能提供稳定高效的双向通信能力。

但在很多实际场景中,我们真的需要这么复杂的技术吗?

想一下这些常见的需求:

  • 一个实时数据大屏,用来展示最新的业务数据

  • 新闻网站需要向用户推送最新的头条消息

  • 后台系统在任务完成后给用户发送一条通知

这些情况有一个共同点:数据只需要从服务器发往客户端,不需要客户端向服务器发送信息。这时候如果还用 WebSocket,就像是为了寄一封信而专门修一条高速公路——虽然强大,但成本太高,也没必要。

这时候,一个更轻量的技术可以很好地解决问题:服务器发送事件(Server-Sent Events,简称 SSE)。它用更简单的方式实现了服务器向客户端的单向数据推送。


什么是 SSE?为什么它更轻量?

SSE 是一种基于 HTTP 的技术,允许服务器通过一个长连接持续向客户端发送数据。它的设计非常简洁,有以下几个优点:

基于 HTTP,无需额外协议

和 WebSocket 需要建立独立的 ws 或 wss 连接不同,SSE 直接使用普通的 HTTP 或 HTTPS 连接。这样做的好处很明显:

  • 不需要特别的服务器支持,任何能处理 HTTP 长连接的后端框架(比如 Node.js、Python、Java 等)都可以使用

  • 更容易通过防火墙和代理,因为它就是普通的 HTTP 流量

  • 协议开销小,消息是纯文本格式,简单易懂

客户端实现非常简单

前端,你不需要安装任何额外的库。浏览器自带的 EventSource api 就可以直接使用:

// 连接到服务器的事件流
const eventSource = new EventSource('/sse-endpoint');

// 接收服务器发来的消息
eventSource.onmessage = function(event) {
  console.log('收到消息:', event.data);
};

// 处理错误
eventSource.onerror = function(error) {
  console.error('连接出错:', error);
  // 浏览器会自动尝试重新连接
};

代码很简单,不需要自己处理重连逻辑,浏览器会自动管理连接状态。


SSE 和 WebSocket 的对比

特性SSEWebSocket
通信方向单向(服务器到客户端)双向
协议HTTP/HTTPS独立的 WebSocket 协议
连接管理自动重连需要手动实现
数据格式文本文本或二进制
适用场景通知、推送、数据展示聊天、游戏、实时协作

简单来说,如果需要双向通信,比如聊天室,就用 WebSocket。如果只需要接收服务器推送,比如新闻更新或状态通知,SSE 是更轻量、更简单的选择。


一个简单的实时时钟示例

下面用 Node.js 和 Express 框架实现一个简单的 SSE 应用,它会每秒向客户端发送当前时间。

后端代码 (server.js):

const express = require('express');
const app = express();

// 提供静态页面
app.use(express.static('public'));

// SSE 路由
app.get('/sse', (req, res) => {
  // 设置 SSE 需要的响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  // 每秒发送一次时间
  const timer = setInterval(() => {
    const timeString = new Date().toLocaleTimeString();
    // SSE 数据格式要求:data: 开头,结尾有两个换行
    res.write(`data: ${timeString}\n\n`);
  }, 1000);
  
  // 客户端断开连接时清理资源
  req.on('close', () => {
    clearInterval(timer);
    res.end();
  });
});

app.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});

前端代码 (public/index.html):

<!DOCTYPE html>
<html>
<head>
    <title>SSE 时钟示例</title>
</head>
<body>
    <h1>当前时间:<span id="time"></span></h1>
    
    <script>
        const timeElement = document.getElementById('time');
        // 创建 SSE 连接
        const eventSource = new EventSource('/sse');
        
        // 接收服务器发送的数据
        eventSource.onmessage = function(event) {
            timeElement.textContent = event.data;
        };
        
        // 处理错误
        eventSource.onerror = function() {
            timeElement.textContent = '连接出错';
        };
    </script>
</body>
</html>

这个例子展示了 SSE 的基本用法:服务器定期发送数据,客户端接收并更新页面。代码很简单,但实现了一个完整的实时功能。


总结:选择合适的技术

技术选型没有绝对的好坏,关键是找到适合具体场景的方案。WebSocket 功能强大,但复杂度也高。对于只需要服务器向客户端推送数据的场景,SSE 是更轻量、更简单的选择。

下次你需要实现实时功能时,可以先问自己:客户端需要向服务器发送数据吗?

如果不需要,那么 SSE 可能是更好的选择。它能减少开发工作量,降低系统复杂度,还能利用 HTTP 的现有基础设施,让你的应用更加高效稳定。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/12904

vue.js $emit/$on的用法和理解_vue组件之间数据传输通信

每个 Vue 实例都实现了事件接口vm.$emit( event, arg ) 触发当前实例上的事件;vm.$on( event, fn )监听event事件后运行。实例说明:Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信,Vuejs 用$emit与$on来进行跨页面之间的数据传输通信

两个浏览器窗口间通信总结

两个浏览器窗口间通信:一个窗口更新localStorage,另一个窗口监听window对象的storage事件来实现通信;所有的WebSocket都监听同一个服务器地址,利用send发送消息,利用onmessage获取消息的变化;借助iframe 或 window.open;HTML5 中的 Web Worker 可以分为两种不同线程类型

前端跨页面通信,你知道哪些方法?

在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个“独立”的运行环境,即使是全局对象也不会在多个Tab间共享。然而有些时候,我们希望能在这些“独立”的Tab页面之间同步页面的数据、信息或状态。

Vue组件之间通信的七种方式

使用Vue也有很长一段时间,但是一直以来都没对其组件之间的通信做一个总结,这次就借此总结一下。父子组件之间的通信props和$emit 父组件通过props将数据下发给props

浏览器标签页之间通信的实现

前端开发过程中,总是避免不了要进行前端标签页之间的通信,最经典的例子莫过于音乐播放网站中,当第一次点击播放列表中的歌曲时,它会打开一个新的标签页进行播放,而当在列表中再次点击歌曲播放时

基于 ThinkJS 的 WebSocket 通信详解

我们的项目是基于 ThinkJS + Vue 开发的,最近实现了一个多端实时同步数据的功能,所以想写一篇文章来介绍下如何在 ThinkJS 的项目中利用 WebSocket 实现多端的实时通信。ThinkJS 是基于 Koa 2 开发的企业级 Node.js 服务端框架

Socket是如何通信的?

其实服务器的处理和客户端大同小异,分三个逻辑分支:检索成功,用检索到的Socket来处理接收报文;检索失败,服务器侦听(listen)目的端口,创建全新的Socket服务客户;检索失败,服务器没有侦听目的端口,丢弃处理

vue中使用v-model完成组件间的通信

如何实现两个组件之间的双向传递呢?即,在父组件中修改了值,子组件会立即更新。在子组件中修改了值,父组件中立即更新。vue中有一个很神奇的东西叫v-model,它可以完成我们的需求。

vue父子组件通信高级用法

vue项目的一大亮点就是组件化。使用组件可以极大地提高项目中代码的复用率,减少代码量。但是使用组件最大的难点就是父子组件之间的通信。父组件通过$refs调用子组件的方法。 以上就是父子组件通信的方式

微服务的三种通信方法

在微服务架构的世界中,我们通过一系列服务构建应用。集合中的每项服务都符合以下标准:松散耦合、可维护和可测试、可以独立部署,微服务架构中的每个服务都解决了应用中的业务问题

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!