我的应用程序是一个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);
}
}
如this中所述,返回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()));
}
这有助于通过断开连接来关闭UI端的连接。但我的主要问题仍未解决。我应该如何将错误消息传播回前端?所有其他(普通)端点都会使用上面给出的正确HTTP代码抛出自定义运行时异常。
我是否应该更改我的ProcessedResult类以获取异常详细信息?
服务器端事件使用开放的HTTP连接来流式传输来自服务器的内容。根据Eventsource的W3C规范,建立连接需要具有适当Content-Type头的HTTP 200 OK响应,HTTP 500, 502, 503, 504
或任何其他网络错误将导致浏览器重新建立连接。如果上述情况均不满足,则使用readyState = 'CLOSED'
触发错误事件。简而言之,onError
回调仅用于处理网络超时或访问控制问题。
由于您在建立连接时已经发送了200 Ok,因此无法根据运行时异常发送不同的HTTP状态代码。处理运行时错误的唯一方法是捕获异常并从服务器发送自定义命名事件,并基于此向close
发送EvetSource
。