I'm implementing an application with a WebSocket endpoint. Here is some code:
@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());
}
}
One of the encode class looks like this:
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();
}
}
Opening the WebSocket calls SocketEndpoint.open()
as expected.
Closing the WebSocket only calls MessageEncoder.destroy()
but not SocketEndpoint.close()
.
Can anyone give me an advise, what I did wrong? Without a solution I would have to check manually if registered sessions are still alive since MessageEncoder.destroy()
has no parameters.
Thanks in advance!
UPDATE
Just implemented a dummy endpoint:
@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());
}
}
When using this dummy endpoint @OnClose
is properly called. I can only see one major difference to the SocketEndpoint
class: DummyEndpoint
does not use any Encoder
classes.
Any hints?
OnClose
annotation, the method is called when closing a tab. I used wildfly 10.1.0.Final, Java 8. What is thisSessionHandler
you use in your endpoint? – EsophagitisSessionHandler
is just a class providing a map that holds all registered sessions and operations on that map. – Kerrillonclose
method is still called correctly, so the issue comes from somewhere else, it would be nice if you could point to a repository with your code to reproduce exactly the issue, as so far it is not feasible. – EsophagitisClean
option on my Wildfly. I'd suspect something like this is happening because your code is working well on my instance. (By the way, when responding please use@username
so that I see your response in my inbox) – Esophagitis