1. введение
HTTP (протокол передачи гипертекста)-это протокол запроса-ответа без состояния. Его простой дизайн делает его очень масштабируемым, но непригодным и неэффективным для высокоинтерактивных веб-приложений в реальном времени из-за большого объема накладных расходов, которые необходимо передавать вместе с каждым запросом/ответом.
Поскольку HTTP является синхронным, а приложения реального времени должны быть асинхронными, любые решения, такие как опрос или длительный опрос ( Comet ), как правило, сложны и неэффективны.
Для решения указанной выше проблемы нам нужен основанный на стандартах, двунаправленный и полнодуплексный протокол, который мог бы использоваться как серверами, так и клиентами, и это привело к введению JSR 356 API -в этой статье мы покажем пример его использования.
2. Настройка
Давайте включим зависимости Spring WebSocket в наш проект:
org.springframework spring-websocket 5.2.2.RELEASE org.springframework spring-messaging 5.2.2.RELEASE
Мы всегда можем получить последние версии зависимостей от Maven Central для spring-websocket и spring-messaging .
3. ТОПАТЬ
Потоковый текстовый протокол обмена сообщениями (STOMP)-это простой, совместимый проводной формат, который позволяет клиенту и серверам взаимодействовать почти со всеми брокерами сообщений. Это альтернатива AMQP (Advanced Message Queuing Protocol) и JMS (Java Messaging Service).
STOMP определяет протокол для взаимодействия клиента и сервера с использованием семантики обмена сообщениями. Семантика находится поверх WebSockets и определяет фреймы, которые сопоставляются с фреймами WebSockets.
Использование STOMP дает нам гибкость при разработке клиентов и серверов на разных языках программирования. В этом текущем примере мы будем использовать STOMP для обмена сообщениями между клиентом и сервером.
4. Сервер WebSocket
Вы можете прочитать больше о создании серверов WebSocket в этой статье .
5. Клиент WebSocket
Для связи с сервером WebSocket клиент должен инициировать соединение WebSocket, отправив HTTP-запрос на сервер с правильно установленным заголовком Upgrade :
GET ws://websocket.example.com/ HTTP/1.1 Origin: http://example.com Connection: Upgrade Host: websocket.example.com Upgrade: websocket
Пожалуйста, обратите внимание, что URL-адреса WebSocket используют схемы ws и wss , вторая означает безопасные WebSocket.
Сервер отвечает, отправляя заголовок Upgrade в ответе, если включена поддержка WebSockets.
HTTP/1.1 101 WebSocket Protocol Handshake Date: Wed, 16 Oct 2013 10:07:34 GMT Connection: Upgrade Upgrade: WebSocket
Как только этот процесс (также известный как рукопожатие WebSocket) завершен, начальное HTTP-соединение заменяется подключением WebSocket поверх того же TCP/IP-соединения, после чего обе стороны могут обмениваться данными.
Это соединение на стороне клиента инициируется экземпляром WebSocketStompClient .
5.1. WebSocketStompClient
Как описано в разделе 3, сначала нам нужно установить соединение с WebSocket, и это делается с помощью WebSocketClient class.
Клиент WebSocket можно настроить с помощью:
- StandardWebSocketClient предоставляется любой реализацией JSR-356, такой как Tyrus
- Клиент Jetty WebSocket предоставляется Jetty 9+ native WebSocket API
- Любая реализация Spring’s WebSocketClient
В нашем примере мы будем использовать StandardWebSocketClient , реализацию клиента WebSocket :
WebSocketClient client = new StandardWebSocketClient(); WebSocketStompClient stompClient = new WebSocketStompClient(client); stompClient.setMessageConverter(new MappingJackson2MessageConverter()); StompSessionHandler sessionHandler = new MyStompSessionHandler(); stompClient.connect(URL, sessionHandler); new Scanner(System.in).nextLine(); // Don't close immediately.
По умолчанию WebSocketStompClient поддерживает SimpleMessageConverter . Поскольку мы имеем дело с сообщениями JSON, мы устанавливаем преобразователь сообщений в MappingJackson2MessageConverter , чтобы преобразовать полезную нагрузку JSON в объект.
При подключении к конечной точке мы передаем экземпляр обработчика сеанса Stomp , который обрабатывает такие события , как afterConnected и handleFrame .
Если ваш сервер поддерживает SockJS, мы можем изменить клиент, чтобы использовать SockJS Client вместо StandardWebSocketClient.
5.2. Обработчик сеанса Stomp
Мы можем использовать сеанс Stomp для подписки на тему WebSocket. Это можно сделать, создав экземпляр Stomp SessionHandlerAdapter , который, в свою очередь, реализует StompSessionHandler .
Обработчик сеанса STOMP предоставляет события жизненного цикла для сеанса STOMP. События включают обратный вызов при установлении сеанса и уведомления в случае сбоев.
Как только клиент WebSocket подключается к конечной точке, уведомляется обработчик сеанса Stomp и вызывается метод after Connected () , в котором мы используем StompSession для подписки на тему:
@Override public void afterConnected( StompSession session, StompHeaders connectedHeaders) { session.subscribe("/topic/messages", this); session.send("/app/chat", getSampleMessage()); } @Override public void handleFrame(StompHeaders headers, Object payload) { Message msg = (Message) payload; logger.info("Received : " + msg.getText()+ " from : " + msg.getFrom()); }
Убедитесь, что сервер WebSocket запущен и работает клиент, сообщение будет отображаться на консоли:
INFO o.b.w.client.MyStompSessionHandler - New session established : 53b993eb-7ad6-4470-dd80-c4cfdab7f2ba INFO o.b.w.client.MyStompSessionHandler - Subscribed to /topic/messages INFO o.b.w.client.MyStompSessionHandler - Message sent to websocket server INFO o.b.w.client.MyStompSessionHandler - Received : Howdy!! from : Nicky
6. Заключение
В этом кратком руководстве мы реализовали клиент WebSocket на основе Spring.
Полная реализация может быть найдена на GitHub .