gpt4 book ai didi

java - WebSocket:永远不会调用 OnClose()

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:44 41 4
gpt4 key购买 nike

我正在实现一个带有 WebSocket 端点的应用程序。这是一些代码:

@ApplicationScoped
@ServerEndpoint(value="/socket", encoders = {MessageEncoder.class, CommandEncoder.class})
public class SocketEndpoint {

/** Default-Logger */
private final static Logger LOG = LoggerFactory.getLogger(SocketEndpoint.class);

@Inject
SessionHandler sessionHandler;

@OnOpen
public void open(Session session, EndpointConfig config) {
LOG.debug("Connected session => '{}' - '{}'", session, config);
sessionHandler.initSession(session);
}

@OnMessage
public void onMessage(Session session, String messageJson) {
// do something
}

@OnClose
public void onClose(Session session, CloseReason reason) {
LOG.debug("Closing session => '{}' - '{}'", session, reason);
sessionHandler.removeSession(session);
}

@OnError
public void onError(Session session, Throwable ex) {
LOG.error("WebSocket error => '{}'", ex.getMessage());
}
}

其中一个编码类如下所示:

public class MessageEncoder implements Encoder.Text<Message> {

/** Default-Logger */
private final static Logger LOG = LoggerFactory.getLogger(MessageEncoder.class);

@Override
public void init(EndpointConfig config) {
LOG.debug("Init MessageEncoder");
}

@Override
public void destroy() {
LOG.debug("Destroy MessageEncoder");
}

@Override
public String encode(MessageE message) throws EncodeException {
return message.toString();
}
}

打开 WebSocket 按预期调用 SocketEndpoint.open()。关闭 WebSocket 仅调用 MessageEncoder.destroy() 而不是 SocketEndpoint.close()

谁能给我一个建议,我做错了什么?如果没有解决方案,我将不得不手动检查注册的 session 是否仍然存在,因为 MessageEncoder.destroy() 没有参数。

提前致谢!


更新

刚刚实现了一个虚拟端点:

@ApplicationScoped
@ServerEndpoint("/dummy")
public class DummyEndpoint {

/** Default-Logger */
private final static Logger LOG = LoggerFactory.getLogger(DummyEndpoint.class);

@OnOpen
public void open(Session session, EndpointConfig config) {
LOG.debug("Connected session with principal => '{}'", session.getId());
}

@OnMessage
public void onMessage(Session session, String messageJson) {
LOG.debug("on message => '{}' => '{}'", session.getId(), messageJson);
}

@OnClose
public void onClose(Session session, CloseReason reason) {
LOG.debug("Closing session => '{}' - '{}'", session, reason);
}

@OnError
public void onError(Session session, Throwable ex) {
LOG.error("WebSocket error => '{}' => '{}'", session, ex.getMessage());
}
}

当使用这个虚拟端点时 @OnClose 被正确调用。我只能看到与 SocketEndpoint 类的一个主要区别:DummyEndpoint 不使用任何 Encoder 类。

有什么提示吗?

最佳答案

如评论中所述,代码运行良好。如果我们从这个 wildfly-websocket-quickstart 开始,在 @OnClose 上添加一个 ServerEndpoint 装饰方法,它可以很好地使用 Wildfly 10.x 和最新的浏览器(例如 Chrome v59.x)。此处工作的 ServerEndpoint 示例(要使用 @Inject 不要忘记在 WEB-INF 文件夹中添加 beans.xml):

@ApplicationScoped
@ServerEndpoint(value="/shout", encoders = {MessageEncoder.class})
public class ShoutServerEndpoint {

@Inject
SessionHandler s;

@OnOpen
public void open(Session session, EndpointConfig config) throws Exception {
s.initSession(session);
}

@OnMessage
public void shout(String text, Session client) {
System.out.println("Session: " + client + " has text: " + text);
Message m = new Message();
try {
client.getBasicRemote().sendObject(m);//use the encoder to write some dummy message
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (EncodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
client.getAsyncRemote().sendText(text.toUpperCase());
}


@OnClose
public void onClose(Session client, CloseReason reason){
System.out.println("Session " + client + " closing for " + reason);
s.destroySession(client);

}

@OnError
public void onError(Session session, Throwable ex) {
System.out.println("error: " + ex.getMessage() );
}
}

因此罪魁祸首似乎是 wildfly 使用的旧版本代码在重新部署 webapp 期间未被清理,例如,使用 Eclipse,如果出现奇怪的行为,使用 Clean 是值得的使用的服务器上的选项(参见:this Eclipse doc)

如果直接使用 wildfly 部署,您可以通过删除(从 this article 开始)中的所有内容来清理资源:

  • /[wildfly-location]/standalone/data
  • /[wildfly-location]/standalone/deployments
  • /[wildfly-location]/standalone/tmp

它确保在未来部署期间不会保留您的代码的旧副本。

关于java - WebSocket:永远不会调用 OnClose(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45306863/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com