Я реализую приложение с конечной точкой 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());
}
}
Один из классов encode выглядит так:
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
.
Любые подсказки?
OnClose
, метод вызывается при закрытии вкладки. Я использовал wildfly 10.1.0.Final, Java 8. Что это заSessionHandler
вы используете в своей конечной точке? - person Adonis   schedule 31.07.2017SessionHandler
— это просто класс, предоставляющий карту, которая содержит все зарегистрированные сеансы и операции на этой карте. - person Second2None   schedule 31.07.2017onclose
по-прежнему вызывается правильно, поэтому проблема возникает откуда-то еще, было бы неплохо, если бы вы могли указать репозиторий с вашим кодом для воспроизведения именно вопрос, так как пока это неосуществимо. - person Adonis   schedule 31.07.2017Clean
на моя Уайлдфлай. Я подозреваю, что что-то подобное происходит, потому что ваш код хорошо работает на моем экземпляре. (Кстати, при ответе используйте@username
, чтобы я увидел ваш ответ в своем почтовом ящике) - person Adonis   schedule 01.08.2017