В качестве последнего средства я пытаюсь закрыть сеансы WebSocket (WS) в Spring (с Spring WebSocket и Spring Session) без участия клиента (и без использования SockJS Spring и его реализаций).
То, что я сейчас делаю, в основном следующее:
public class WsSessionTerminator extends WebSocketHandlerDecorator {
@Override
public void afterConnectionEstablished(WebSocketSession wsSession) throws Exception {
if (tooManyWsSessionsForHttpSession(wsSession)) {
wsSession.close(); // closes session, but WebSocketRegistryListener is not notified
}
super.afterConnectionEstablished(wsSession); // required even if WS session is closed
}
Хотя это закрывает фактический сеанс WS, Spring * WebSocketRegistryListener
не удаляет сеанс WS из своего отображения сеансов HTTP.на сессиях WS.Закрытый сеанс WS остается связанным с сеансом HTTP, пока последний существует.Однако это, похоже, зависит от конкретной реализации.Насколько я могу видеть, простое использование WebSocketSession.close()
уведомит WebSocketRegistryListener
(среди прочего) в AbstractSockJsSession
, но не в StandardWebSocketSession
(который используется в моем случае).
I 'мы попытались обойти проблему следующим образом:
- немедленно позвонив
super.afterConnectionClosed(session, CloseStatus.POLICY_VIOLATION);
;даже если это не вызовет исключение («нет декодера для сеанса ...»), это кажется расточительным решением - , вручную запускающим
SessionDisconnectEvent
;это удалит сеанс из WebSocketRegistryListener
, но создание ложного (STOMP) сообщения ОТКЛЮЧЕНИЕ для события кажется неправильным - с использованием
HandshakeHandler
или прослушиванием (и обработкой) различных событий сеансов без успеха
Я что-то упустил или это упущение со стороны Spring?