Dheerendra
Dheerendra

Reputation: 1568

How to close java-ee websocket connection properly

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.

Upvotes: 6

Views: 11932

Answers (4)

Joao Thomazini
Joao Thomazini

Reputation: 61

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.

Upvotes: 3

Sely Lychee
Sely Lychee

Reputation: 312

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

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

Upvotes: 0

Mike
Mike

Reputation: 4963

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

Upvotes: 1

Anar Orujov
Anar Orujov

Reputation: 591

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.

Upvotes: 0

Related Questions