У меня несколько проблем с производительностью при отправке данных с сервера в браузер с использованием событий, отправленных сервером.Я сделал метод @RequestMapping
(getSseEmitter
) в контроллере, который запускается из пользовательского интерфейса при загрузке страницы.Который инициирует SseEmitter
, а также реализует метод @EventListener
(onEventEmitter
), который будет вызываться всякий раз, когда я пытаюсь опубликовать событие сообщения / объекта (this.eventPublisher.publishEvent(chain)
).
Я пытаюсь здесь сделать простую вещь.. Всякий раз, когда цепочечный процесс успешно выполняется в запланированное время, пользовательский интерфейс автоматически должен обновлять статус «Последние», время завершения и другие подробности.Итак, я должен опубликовать событие (т. Е. this.eventPublisher.publishEvent(chain)
) в начале и конце выполнения Chain
.
Пока все работает нормально, после публикации события вручную метод onEventEmitter
вызывается и отправляется в браузер методом refreshChainStatus
в onMesaage
блок и получает работу, выполненную согласно требованию.
Но возникает проблема: метод обработчика (getSseEmitter
) в ChainController
часто выполняется и консоль заполняется перечисленными ниже ошибками.
Ошибка в консоли браузера: Не удалось загрузить ресурс: net :: ERR_EMPTY_RESPONSE
Ошибка в консоли редактора пользовательского интерфейса: [HPM] GET / XXXXXX / rest / api / refreshChainStatus -> https://localhost:8443
Ошибка в редакторе кода сервераКонсоль: [ОШИБКА] 2019-09-24 12: 44: 42.273 [https-jsse-nio-8443-exec-8] DefaultHandlerExceptionResolver - Тайм-аут асинхронного ожидания для GET [/ XXXXXX / rest / api / refreshChainStatus]
Если источник события снова восстанавливает соединение, то есть снова вызывает метод контроллера, что, конечно, мне не нужно.
Пожалуйста, предложите мне, как избежать вышеупомянутых ошибок, влияющих на производительность.
Пожалуйста, найдите ниже код соответственно:
@RestController
public class ChainController {
@RequestMapping(value = "/sse")
public SseEmitter getSseEmitter(HttpServletResponse response) {
response.setHeader("Cache-Control", "no-store");
SseEmitter emitter = new SseEmitter(180_000L);
emitter.onCompletion(() -> this.emitters.remove(emitter));
emitter.onTimeout(() -> this.emitters.remove(emitter));
this.emitters.add(emitter);
return emitter;
}
@EventListener
public void onEventEmitter(Chain result) {
List<SseEmitter> deadEmitters = new ArrayList<>();
this.emitters.forEach(emitter -> {
try {
emitter.send(result);
}
catch (Exception e) {
deadEmitters.add(emitter);
}
});
this.emitters.removeAll(deadEmitters);
}
}
this.eventPublisher.publishEvent(chain); //Call from another service class.
Код машинописного текста:
refreshChainStatus() {
var eventSource = new EventSource("/sse");
eventSource.onmessage = function(event) {
};
eventSource.onopen = e => {
}
eventSource.onerror = e => {
eventSource.close();
};
eventSource.addEventListener('second', function(e) {
}, false);
}