什么是SSE(服务器发送事件)?如何将 SSE 与 Spring 集成

实时通信已成为现代网络应用程序的一个重要方面,它使开发人员能够向用户提供动态更新和交互式体验。服务器发送事件(SSE)是促进实时通信的一项强大技术。它因其简单、易用以及与各种网络浏览器和平台兼容而广受欢迎。

在本文中,我们将深入探讨 SSE 及其与 Spring Framework 的集成,以及 SSE 如何增强 Spring 应用程序的通信能力,实现向客户端交付实时更新。通过在 Spring 中利用 SSE 的强大功能,开发人员可以创建反应灵敏的交互式网络应用程序,让用户始终参与其中并了解最新信息。

什么是 SSE(服务器发送事件)?

服务器发送事件(SSE)是一种网络技术,能让服务器通过单个长期 HTTP 连接向客户端发送实时更新或事件。与 WebSocket 等其他实时通信协议相比,它是一种简单高效的替代方案。

与客户端发起通信的传统 HTTP 请求不同,SSE 允许服务器发起通信,并在发生新事件或更新时向客户端推送数据。这种基于推送的模式消除了客户端反复轮询服务器更新的需要,从而减少了网络开销,提高了效率。

什么是SSE(服务器发送事件)?如何将 SSE 与 Spring 集成

SSE 依赖于客户端的 EventSource API,它提供了一种处理传入事件的便捷方法。服务器以一种称为 “文本/事件流 “的特定格式向客户端发送数据。每个事件由包含有效载荷的数据字段以及可选的事件和 ID 字段组成。

SSE 受大多数现代Web浏览器的支持,可以轻松集成到基于各种平台和框架构建的网络应用程序中。在 Spring Framework 的背景下,SSE 可以无缝集成,实现实时通信并向客户端推送更新,是需要实时数据同步、通知或实时馈送的应用程序的绝佳选择。

SSE 的局限性

虽然服务器发送事件(SSE)为实时通信提供了一种高效、直接的方法,但它也有一些需要考虑的局限性:

  • 单向通信: SSE 仅支持服务器到客户端的通信。客户端无法通过 SSE 连接发送数据或与服务器交互。如果需要双向通信,应考虑使用 WebSocket 等替代技术。
  • 缺乏二进制数据支持: SSE 主要用于发送文本数据。它本身不支持二进制数据的传输。如果需要传输二进制信息,则需要先将其编码为文本格式(如 Base64),然后再通过 SSE 发送。
  • 浏览器受限: 虽然大多数现代网络浏览器都支持 SSE,但仍有一些较旧的浏览器或特殊平台不具备 SSE 功能。在决定使用 SSE 时,必须考虑目标受众和浏览器兼容性要求。
  • 连接限制: SSE 的最大打开连接数有限制,尤其是在打开多个标签页时,这可能会让人很痛苦,因为该限制是针对每个浏览器的,而且设置得很低(6)。这个限制是针对每个浏览器+域的,这意味着你可以在 www.example1.com 的所有标签页中打开 6 个 SSE 连接,并使用 HTTP/2 打开另外 6 个 SSE 连接到 www.example2.com.When,服务器和客户端之间会协商最大同时 HTTP 流的数量(默认为 100)。

SSE 与 Spring MVC- Spring Boot 集成

1. 配置依赖关系: 在项目中加入所需的依赖项。为支持 SSE,您需要使用 spring-web 模块,该模块通常是 Spring Web MVC 框架的一部分。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. 创建 SSE 控制器:在 Spring 中,你可以创建一个专门用于处理 SSE 请求的控制器。用 @RestController 或 @Controller 以及适当的请求映射注解(@RequestMapping、@GetMapping 等)来注解控制器类。

3. 实现 SSE 端点: 在 SSE 控制器中,定义一个方法作为 SSE 端点。用 @GetMapping 或相应的映射注解来注解该方法,并从该方法返回一个 SseEmitter 对象。

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/sse")
public class SseController {

  private final SseService sseService;

  @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  public SseEmitter subscribeToSseEvents() {
    return this.sseService.subscribe();
  }

}

4. 存储发射器,以便以后在代码中需要的地方发送应用程序产生的不同事件。

private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();

@Override
public SseEmitter subscribe() {
  final SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
  this.emitters.add(emitter);

  emitter.onCompletion(() -> this.emitters.remove(emitter));

  return emitter;
}

在 SseEmitter 类的构造函数中指定的值是以毫秒为单位的超时时间,通常它的默认值很短,在示例中我们设置了 Long.MAX_VALUE 值,以设置剩余时间的最大值,但您可以根据应用程序的需要调整该值。

文档指出 : 默认情况下未设置,在这种情况下使用 MVC Java 配置或 MVC 命名空间中配置的默认值,如果未设置,则超时时间取决于底层服务器的默认值。

5. 最后,我们只需要在向客户端发送信息的用例中触发事件。为此,我在我们的 SseService .NET 中定义了一个方法:

public void sendEvent(final String message) {

  this.emitters.forEach(emitter -> {
    try {
      emitter.send(SseEmitter.event()
          .name("event-test")
          .data(SseMessage.builder()
              .description(message)
              .build()));
    } catch (final Exception e) {
      emitter.complete();
    }
  });

在这里,我们只需在先前存储的订阅者列表中滚动,然后发送相应的事件。事件的 “name “字段表示事件的名称(我们可以自定义该名称,以便在客户端以个性化的方式捕获该名称,否则默认值为 “message”),”data “字段是事件的正文,这里我们可以发送一个 Java 对象,因此我们可以发送与每个事件相关的信息。(在我的例子中,我只发送纯文本字符串)。

SSE 与 JavasScript 集成

要将服务器发送事件 (SSE) 与 JavaScript 集成,可以按照以下步骤操作:

1. 创建 EventSource 对象: 将 SSE 端点 URL 作为参数,在 JavaScript 代码中实例化一个新的 EventSource 对象。例如:

const eventSource = new EventSource('http://localhost:8080/api/v1/sse/stream');

2. 注册事件监听器:附加事件监听器来处理不同类型的SSE事件。该EventSource对象支持三个主要事件:openmessageerror。例如:

eventSource.addEventListener('open', () => {
  // Connection is established
});

eventSource.addEventListener('event-test', (event) => {
  // Handle SSE event data
  const eventData = JSON.parse(event.data);
  console.log(eventData);
  // Process and use the received data
});

eventSource.addEventListener('error', () => {
  // Handle SSE connection errors
});

3. 接收 SSE 事件: 当服务器发送 SSE 事件时,将触发事件-事件监听器(这是我在 Spring Integration 中指定的事件名称,但默认为 “消息”)。使用 event.data 访问事件数据,并对接收到的数据执行所需的操作。您可以更新用户界面、触发特定函数或以任何方式处理数据。

4. 关闭连接: 完成 SSE 操作后,确保关闭连接以释放资源。您可以使用 EventSource 对象的 close() 方法关闭 SSE 连接:

eventSource.close();

按照以上步骤,您就可以将 SSE 与 JavaScript 集成,并从服务器接收实时更新。记住要处理任何必要的错误情况,在不再需要时清理 SSE 连接,并确保服务器端的 SSE 端点配置正确,以便向连接的客户端发送 SSE 事件。

小结

服务器发送事件(SSE)为服务器和客户端之间的实时通信提供了一种简单高效的方法。有了 SSE,服务器就可以通过单个长期 HTTP 连接向客户端推送数据更新,从而消除了持续轮询的需要。

将 SSE 与 Spring 集成后,开发人员就能增强其应用程序的实时通信能力。通过配置 SSE 端点、发布 SSE 事件以及利用客户端的 EventSource API,开发人员可以实现无缝的实时更新、通知和数据同步。

在 JavaScript(如 React 应用程序)中使用 SSE 时,创建 EventSource 对象、注册事件监听器和处理 SSE 事件变得简单易行。接收到的 SSE 数据可在应用程序中进行处理和利用,以更新用户界面或触发特定操作。

虽然 SSE 有一些局限性,如单向通信和有限的浏览器支持,但它仍然是以简单、兼容的方式提供实时更新的强大工具。

通过将 SSE 的功能与 Spring 等框架和 React 等 JavaScript 库结合使用,开发人员可以构建交互式响应应用程序,为用户提供实时体验。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论