6

I am implementing a small chat application using java-ee websockets.
At one time I want to close session for a client for various reasons so for closing connection.
For closing connection I called onClose function and in that function I called session.close() But after that I got the following error:

java.lang.IllegalStateException: The WebSocket session has been closed and no method (apart from close()) may be called on a closed session
    at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:643)
    at org.apache.tomcat.websocket.WsSession.addMessageHandler(WsSession.java:168)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:81)
    at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:129)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:629)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

I'm not sure what I did wrong and I why I got this exception.

1
  • It's been a year already.. did you figure out where was the problem and how to handle it properly? I have the same issue now on Tomcat7
    – TMG
    Commented Nov 15, 2015 at 15:19

4 Answers 4

3

I was having the same issue as I started learning this stuff today.

What I have found so far is that on the server at the annotation @OnMessage I was closing the connection when the Server received a "quit" message by calling the session.close. Then at the end of the @OnMessage I was issuing the return that is mandatory as the method requires a return and it was the return that was throwing the Exception since the session has been closed already.

My solution is to instead of making the server close the session I send a message "youquit" back to the client and I have the client calling the session.close.

The server now receives the close event and is ready for the next connection and the client ends without exception.

@OnMessage
public String onMessage(String message, Session session) throws DeploymentException, IOException {
    switch (message) {
        case "quit":
            //session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "Game ended"));
            message = "you" + message;
            break;
    }
    return message;
}

@OnClose
public void onClose(Session session, CloseReason closeReason) {
    logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
}

I have tried to catch the exception at the return level but it does not work.

I now believe that you cannot close the connection at the @OnMessage entry point.

1

This appears to have been due to a bug which has now been fixed: https://github.com/Atmosphere/atmosphere/issues/1770

1
  • I don't think this is relevant in this case. The OP seems to use JSR356 websocket API directly rather than via Atmosphere framework.
    – TMG
    Commented Nov 15, 2015 at 15:18
0

Websocket OnClose method invokes when session closes, you dont need close session. You want close closed session. This error shows that session already closed. You can see it from here:

http://docs.oracle.com/javaee/7/api/javax/websocket/Session.html

Once the session is closed, it is no longer valid for use by applications. Calling any of its methods (with the exception of the close() methods) once the session has been closed will result in an IllegalStateException being thrown. Developers should retrieve any information from the session during the Endpoint.onClose(javax.websocket.Session, javax.websocket.CloseReason) method. Following the convention of Closeable calling the Session close() methods after the Session has been closed has no effect.

4
  • As the blockquote is saying "Calling any of its methods (with the exception of the close() methods) once the session has been closed will result in an IllegalStateException being thrown" but it is throwing IllegalStateException on calling session.close()
    – Dheerendra
    Commented Oct 25, 2014 at 7:52
  • are you sure that after session close dont call other method? did you debug project? Commented Oct 25, 2014 at 9:00
  • 1
    All I want to do is force close the session from server side, that's why I called session.close()
    – Dheerendra
    Commented Oct 25, 2014 at 18:59
  • When the client is interrupted, there is no OnClose trigger on the server, for at least Tomcat 9 and probably many others. If the client ends the connection, an EndOfFile error is thrown. I catch that in OnError and close the connection there. Commented Nov 22, 2020 at 21:25
0

Check if the session is open and close it if yes.

if(session.isOpen()){
    session.close();
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.