Jay*_*Jay 7 java server-sent-events spring-boot spring-webflux angular
我的应用程序是一个具有多个端点的Spring Boot应用程序。我们正在尝试使用Webflux添加启用SSE的端点。
用例:
步骤1:前端向POST端点提交请求,并获得唯一的ID。
步骤2:前端使用GET端点获取处理的结果(启用SSE-Flux)
Angular使用EventSource对象来使用SSE端点。它需要端点来产生文本/事件流。它对于肯定的测试用例非常有效。但是,当从服务中抛出运行时异常时,Angular前端将无法获取HTTP状态代码和异常详细信息。只是没有数据的错误。
抛出异常:
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class RequestNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public RequestNotFoundException(String message) {
super(message);
}
}
Run Code Online (Sandbox Code Playgroud)
如本节所述,返回a Flux<ServerSentEvent>并以自定义事件终止通量:
Java端点
@GetMapping(path= "{id}/async", produces=MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Optional<ProcessedResult>>> getProcessedResultStream(
@PathVariable("id") @ApiParam(value = "The unique identifier of the request", required = true) String id)
throws InterruptedException {
// Combining data and adding a disconnect event to handle at the frontend.
return Flux.concat(
Flux.just(ServerSentEvent.<Optional<ProcessedResult>>builder(service.getProcessedResult(id))
.build()),
Flux.just(ServerSentEvent.<Optional<ProcessedResult>>builder().event("disconnect").build()));
}
Run Code Online (Sandbox Code Playgroud)
这有助于通过断开连接来在UI端关闭连接。但是我的主要问题仍然悬而未决。我应该如何将错误消息传播回前端?所有其他(正常)终结点都会使用上述正确的HTTP代码引发自定义运行时异常。
我是否也应该更改ProcessedResult类以获取异常详细信息?
服务器端事件使用开放的 HTTP 连接从服务器传输内容。根据 W3C 规范,Eventsource HTTP 200 OK响应需要具有正确的 Content-Type 标头才能建立连接,HTTP 500, 502, 503, 504否则任何其他网络错误将导致浏览器重新建立连接。如果上述情况都不满足,则会触发错误事件readyState = 'CLOSED'。简而言之,onError回调仅用于处理网络超时或访问控制问题。
不可能根据运行时异常发送不同的 HTTP 状态代码,因为您在建立连接时已经发送了。200 OK处理运行时错误的唯一方法是捕获异常并从服务器发送自定义命名事件并基于该事件close。EventSource