You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSE on-message事件在Postman正常但Angular前端无实时响应

问题分析与解决方案

核心问题

后端基于JAX-RS实现的SSE接口,通过Postman请求可实时接收每秒推送的消息,但使用Angular的EventSourcePolyfill请求时,所有消息需等待10秒后一次性返回,无法实时接收。

可能原因

  • 响应缓冲未禁用:后端容器(如Tomcat、Jetty)或前端代理服务器(如nginx)开启了响应缓冲,导致消息被缓存至请求结束才统一返回。
  • SSE消息格式不规范:手动拼接的消息未严格遵循SSE标准格式,前端无法识别单个事件边界。
  • EventSourcePolyfill配置问题:polyfill默认行为可能启用了内部缓冲,未正确处理分块传输。

后端修复方案

1. 规范SSE消息格式

使用JAX-RS的SseEventBuilder构建事件,自动处理标准格式(避免手动拼接换行符出错):

@GET
@Path("/stream")
@Produces("text/event-stream")
@Timed(absolute = true, name = "GET./stream")
public void getEmitter(@Context SseEventSink sseEventSink, @Context Sse sse, 
                       @QueryParam("prompt") String prompt) {
    System.out.println("prompt: " + prompt);
    executor.execute(() -> {
        try {
            for (int i = 0; i < 10; i++) {
                // 使用builder构建标准SSE事件
                sseEventSink.send(sse.newEventBuilder()
                    .data("Hello World!" + i)
                    .build());
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            sseEventSink.close();
        }
    });
}

2. 强制禁用响应缓冲

添加缓存控制头,确保容器不会缓冲响应:

@GET
@Path("/stream")
@Produces("text/event-stream")
@Timed(absolute = true, name = "GET./stream")
public void getEmitter(@Context SseEventSink sseEventSink, @Context Sse sse, 
                       @Context HttpServletResponse response, @QueryParam("prompt") String prompt) {
    // 禁用缓存与缓冲
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Expires", "0");
    // 强制启用分块传输
    response.setHeader("Transfer-Encoding", "chunked");

    executor.execute(() -> {
        try {
            for (int i = 0; i < 10; i++) {
                sseEventSink.send(sse.newEvent("Hello World!" + i));
                // 针对Jersey实现手动刷新输出流
                if (sseEventSink instanceof JerseySseEventSink) {
                    ((JerseySseEventSink) sseEventSink).getOutputStream().flush();
                }
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            sseEventSink.close();
        }
    });
}

3. 代理服务器配置调整

若使用nginx作为反向代理,针对SSE接口禁用缓冲:

location /api/ai/notes/stream {
    proxy_pass http://localhost:9999/ai/notes/stream;
    proxy_buffering off;
    proxy_set_header Connection '';
    proxy_http_version 1.1;
    chunked_transfer_encoding on;
}

前端修复方案

1. 测试原生EventSource(排除polyfill问题)

若目标浏览器支持原生EventSource,先替换polyfill验证:

sseTest() {
    const authToken = this.localStorageService.get('tokenInfo')['accessToken'];
    // 原生EventSource不支持自定义headers,若需携带token可通过URL参数传递
    const params = new URLSearchParams({ prompt: 'your-prompt' });
    const es = new EventSource(`/api/ai/notes/stream?${params}`);
    
    const listener = (event: Event) => {
        console.log(event);
    };
    es.addEventListener('open', listener);
    es.addEventListener('message', listener);
    es.addEventListener('error', listener);
}

2. 调整EventSourcePolyfill配置

若必须使用polyfill,禁用内部缓冲并添加缓存控制头:

sseTest() {
    const authToken = this.localStorageService.get('tokenInfo')['accessToken'];
    const eventSourceInitDict = {
        headers: {
            Authorization: 'Bearer ' + authToken,
            'Cache-Control': 'no-cache'
        },
        withCredentials: true,
        bufferSize: 1 // 禁用内部缓冲
    };
    
    const es = new EventSourcePolyfill('/api/ai/notes/stream', eventSourceInitDict);
    const listener = (event: any) => {
        console.log(event.data);
    };
    es.addEventListener('open', listener);
    es.addEventListener('message', listener);
    es.addEventListener('error', listener);
}

验证步骤

  1. 直接访问后端地址localhost:9999/ai/notes/stream,通过浏览器控制台确认是否实时接收消息。
  2. 检查代理服务器(若有)的缓冲配置是否已禁用。
  3. 查看后端返回的响应内容,确认每个事件以\n\n结尾,符合SSE标准格式。

内容的提问来源于stack exchange,提问作者Sritharan Mahendra Babu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:05:36