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

Angular中Server-Sent Event发起多次请求问题咨询

问题描述

我正在使用Angular和Spring Boot开发简易聊天系统,采用Server-Sent Event(SSE)实现。客户端已完成开发,可正常接收事件,但在浏览器网络控制台发现异常:预期仅调用一次接口,实际出现多次请求。添加onopen事件后确认该问题存在,请问这是我的实现错误还是Angular的正常行为?

以下是客户端代码:

private getMessages(): Observable<any> {
  return new Observable((observer: { next: (arg0: any) => void; }) => {
    let ess = new EventSource("http://localhost:8080/api/messages");

    ess.onopen = ev => {
      console.log("Connection open")
    }

    ess.onmessage = ev => {
      this.zone.run(() => {
        observer.next(ev.data)
      })
    }
  })
}

ngOnInit(): void {
  this.sub = this.getMessages().subscribe({
    next: (data: any) => {
      //console.log(data);
      this.addMessage(data)
    },
    error: err => console.log(err)
  });
}

网络请求截图:
浏览器网络控制台多次请求截图

问题分析与解决

这不是Angular的正常行为,是你的SSE实现存在几个关键问题导致的重复连接:

  • 缺少连接关闭逻辑
    你的Observable没有处理订阅取消时的资源释放,当组件被销毁或者订阅被取消时,EventSource没有被关闭。如果组件因为路由跳转、变更检测等原因重新初始化,就会创建新的EventSource连接,旧连接可能还没断开,导致多次请求。

    解决办法:在Observable的清理函数里关闭EventSource:

    private getMessages(): Observable<any> {
      return new Observable((observer: { next: (arg0: any) => void; }) => {
        const ess = new EventSource("http://localhost:8080/api/messages");
    
        ess.onopen = ev => {
          console.log("Connection open")
        }
    
        ess.onmessage = ev => {
          this.zone.run(() => {
            observer.next(ev.data)
          })
        }
    
        // 添加清理逻辑,订阅取消时关闭连接
        return () => {
          ess.close();
          console.log("Connection closed")
        };
      })
    }
    
  • 组件未正确销毁订阅
    如果组件被多次实例化(比如路由复用、组件嵌套重复渲染),或者ngOnInit被多次触发,会重复创建订阅和SSE连接。需要在组件销毁时主动取消订阅:

    ngOnDestroy(): void {
      if (this.sub) {
        this.sub.unsubscribe();
      }
    }
    
  • SSE服务端连接异常导致自动重连
    浏览器的EventSource默认会在连接断开后自动重连,如果你的Spring Boot服务端没有正确保持SSE长连接(比如超时、异常断开、响应头配置错误),浏览器就会自动发起新连接。检查服务端的响应头是否正确设置:

    • Content-Type: text/event-stream
    • Cache-Control: no-cache
    • Connection: keep-alive
      同时确保服务端不会主动关闭连接,维持长连接状态。

内容的提问来源于stack exchange,提问作者Giane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:56:30