-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Hello, this is the same issue with #24842. Open another one since I can not reopen it because this issue has not been fixed eventually. It still happens occasionally when using org.springframework.web.socket.adapter.standard.StandardWebSocketSession.
The native org.apache.tomcat.websocket.wsSession will set its state finally to CLOSED after calling fireEndpointOnClose when calling StandardWebSocketSession#closeInternal. (tomcat-embed-websocket:10.1.39)
public class WsSession implements Session {
...
public void doClose(CloseReason closeReasonMessage, CloseReason closeReasonLocal, boolean closeSocket) {
if (!state.compareAndSet(State.OPEN, State.OUTPUT_CLOSING)) {
return;
}
...
fireEndpointOnClose(closeReasonLocal);
if (!state.compareAndSet(State.OUTPUT_CLOSING, State.OUTPUT_CLOSED) || closeSocket) {
state.set(State.CLOSED);
closeConnection();
} else {
sessionCloseTimeoutExpiry =
Long.valueOf(System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(getSessionCloseTimeout()));
}
...
}
...
}The method fireEndpoinOnClose will call the expression this.handler.afterConnectionClosed in org.springframework.web.socket.adapter.standar.StandardWebSocketHandlerAdapter#onClose.
Finally in org.springframework.web.socket.messaging.StompSubProtocolHandler#afterSessionEnded the decoder of the session will be removed.
However, during above process, the state of the session is still OUTPUT_ClOSING which is marked as true for isOpen method as below.
public class WsSession implements Session {
...
@Override
public boolean isOpen() {
return state.get() == State.OPEN || state.get() == State.OUTPUT_CLOSING || state.get() == State.CLOSING;
}
...
}Therefore, with the fix in previous issue, when the decoder is null for the session, the session might still be in state of OUTPUT_CLOSING.
BTW. This does not happen when using SocketJsSession, because the state will be set to CLOSED, here, before calling afterConnectionClosed