【问题标题】:Server-sent events SpringBoot - Angular 7服务器发送事件 SpringBoot - Angular 7
【发布时间】:2021-09-06 20:03:43
【问题描述】:

我正在使用SpringBoot 2.2.6Angular 7。由于某些原因,我需要在前端没有转发任何呼叫的情况下通过后端调用前端。

代码流应该从应该调用Angular 服务(或其他东西)的后端REST Controller 开始,我已经读过我必须使用Socket 但我找不到反映的示例或教程我的需求。

你能给我一个正确的解决方案或教程吗?

------------------- 更新 ------

感谢您的所有回复,我尝试了不同的解决方案,但没有人按预期工作。我找到了以下TypeScript 代码来拦截来自Angular 的事件:

export class LoginComponent implements OnInit {
  ngOnInit() {
   this.connect();
  }

  connect(): void {
   let source = new EventSource('http://localhost:8080/auth/streamsource');
   source.addEventListener('message', function (event) {
   let n: any;
   n = JSON.parse(event.data);
   console.log(event.data); 
   });
  }
}

但是当 LoginComponent 被加载时,它会循环调用跟随后端端点:

@CrossOrigin
@GetMapping("/streamsource")
public Flux<String> streamEvents() {
    return Flux.interval(Duration.ofSeconds(1))
              .map(sequence -> "Flux - " + LocalTime.now().toString());
}

我也尝试过:

@CrossOrigin
@RequestMapping(path = "/streamsource", method = RequestMethod.GET)
public SseEmitter stream() throws IOException {
    SseEmitter notifier = new SseEmitter();     
    notifier.send(SseEmitter.event().data("hello"));

    return notifier;    
}

结果相同.. 我想要实现的流程是:

  1. 客户开始(使用他自己的门户)一个 IDP 初始化的 SSO 并调用一个由SpringSecurity 过滤的端点
  2. 如果身份验证成功,Spring 将流程重定向到我指定的控制器
  3. 我想通过这个该死的控制器向我的前端发送一个令牌

有可能吗?

【问题讨论】:

  • 初始连接总是由浏览器建立的……对吧..?

标签: java angular spring-boot websocket


【解决方案1】:

套接字是一个选项,服务器发送事件也是如此。

服务器发送的事件: 服务器发送事件(SSE)打开一个 HTTP 连接并不断地向所有订阅的客户端发送更新。

WebSockets: WebSockets 用于客户端和服务器之间的双向通信。

HTTP 长轮询: 长轮询打开一个 HTTP 请求,该请求在收到更新之前一直保持打开状态。

查看下面的链接了解不同之处: https://aquil.io/articles/a-comparison-between-websockets-server-sent-events-and-polling

如果只有后端需要调用前端,那么 SSE 是正确的选择。 创建 SSE 流端点:

@GetMapping(path = "/stream-flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamFlux() {
    return Flux.interval(Duration.ofSeconds(1))
      .map(sequence -> "Flux - " + LocalTime.now().toString());
}

使用服务器发送的事件:

public void consumeServerSentEvent() {
    WebClient client = WebClient.create("http://localhost:8080/sse-server");
    ParameterizedTypeReference<ServerSentEvent<String>> type
     = new ParameterizedTypeReference<ServerSentEvent<String>>() {};

    Flux<ServerSentEvent<String>> eventStream = client.get()
      .uri("/stream-sse")
      .retrieve()
      .bodyToFlux(type);

    eventStream.subscribe(
      content -> logger.info("Time: {} - event: name[{}], id [{}], content[{}] ",
        LocalTime.now(), content.event(), content.id(), content.data()),
      error -> logger.error("Error receiving SSE: {}", error),
      () -> logger.info("Completed!!!"));
}

查看下面的链接了解完整的实施细节: https://www.baeldung.com/spring-server-sent-events

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @MarcoForberg 添加了简短的细节。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 2019-09-25
  • 1970-01-01
  • 2015-09-24
  • 2015-06-16
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多