Я использую tomcat 8.0.23 для прекращения подключения к сети. У меня есть следующий код, чтобы заботиться о входящих сообщений:Tomcat throws «Удаленная конечная точка находилась в состоянии [BINARY_FULL_WRITING] ...» при попытке записи в сеанс websocket одновременно
@OnMessage
public void onMsg(Session session, byte[] request) {
executorService.execute(() ->
session.getAsyncRemote().sendBinary(
ByteBuffer.wrap(getResponse(session, request)), result -> {
if (!result.isOK()) {
LOGGER.catching(result.getException());
}
}
));
}
Но я получаю следующее исключение:
Exception in thread "pool-6-thread-10160" java.lang.IllegalStateException: The remote endpoint was in state [BINARY_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1148)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.binaryStart(WsRemoteEndpointImplBase.java:1101)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendBytesByCompletion(WsRemoteEndpointImplBase.java:152)
at org.apache.tomcat.websocket.WsRemoteEndpointAsync.sendBinary(WsRemoteEndpointAsync.java:65)
Похоже, что, когда я пытаюсь написать в ту же сессию одновременно Это исключение вызывает tomcat.
ошибка исходит от this method:
private void checkState(State... required) {
for (State state : required) {
if (this.state == state) {
return;
}
}
throw new IllegalStateException(
sm.getString("wsRemoteEndpoint.wrongState", this.state));
}
Я не ожидал, что sendBinary бросить это исключение, поскольку основанный на java doc:
sendBinary недействительные (данные ByteBuffer, обработчик SendHandler) sendBinary
Throws: IllegalArgumentException - если данные или обработчик равны нулю.
Так что, похоже, что проверки выполнения Tomcat, чтобы увидеть, если состояние open
или нет в this code:
public synchronized void binaryStart() {
checkState(State.OPEN);
state = State.BINARY_FULL_WRITING;
}
и если это не open
то выбросит это исключение.
Интересно отметить, что при java doc для RemoteEndpoint.Basic
(не RemoteEndpoint.Async
) мы читаем:
Если соединение WebSocket, лежащее в основе этой RemoteEndpoint занято посылает сообщение, когда вызов сделан, чтобы отправить еще один, например, , если два потока попытаются вызвать метод отправки одновременно или если разработчик пытается отправить новое сообщение, находясь в середине , отправляя существующий, метод отправки, вызываемый, когда соединение уже занято, может IllegalStateException.
Нет такого абзаца для RemoteEndpoint.Async
!
ТЕПЕРЬ ВОПРОС
Разве это не приемлемо вызывать RemoteEndpoint.Async.sendBinary
на сессии, а что-то еще пишет в той же сессии?
Если это не приемлемо, как проверить состояние удаленной конечной точки, прежде чем пытаться ее написать!
Update 1:
Похоже, что там было в discussion вокруг того же вопроса на java.net.
Update 2:
Ссылка на аналогичную bug report на апач Bugzilla.