Я использую серверные события (SSE) в Java Spring. Всякий раз, когда новый клиент подписывается на услугу событий я выполнить следующий код в контроллере REST:Java spring SseEmitter/ResponseBodyEmitter: обнаружение перезагрузки браузера
SseEmitter emitter = new SseEmitter(-1L);
emitter.onCompletion(() -> {
logger.debug(TAG + "Emitter completed.");
emitters.remove(emitter);
});
return emitter;
Затем, когда должно быть доведено до сведения клиентов исполняют событие:
for (ResponseBodyEmitter emitter: emitters) {
emitter.send("Message #1");
}
Проблемы заключается в том, что когда один из клиентов перезагружает браузер, эмиттер не завершается (как я и ожидал), и при вызове вышеприведенного кода я получаю исключение прерывистого канала. Только после запуска этого исключения я вижу, что эмиттер завершен.
Есть ли способ решить эту проблему?
Как вы обрабатываете несколько вкладок, jwt будет одинаковым для всех вкладок в сеансе, правильно? – TruckDriver
Что делать, если клиент внезапно закрывает приложение, никогда не возвращается в течение 30 дней. Старое соединение все равно останется открытым? Это также не очень хорошо работает, когда есть несколько серверов приложений с балансировкой нагрузки - поскольку пользователь может подключаться к другой AS при их повторном подключении. Это не похоже на перспективный подход. – user1102532
Нет, SseEmitter создается со значением тайм-аута в конструкторе. Тайм-аут не относится к простоям, а скорее к «времени жить». По дизайну соединения будут удалены каждый, например. X секунд/минут, и клиент воссоздает его ... если он по-прежнему необходим. Что касается балансировки нагрузки, конечно, когда клиент подключается или повторно подключается, код сервера не должен полагаться на состояние в памяти, чтобы воссоздать сеанс клиента. Но опять же, дизайн SSE, а также SseEmitter от Spring, по своей сути связан с сеансом/соединением, так что пока соединение живое, вы можете работать в mem. –