Подтвердить что ты не робот

Подключение к Stomp через WebSockets, реализованное с помощью Spring 4 из Java-клиента

Я получил веб-приложение, реализованное с помощью Spring, используя STOMP через WebSockets Messaging, аналогично описанному здесь (с RabbitMQ на бэкэнд). Он работает на Tomcat, и я могу подключиться к приложению, используя обычные URL-адреса (например, http://host/server/). Мне также был предоставлен демо-клиент - страница JSPX, в которой используются Web-узлы Modernizr и SockJS. Код подключения в демо-клиенте выглядит следующим образом:

if (Modernizr.websockets) {
    socket = new WebSocket('ws://host/server/endpointx');
}
else {
    socket = new SockJS('/server/endpointy');
}

stompClient = Stomp.over(socket);
stompClient.connect(headers, function(frame) { ... });
....

Демо-клиент отлично работает (когда я загружаю JSPX-страницу в браузере, я могу подключиться к серверу). Но моя цель - подключиться к одному серверу с помощью некоторой библиотеки Java STOMP. Проблема в том, что библиотеки, которые я пробовал, требуют хост и порт как параметры подключения: например, с помощью ActiveMQ Stomp библиотека:

StompConnection connection = new StompConnection();
connection.open("host", port);
connection.connect(new HashMap<String, String>());

Если я укажу port как 61613, соединение будет успешным, но я сразу же удалю RabbitMQ, а не мой сервер (это не то, что я хочу). Если я укажу 8080 (или 80), при подключении я получаю сообщение об ошибке

java.io.EOFException     в java.io.DataInputStream.readByte(Неизвестный источник)     at org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:137)     на org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:77)     на org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:68)     at org.apache.activemq.transport.stomp.StompConnection.connect(StompConnection.java:139)     at.... stomp.impl.activemq.ActiveMQStompDriver.connect(ActiveMQStompDriver.java:39)     ... еще 25

и трассировка показывает, что это связано с тем, что кадр CONNECT никогда не получает ожидаемый кадр CONNECTED (на самом деле он ничего не получает).

Итак, я озадачен: я использую неправильный порт? или иметь дело с некоторой несовместимостью библиотеки? или мне нужно каким-то образом указать Tomcat, что я хочу обновить HTTP-соединение с WebSockets?

Если вышеуказанный вопрос трудно ответить, то это одинаково полезно: как подключиться к приложению Spring с помощью STOMP через канал обмена сообщениями WebSockets, запущенный на Tomcat, с помощью Java?

4b9b3361

Ответ 1

Я получил веб-приложение, реализованное с помощью Spring, с помощью STOMP через WebSockets Messaging, похожее на то, что описано здесь (с RabbitMQ на бэкэнд). Он работает на Tomcat, и я могу подключиться к приложению, используя обычные URL-адреса (например, http://host/server/).

Это только для справки позже в ответе:

Browser -> WebSocket -> Spring STOMP Broker Relay -> RabbitMQ

Рабочий пример создает клиент Javscript в браузере конечного пользователя. Он подключается через WebSockets к вашему серверу Tomcat и ретранслятору Spring STOMP Broker Relay в вашем приложении. Реле, как следует из его названия, передает сообщения STOMP, полученные через WebSocket, в фактический сокет, который подключен к RabbitMQ (также через STOMP).

Мне также был предоставлен демо-клиент - страница JSPX, в которой используются Web-узлы Modernizr и SockJS.

Не относится к ответу, но вам не нужно проверять, поддерживаются ли WebSockets в клиентском браузере. SockJS сделает это за вас и автоматически выбирает лучший канал для использования. В любом современном браузере не за ограничительным прокси-сервером это будут WebSockets.

Но моя цель - подключиться к одному серверу с помощью некоторой библиотеки Java STOMP. Проблема в том, что библиотеки, которые я пробовал, требуют хоста и порта в качестве параметров подключения

Я сомневаюсь, что клиент Java STOMP будет разработан для работы в этом сценарии (хотя все возможно). Обычно клиент Java STOMP будет запускать серверную часть или где-то, что он просто подключится непосредственно к серверу STOMP, в вашем случае это будет означать подключение напрямую к RabbitMQ.

Вы упомянули, что можете напрямую подключиться к Кролику, так что это будет одно из возможных решений здесь (вы сказали, что не хотите этого делать, но не почему, не стесняйтесь прояснить этот момент в комментарии). Если ваш код работает на стороне сервера, то это, безусловно, путь. Переход через канал WebSocket и брокерское реле Spring просто добавит дополнительный перехват и ненужную задержку.

Другим решением будет использование Java-клиента, который может общаться через WebSockets и STOMP. Я бы рекомендовал это, только если ваш Java-код работает как удаленный клиент где-то, и у него не будет доступа к разговору напрямую с RabbitMQ.

Итак, я озадачен: я использую неправильный порт? или иметь дело с некоторой несовместимостью библиотеки? или мне нужно каким-то образом указать Tomcat, что я хочу обновить HTTP-соединение с WebSockets?

61613 - это правильный порт для непосредственного общения с RabbitMQ, если это то, что вы хотите сделать. Порт для установки соединения WebSocket - это только стандартный HTTP или HTTPS-порт, на котором Tomcat прослушивает подключения (по умолчанию будет 8080/8443). Вы не можете говорить STOMP напрямую с Tomcat, он не понимает этот протокол. Вы должны инициировать подключение к WebSocket, а затем поговорить с STOMP в своем приложении (т.е. Ретранслятор бета-версии STOMP Spring).

Для этого вам нужен клиент, который знает, как говорить с WebSocket и клиентом, который может говорить STOMP по каналу WebSocket. Ваш текущий клиент пытается сделать регулярное подключение сокетов к Tomcat, а не к соединению WebSocket. Чтобы быть успешным, необходимо сначала инициировать соединение с WebSocket, а затем отправлять сообщения STOMP через соединение WebSocket.

Когда ваша демонстрация запускается в браузере, соединение WebSocket обрабатывается вашим браузером и SockJS, а ваш клиент Javascript STOMP разговаривает через соединение WebSocket с приложением через STOMP (см. диаграмму ASCII выше).

Если вышеуказанный вопрос трудно ответить, то это одинаково полезно: как подключиться к приложению Spring с помощью STOMP через канал обмена сообщениями WebSockets, запущенный на Tomcat, с помощью Java?

Я не думаю, что вы, как правило, хотите это сделать. Если у вас есть Java-код, запущенный на Tomcat, было бы более эффективно напрямую подключаться к RabbitMQ (т.е. Вашему серверу STOMP) с вашим клиентом Java STOMP.

STOMP поверх WebSockets в основном заключается в том, что удаленные и удаленные клиенты на базе браузера могут легко и безопасно подключать и отправлять сообщения без прямого доступа к вашему серверу RabbitMQ.

Надеюсь, что это поможет!