如何正确关闭java-ee websocket连接

时间:2014-10-25 01:08:59

标签: java java-ee websocket

我正在使用java-ee websockets实现一个小型聊天应用程序 有一次,我想出于各种原因为客户关闭会话,以便关闭连接 为了关闭连接我调用了onClose函数,在那个函数中我调用了session.close()但是之后我得到了以下错误:

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)

我不确定我做错了什么,为什么我得到了这个例外。

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,因为我今天开始学习这些东西。

到目前为止我发现的是,在注释@OnMessage的服务器上,当服务器收到" quit"时,我正在关闭连接。通过调用session.close消息。 然后在@OnMessage结束时,我发出了强制性的返回,因为该方法需要返回,并且它是抛出异常的返回,因为会话已经关闭了。

我的解决方案是,不是让服务器关闭会话,而是发送消息" youquit"回到客户端,我让客户端调用session.close。

服务器现在接收close事件并准备好进行下一次连接,客户端无例外地结束。

@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));
}

我试图在返回级别捕获异常,但它不起作用。

我现在相信你无法在@OnMessage入口点关闭连接。

答案 1 :(得分:1)

这似乎是由于一个现已修复的错误: https://github.com/Atmosphere/atmosphere/issues/1770

答案 2 :(得分:0)

Websocket OnClose方法在会话关闭时调用,您不需要关闭会话。你想要关闭闭会话。此错误显示会话已关闭。你可以从这里看到它:

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

  

会话结束后,它将不再有效   应用。调用它的任何方法(除了   close()方法)一旦会话关闭就会导致   抛出IllegalStateException。开发人员应该检索任何   来自会议期间的信息   Endpoint.onClose(javax.websocket.Session,javax.websocket.CloseReason)   方法。遵循Closeable调用Session的约定   会话关闭后的close()方法无效。

答案 3 :(得分:0)

检查会话是否已打开,如果是,请将其关闭。

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