и в фоновом потоке Async мы отправляем непрерывные сообщения данных клиенту через SseEmitter
Метод @controller
Код: Выделить всё
@PostMapping(value = "/sse", consumes = { "application/json"},produces = {"text/event-stream"})
public ResponseEntity executeSseStreaming(
HttpServletRequest request, final @Valid @RequestBody ApiRequestDto apiRequestDto) throws JsonProcessingException {
String commandWithArgs = apiRequestDto.getCommand();
return new ResponseEntity(Service.executeServiceStreaming(commandWithArgs),
HttpStatus.OK);
}
Код: Выделить всё
@Override
public SseEmitter executeServiceStreaming(String command) {
SseEmitter sseEmitter = new SseEmitter(15 * 60 * 1000L);
commandInvoker.invokeAsyncMethodStreaming(command, sseEmitter);// background async task
return sseContext.getSseEmitter();
}
Код: Выделить всё
@Async("cmdAsyncCall")
public void invokeAsyncMethodStreaming(String cliBuff, SseEmitter sseEmitter) {
sock = connectionManagerFactory.getCommandExecConnection(cliBuff);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
sseEmitter().send(line);
}
sseContext.getSseEmitter().complete();
} catch (Exception e) {
sseContext.getSseEmitter().completeWithError(e);
throw new CustomException(ErrorConstants.EC_SOCKET_READ_FAILED, e);
}
}
Код: Выделить всё
@Configuration
@EnableAsync(proxyTargetClass = true)
public class CustomeAsyncCallConfig {
@Bean(name = "cmdAsyncCall")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("SSE Thread: AsyncCall -");
executor.initialize();
return executor;
}
}
Код: Выделить всё
12-Dec-2024 14:16:03.364 SEVERE [catalina-exec-7] org.apache.catalina.connector.CoyoteAdapter.asyncDispatch Exception while processing an asynchronous request java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.Response.sendError(Response.java:1110) at org.apache.catalina.connector.Response.sendError(Response.java:1092) at org.apache.catalina.valves.RequestFilterValve.denyRequest(RequestFilterValve.java:394) at org.apache.catalina.valves.RequestFilterValve.process(RequestFilterValve.java:364) at org.apache.catalina.valves.RemoteAddrValve.invoke(RemoteAddrValve.java:54) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239) at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:243) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Unknown Source)
- Возврат объекта SseEmmiter непосредственно из метода API контроллера ,
- Использование специальной службы Executor для асинхронной обработки и удаление @async.
Но это также вызывает ту же проблему. Клиент может получить все данные, соединение также закрывается на стороне клиента после получения всех данных в почтальоне. но на сервере эта ошибка возникает в самом конце в обоих случаях.
пробовал выполнить API также из пользовательского Java-клиента, но наблюдалось такое же поведение. Я могу получить все данные на стороне клиента с закрытием соединения в конце. но на стороне сервера есть это конкретное исключение в журналах Catalina. имя потока в stacktrace означает, что оно отличается от имени потока Async и может быть вызвано самой пружиной.
Я новичок в событиях, отправленных сервером. любая помощь будет принята с благодарностью. Заранее спасибо.
Подробнее здесь: https://stackoverflow.com/questions/792 ... -call-send