欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 相比于WebSocket,SSE更适合轻量级

相比于WebSocket,SSE更适合轻量级

2025/2/21 3:12:51 来源:https://blog.csdn.net/Esther_liew/article/details/145685737  浏览:    关键词:相比于WebSocket,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 提供了一种高效的解决方案。

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词