当前位置: 首页 > news >正文

SSE SseEmitter.completeWithError(e) 触发的处理逻辑

Java 客户端使用 OkHttp 监听 SSE(Server-Sent Events) 的情况下,当服务端调用 SseEmitter.completeWithError(e),客户端会触发 EventSourceListeneronFailure() 方法(而不是 onError)。


1. 服务端(Spring Boot)调用 completeWithError

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@RestController
public class SseController {

    @GetMapping("/sse-stream")
    public SseEmitter streamEvents() {
        SseEmitter emitter = new SseEmitter();

        new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    emitter.send(SseEmitter.event().data("Event " + i));
                    Thread.sleep(1000);
                }
                // 模拟一个错误并主动关闭
                throw new RuntimeException("Server-side error!");
            } catch (Exception e) {
                emitter.completeWithError(e); // 触发客户端的 onFailure()
            }
        }).start();

        return emitter;
    }
}

2. 客户端(Java + OkHttp)监听 SSE

OkHttp 提供了 EventSource 类来监听 SSE 事件,并需要实现 EventSourceListener 来接收回调。

关键方法

  • onOpen() – 连接建立时触发。
  • onEvent() – 收到服务器事件时触发。
  • onClosed() – 服务器主动关闭(emitter.complete())时触发。
  • onFailure() – 服务器调用 completeWithError() 或网络错误时触发

代码示例

import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;

public class SseClient {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("http://localhost:8080/sse-stream")
                .build();

        EventSource.Factory factory = EventSources.createFactory(client);
        factory.newEventSource(request, new EventSourceListener() {
            @Override
            public void onOpen(EventSource eventSource, Response response) {
                System.out.println("SSE connected!");
            }

            @Override
            public void onEvent(EventSource eventSource, String id, String type, String data) {
                System.out.println("Received event: " + data);
            }

            @Override
            public void onClosed(EventSource eventSource) {
                System.out.println("SSE closed by server.");
            }

            @Override
            public void onFailure(EventSource eventSource, Throwable t, Response response) {
                System.err.println("SSE error: " + t.getMessage());
                // 可以在这里重试
            }
        });
    }
}

3. 执行流程

  1. 服务端
    • 发送5条事件后,调用 emitter.completeWithError(e)
  2. 客户端
    • 收到5条正常事件(onEvent())。
    • 当服务端 completeWithError(e) 时,触发 onFailure(),并打印错误信息。

4. 总结

服务端行为客户端(OkHttp)回调方法
emitter.send(data)onEvent()
emitter.complete()onClosed()
emitter.completeWithError(e)onFailure()
网络断开/超时onFailure()

因此,SseEmitter.completeWithError(e) 会触发客户端的 onFailure() 方法,而不是 onError(这是浏览器 EventSource 的行为)。

相关文章:

  • 使用 PowerShell 脚本 + FFmpeg 在 Windows 系统中批量计算 MP4视频 文件的总时长
  • (C语言)文本动态通讯录(动态通讯录升级版)(C语言小项目)
  • macOS 15 通过 MacPorts 安装 PHP 7 构建错误找不到符号在 dns.o 中解决方法
  • 使用 rsync 进行服务器文件同步与优化
  • STM32基础教程——输入捕获模式测量PWM频率
  • SD(Stable Diffusion)模型学习图谱
  • 视频生成的测试时Scaling时刻!清华开源Video-T1,无需重新训练让性能飙升
  • 内网YUM源搭建手册(Internal Network yum Source Construction Manual)
  • c++ primer 阅读手记 第六章
  • RCE——回调后门
  • 【ADC测试】在ADC马密度的方式测试INL和DNL
  • 蓝桥杯python编程每日刷题 day 20
  • postman测试调用WebService时不会自动添加命名空间
  • 交换机与路由器的区别:深入解析
  • nginx优化(持续更新!!!)
  • cv图像分割
  • Python正则表达式(二)
  • 从零开始跑通3DGS教程:介绍
  • Java + LangChain 实战入门,开发大语言模型应用!
  • 【实战】解决图片 Hover 抖动问题的完整指南
  • 武汉网站建设工作室/宁波网络推广产品服务
  • 时尚网站网页设计/北京seo优化技术
  • 湖州网站建设湖州网站建设/seo快速排名关键词
  • 好利蛋糕店官方网站/webview播放视频
  • 网站建设副业/优化网站的软件下载
  • 建设网站相关法律条文/郑州学校网站建设