GPT 的流式交互,Spring 可以实现吗?

开发
这篇文章,我们分析了如何使用 SseEmitter 实现客户端和服务器的流式交互。

先看一张和 GPT交互的图片,让 GPT 写一篇200字的诗歌赞美 Java:

那么问题来了,我们是否也可以轻松地实现这种流式交互?

但是是必须的,这篇文章我们就来聊一聊主角:Spring SseEmitter。

1. 什么是 SSE?

SseEmitter 是 Spring MVC 中用于实现服务器发送事件(Server-Sent Events, 简称 SSE)的一个类,它是一种基于 HTTP 协议的标准,用于服务器向客户端单向推送事件。

SSE 允许服务器通过单向通道向客户端持续推送数据,适用于需要实时更新的应用场景,如实时通知、消息推送、动态数据展示等。SseEmitter 的工作原理主要涉及以下几个方面:

SSE 的特点:

  • 单向通信:仅服务器可以主动发送数据到客户端。
  • 持久连接:使用持久的 HTTP 连接,服务器可以持续发送事件。
  • 自动重连:浏览器在连接断开后会自动尝试重连。
  • 基于文本:传输的数据格式为纯文本,通常为 UTF-8 编码。

2. SseEmitter如何实现?

使用 SseEmitter 实现像 GPT一样的流式交互,其实还是比较简单的,在控制器中创建 SseEmitter 并返回,示例代码如下:

@RestController
publicclass SseController {

    @GetMapping("/sse")
    public SseEmitter streamSseMvc() {
        SseEmitter emitter = new SseEmitter();
        // 异步处理发送事件
        Executors.newSingleThreadExecutor().execute(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    emitter.send("Message " + i);
                    Thread.sleep(1000);
                }
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }
}

主要方法:

  • send(Object object):发送事件数据给客户端。
  • complete():关闭连接。
  • completeWithError(Throwable ex):在发生错误时关闭连接并发送错误信息。

效果如下图:

3. 工作流程

(1) 客户端请求 SSE 端点

客户端通过 EventSource API 或其他方式向服务器的 SSE 端点发送 HTTP GET 请求。例如:

const eventSource = new EventSource('/sse');

eventSource.onmessage = function(event) {
    console.log('Received event:', event.data);
};

eventSource.onerror = function(err) {
    console.error('EventSource failed:', err);
};

(2) 服务器端建立 SseEmitter

当服务器接收到 SSE 请求时,控制器方法会创建一个 SseEmitter 实例并返回。这会触发 Spring MVC 将响应头设置为 Content-Type: text/event-stream,以维持持久连接。

(3) 服务器端发送事件

通过 SseEmitter.send() 方法,服务器可以向客户端发送事件数据。通常,这些操作会在异步线程中进行,以避免阻塞主线程。

(4) 持久连接和生命周期管理

SseEmitter 管理着 SSE 连接的生命周期,包括处理超时、连接断开和错误等情况。可以通过配置超时时间来控制连接的最长持续时间:

SseEmitter emitter = new SseEmitter(30_000L); // 30秒超时

如果连接在指定时间内未关闭,SseEmitter 会自动触发超时处理。

(5) 客户端接收事件

客户端通过 EventSource 接收并处理服务器发送的事件。当服务器调用 emitter.complete() 或连接因超时等原因关闭时,客户端的 onclose 事件会被触发。

4. 错误处理与重试机制

  • 服务器端:在发送事件过程中,如果发生异常,可以调用 emitter.completeWithError(e) 来通知客户端错误并关闭连接。
  • 客户端端:客户端的 EventSource 会自动尝试重新连接,当连接断开时,会触发 onerror 事件。可以在客户端代码中实现更复杂的重试逻辑,例如增加重试次数限制或延迟策略。

5. 适用场景与限制

(1) 适用场景

  • 实时通知,如聊天应用、社交媒体动态更新。
  • 实时监控,如服务器状态监控、数据仪表盘。
  • 需要频繁推送更新但数据量不大的场景。

(2) 限制

  • 仅支持服务器到客户端的单向通信。
  • 需要浏览器支持 SSE 协议(大多数现代浏览器支持,但部分老旧浏览器可能不兼容)。
  • 对于需要高频率、大数据量的实时通信,WebSocket 可能更为合适。

6. 总结

这篇文章,我们分析了如何使用SseEmitter实现客户端和服务器的流式交互,SseEmitter提供了一个简洁的方式在 Spring 应用中实现服务器发送事件,通过维护持久连接和异步事件推送,满足了大多数实时数据推送的需求。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2024-05-17 09:35:55

GPT-4o模型OpenAI

2022-06-09 08:30:59

Istiospring clo

2024-10-14 09:20:09

异步流式接口

2024-10-14 13:30:20

2023-05-18 00:05:47

2009-08-14 14:53:55

WINDOWS服务交互

2023-05-11 00:15:04

2024-05-14 08:23:27

GPT-4oAI技术

2024-02-01 14:59:14

多线程硬件系统

2024-10-15 10:17:34

2019-04-08 15:11:12

HTTP协议Web

2020-09-25 07:49:36

策略模式Spring

2021-02-01 12:18:55

策略模式Spring

2022-07-07 14:18:43

SpringWeb应用设计

2024-06-19 10:48:31

ChatGPTGPT项目

2023-06-01 08:22:13

2010-01-20 09:23:38

jBPM高级交互模式jBPM四眼原则

2011-06-13 09:04:39

QT Flash 交互

2009-06-26 14:54:18

Spring支持EJB

2023-02-13 08:10:40

Gateway网关Spring
点赞
收藏

51CTO技术栈公众号