How to properly close java-ee web connection

I am using a small chat application using java-ee websockets.
At one time I want to close the session for the client for various reasons, so to close the connection.
To close the connection, I named a function onClose

and in this function I named 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 why I got this exception.

+3


source to share


4 answers


I had the same problem as I started studying this stuff today.

What I have found so far is that on the server, in the @OnMessage annotation, I was closing the connection when the server received a "quit" message by calling session.close. Then at the end of @OnMessage, I was issuing a return value that is required since the method requires a return, and that was a return that would throw an exception since the session was already closed.

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

The server now receives a 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 tried to catch the exception at the return level but it doesn't work.

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

+2


source


This seems to be related to a bug that was fixed: https://github.com/Atmosphere/atmosphere/issues/1770



+1


source


Websocket's OnClose method calls when the session is closed, you don't need a closed session. You want to close the closed session. This error indicates that the session has already been 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 using the Application. Calling any of its methods (with the exception of close ()) after the session is closed will throw an IllegalStateException. Developers need information from the session during the Endpoint.onClose (javax.websocket.Session, javax.websocket.CloseReason) method. Following the close convention, calling the session close () after the session is closed has no effect.

0


source


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

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

      

0


source







All Articles