Завершить отправленное событие IOException, вызывающее неуловимое исключение IllegalStateException - PullRequest
0 голосов
/ 24 января 2019

У меня есть приложение, в котором клиенты получают SseEmitter, SseEmitter будет передавать клиенту сообщения jms.

Существует проблема, когда клиент закрывает соединение (закрывает браузер).Будет сгенерировано исключение IOException, что приведет к следующему неуловимому исключению:

2019-01-24 12:33:59.163 ERROR 26516 --- [nio-8080-exec-6] o.a.catalina.connector.CoyoteAdapter     : Exception while processing an asynchronous request

java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
    at org.apache.coyote.AsyncStateMachine.asyncError(AsyncStateMachine.java:440) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:512) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.Request.action(Request.java:430) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:382) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_162]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_162]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.14.jar:9.0.14]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162]

Перехват исключения IOException не препятствует созданию этого исключения.Я реализовал работу, в рамках которой клиент отправляет запрос на удаление своего эмиттера из коллекции эмиттеров, которые будут отправлять события.

Однако в случае сбоя клиента / браузера это исключение все равно будет выдано.

   @Scheduled(fixedDelay = 2000L)
      public void sendEvent()  {
           TextMessage message = null;
           try {
               message = messageBlockingQueue.take();
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           for(SseEmitter sseEmitter:emitterMap.values()) {
               TextMessage finalMessage = message;
                   try {
                       sseEmitter.send(finalMessage.getText());
                   }  catch (IOException e) {
                       sseEmitter.completeWithError(e);
                   } catch (JMSException e) {
                       e.printStackTrace();
                   }
            }
        }

конечная точка:

@CrossOrigin(allowCredentials = "true")
@RequestMapping(value = "/event", method = RequestMethod.GET)
public SseEmitter getEvent(HttpServletRequest request){
    HttpSession session = request.getSession();
    if(eventService.getEmitterMap().containsKey(session)){
        System.out.println("existing sub found:"+session.getId());
        return eventService.getEmitterMap().get(session);
    }else{
        final SseEmitter emitter = new SseEmitter(84000000000L);
        eventService.register(session,emitter);
        System.out.println("created new sub:"+session.getId());
        return emitter;
    }
}

1 Ответ

0 голосов
/ 24 января 2019

После дальнейших исследований это исключение можно объяснить ошибкой в ​​tomcat.

https://github.com/spring-projects/spring-boot/issues/15057

Чтобы решить эту проблему, я переключился с tomcat на jetty.

...