【发布时间】:2017-12-31 14:10:09
【问题描述】:
我正在实现一个带有 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()。
谁能给我一个建议,我做错了什么?如果没有解决方案,我将不得不手动检查注册的会话是否仍然存在,因为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 类。
有什么提示吗?
【问题讨论】:
-
您使用的是什么应用服务器?当你说关闭 WebSocket 时,你到底是什么意思?您是从调用 websocket.close() 的客户端 vi 关闭它吗?还是关闭浏览器?
-
我使用的是 Wildfly 10.0.1 应用服务器。尝试关闭 websocket 调用 ws.close() 并关闭浏览器。
-
可能与以下内容重复:stackoverflow.com/questions/24717403/…
-
@Duong Nguyen 这不是重复的。在发这个之前看到你的意思的帖子。我使用 Firefox、Chrom、IE、Edge 和一些用于 Websockets 的 FF/Chrome 插件测试了我的代码……此外:我实现的“@OnError”方法也没有被调用。关闭 websocket 时调用的唯一方法是编码器类中的“@OnDestroy”。
-
使用此quickstart 并添加
OnClose注释,在关闭选项卡时调用该方法。我使用wildfly 10.1.0.Final,Java 8。您在端点中使用的SessionHandler是什么?
标签: java websocket encoder oncloselistener