LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【前端开发】WebSocket太笨重?试试SSE的轻量级魅力!

admin
2025年1月10日 15:34 本文热度 66

导读

这篇文章主要介绍了在项目中发现的频繁请求问题及解决方案。先指出轮询的缺点,对比 WebSocket 与 SSE 的优缺点,包括客户端实现、适用场景等。接着详细介绍 SSE 的工作原理、代码示例及改造效果,最后总结 SSE 有优势也有局限,选择数据通信策略应综合考虑项目需求等因素。

一、 前言

在查看代码以后发现这些频繁的请求是因为我们的项目首页有一个待办任务数量和消息提醒数量的展示,所以之前的同事使用了定时器,每隔十秒钟发送一次请求到后端接口拿数据,这也就是我们常说的轮询做法

1. 轮询的缺点

我们都知道轮询的缺点有几种:

资源浪费

  • 网络带宽:频繁的请求可能导致不必要的网络流量,增加带宽消耗。

  • 服务器负载:每次请求都需要服务器处理,即使是空返回,也会增加服务器的CPU和内存负载。

用户体验

  • 界面卡顿:频繁的请求和更新可能会造成用户界面的卡顿,影响用户体验。

2. websocket的缺点

那么有没有替代轮询的做法呢? 聪明的同学肯定会第一时间想到用websocket,但是在目前这个场景下我觉得使用websocket是显得有些笨重。我从以下这几方面对比:

  1. 客户端实现

    • WebSocket 客户端实现需要处理连接的建立、维护和关闭,以及可能的重连逻辑。

    • SSE 客户端实现相对简单,只需要处理接收数据和连接关闭。

  2. 适用场景

    • WebSocket 适用于需要双向通信的场景,如聊天应用、在线游戏等。

    • SSE 更适合单向数据推送的场景,如股票价格更新、新闻订阅等。

  3. 实现复杂性

    • WebSocket 是一种全双工通信协议,需要在客户端和服务器之间建立一个持久的连接,这涉及到更多的编程复杂性。

    • SSE 是单向通信协议,实现起来相对简单,只需要服务器向客户端推送数据。

  4. 浏览器支持

    • 尽管现代浏览器普遍支持 WebSocket,但 SSE 的支持更为广泛,包括一些较旧的浏览器版本。

  5. 服务器资源消耗

    • WebSocket 连接需要更多的服务器资源来维护,因为它们是全双工的,服务器需要监听来自客户端的消息。

    • SSE 连接通常是单向的,服务器只需要推送数据,减少了资源消耗。

二、 详细对比

对于这三者的详细区别,你可以参考下面我总结的表格:

以下是 WebSocket、轮询和 SSE 的对比表格:

特性WebSocket轮询PollingServer-Sent Events (SSE)
定义全双工通信协议,支持服务器和客户端之间的双向通信。客户端定期向服务器发送请求以检查更新。服务器向客户端推送数据的单向通信协议。
实时性高,服务器可以主动推送数据。低,依赖客户端定时请求。高,服务器可以主动推送数据。
开销相对较高,需要建立和维护持久连接。较低,但频繁请求可能导致高网络和服务器开销。相对较低,只需要一个HTTP连接,服务器推送数据。
浏览器支持现代浏览器支持,需要额外的库来支持旧浏览器。所有浏览器支持。现代浏览器支持良好,旧浏览器可能需要polyfill。
实现复杂性高,需要处理连接的建立、维护和关闭。低,只需定期发送请求。中等,只需要处理服务器推送的数据。
数据格式支持二进制和文本数据。通常为JSON或XML。仅支持文本数据,通常为JSON。
控制流客户端和服务器都可以控制消息发送。客户端控制请求发送频率。服务器完全控制数据推送。
安全性需要wss://(WebSocket Secure)来保证安全。需要https://来保证请求的安全。需要SSE通过HTTPS提供,以保证数据传输的安全。
适用场景需要双向交互的应用,如聊天室、实时游戏。适用于更新频率不高的场景,如轮询邮箱。适用于服务器到客户端的单向数据流,如股票价格更新。
跨域限制默认不支持跨域,需要服务器配置CORS。默认不支持跨域,需要服务器配置CORS。默认不支持跨域,需要服务器配置CORS。
重连机制客户端可以实现自动重连逻辑。需要客户端实现重连逻辑。客户端可以监听连接关闭并尝试重连。
服务器资源较高,因为需要维护持久连接。较低,但频繁的请求可能增加服务器负担。较低,只需要维护一个HTTP连接。

这个表格概括了 WebSocket、轮询和 SSE 在不同特性上的主要对比点。每种技术都有其适用的场景和限制,选择合适的技术需要根据具体的应用需求来决定。

三、 SSE(Server-Sent Events)介绍

我们先来简单了解一下什么是Server-Sent Events

Server-Sent Events (SSE) 是一种允许服务器主动向客户端浏览器推送数据的技术。它基于 HTTP 协议,但与传统的 HTTP 请求-响应模式不同,SSE 允许服务器在建立连接后,通过一个持久的连接不断地向客户端发送消息。

工作原理

  1. 建立连接

    • 客户端通过一个普通的 HTTP 请求订阅一个 SSE 端点。

    • 服务器响应这个请求,并保持连接打开,而不是像传统的 HTTP 响应那样关闭连接。

  2. 服务器推送消息

    • 一旦服务器端有新数据可以发送,它就会通过这个持久的连接向客户端发送一个事件。

    • 每个事件通常包含一个简单的文本数据流,遵循特定的格式。

  3. 客户端接收消息

    • 客户端监听服务器发送的事件,并在收到新数据时触发相应的处理程序。

  4. 连接管理

    • 如果连接由于任何原因中断,客户端可以自动尝试重新连接。

著名的计算机科学家林纳斯·托瓦兹(Linus Torvalds) 曾经说过:talk is cheap ,show me your code

我们直接上代码看看效果:

java代码

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;


@RestController

@RequestMapping("platform/todo")

public class TodoSseController {

    private final ExecutorService executor = Executors.newCachedThreadPool();

    @GetMapping("/endpoint")

    public SseEmitter refresh(HttpServletRequest request) {

        final SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);

        executor.execute(() -> {

            try {

                while (true) { // 无限循环发送事件,直到连接关闭

                   // 发送待办数量更新

                    emitter.send(SseEmitter.event().data(5));

                    // 等待5秒

                    TimeUnit.SECONDS.sleep(5);

                }

            } catch (IOException e) {

                emitter.completeWithError(e);

            } catch (InterruptedException e) {

                // 当前线程被中断,结束连接

                Thread.currentThread().interrupt();

                emitter.complete();

            }

        });

        return emitter;

    }

}

前端代码

beforeCreate() {

  const eventSource = new EventSource('/platform/todo/endpoint');

  eventSource.onmessage = (event) => {

    console.log("evebt:",event)

  };

  eventSource.onerror = (error) => {

    console.error('SSE error:', error);

    eventSource.close();

  };

  this.$once('hook:beforeDestroy', () => {

    if (eventSource) {

    eventSource.close();

  }

  });

},

改造后的效果

可以看到,客户端只发送了一次http请求,后续所有的返回结果都可以在event.data里面获取,先不谈性能,对于有强迫症的同学是不是一个很大改善呢?

总结

虽然 SSE(Server-Sent Events)因其简单性和实时性在某些场景下提供了显著的优势,比如在需要服务器向客户端单向推送数据时,它能够以较低的开销维持一个轻量级的连接,但 SSE 也存在一些局限性。例如,它不支持二进制数据传输,这对于需要传输图像、视频或复杂数据结构的应用来说可能是一个限制。此外,SSE 只支持文本格式的数据流,这可能限制了其在某些数据传输场景下的应用。还有,SSE 的兼容性虽然在现代浏览器中较好,但在一些旧版浏览器中可能需要额外的 polyfill 或者降级方案。

考虑到这些优缺点,我们在选择数据通信策略时,应该基于项目的具体需求和上下文来做出决策。如果项目需要双向通信或者传输二进制数据,WebSocket 可能是更合适的选择。

如果项目的数据更新频率不高,或者只需要客户端偶尔查询服务器状态,传统的轮询可能就足够了。

而对于需要服务器频繁更新客户端数据的场景,SSE 提供了一种高效的解决方案。

总之,选择最合适的技术堆栈需要综合考虑项目的需求、资源限制、用户体验和未来的可维护性。


作者:秋天的一阵风
链接:https://juejin.cn/post/7451991754561880115
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

该文章在 2025/1/10 15:34:56 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved