Sec*_*one 14 java encoder websocket oncloselistener
我正在使用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());
}
}
Run Code Online (Sandbox Code Playgroud)
其中一个编码类看起来像这样:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
SocketEndpoint.open()按预期打开WebSocket调用.关闭WebSocket仅调用MessageEncoder.destroy()但不调用SocketEndpoint.close().
任何人都可以给我一个建议,我做错了什么?没有解决方案,我必须手动检查注册的会话是否仍然存在,因为MessageEncoder.destroy()没有参数.
提前致谢!
UPDATE
刚刚实现了一个虚拟端点:
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
使用此虚拟端点时,@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() );
}
}
Run Code Online (Sandbox Code Playgroud)
因此,罪魁祸首似乎是 Wildfly 使用的旧版本代码在重新部署 Web 应用程序期间未清理,例如使用 Eclipse,如果出现奇怪的行为,则值得在Clean服务器上使用该选项使用(参见:此 Eclipse 文档)
如果直接使用 Wildfly 进行部署,您可以通过删除(来自本文)中的所有内容来清理资源:
/[wildfly-location]/standalone/data/[wildfly-location]/standalone/deployments/[wildfly-location]/standalone/tmp它确保在未来的部署期间不会保留旧代码的副本。
| 归档时间: |
|
| 查看次数: |
1635 次 |
| 最近记录: |