Skip to content

Avoid “No decoder for session id” Exception if session is closed #34787

Open
@piaorlm

Description

@piaorlm

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: messagingIssues in messaging modules (jms, messaging)status: waiting-for-triageAn issue we've not yet triaged or decided on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions