spring websocket что это
Spring Websocket на примере онлайн чата
Сегодня будет практичная но очень интересная тема: использование Websocket в Spring Boot приложении на примере онлайн чата.
Очень часто бывает необходимым получать данные с сервера без перезагрузки страницы. Для этого используют технологию AJAX. Но что делать если клиент не знает, когда будет ответ от сервера?
Можно например делать запрос на сервер каждые несколько секунд и смотреть — готов ли сервер дать нам информацию. Такой подход не самое хорошее решение. Особенно когда речь заходит об высоконагруженных системах с большим количеством пользователей. Тогда на помощь приходят веб сокеты.
Использование технологии веб сокетов без сторонних фреймворков или библиотек — занятие не самое удобное. Поэтому в данной статье мы рассмотрим Spring Websocket с библиотекой StompJS. Ведь нужно будет не только передавать сообщения с сервера, но и принимать их на клиенте.
На примерах все выглядит значительно проще, чем в теории. Современное программирование стало настолько простым, что скоро Вам нужно будет нажимать Ctrl+Space и Eclipse будет сам писать код))
Первое что нужно сделать — создать простое Spring Boot приложение. Далее нужно добавить необходимые зависимости для веб сокетов:
Для серверной части этого достаточно.
Напишем настройки для WebSocket:
Не пугаться. Здесь все просто. Аннотация @Configuration говорит, что это конфигурационный класс спринг приложения. @EnableWebSocketMessageBroker — указывает, что мы разрешаем работу с веб сокетами. Далее в методе configureMessageBroker мы указываем префиксы и адреса нашего веб сокет эндпоинта. В registerStompEndpoints подключается конечный адрес, по котором мы будем слушать и передавать сообщения. .withSockJS() — говорит, что будет использоваться библиотека SockJS которая является оберткой для стандартных веб сокетов и обеспечивает более удобное их использование.
Это все настройки, которые нужны для передачи сообщение по Websocket.
Для того, чтобы приложение слушало входящие сообщения и посылало исходящие, необходимо воспользоваться контроллером, который мы привыкли видеть в Spring MVC приложениях. Только вместо аннотаций @GetMapping и т.д. Нужно воспользоваться аннотациями, которые предназначены для Spring Websocket:
@MessageMapping — урл, по которому будет слушать наш сервер. @SendTo — урл, куда он отправит сообщение. Message — простой объект:
Можно передавать как объекты, так и список объектов. Можно просто строки или числа передавать. Здесь разницы нет. Для наглядности и предметной области я создал простой объект в которого только два поля: from — будет содержать имя адресата и message — само сообщение.
Вы же можете изменить объект как только пожелаете.
Это все, что касается серверной части. Если запустить приложение — оно будет слушать входящие сообщения и как только поймает хоть одно — сразу отправит его на клиент.
На этом можно было бы и закончить статью, но как по мне — нужно увидеть приложение в действии.
Давайте напишем клиентскую часть. Будет использовано HTML, CSS, Javascript, JQuery. Если Вы не знакомы с этими технологиями и языками программирования — не спешите закрывать статью. Код будет максимально понятным и простым. Для подключения необходимых библиотек, вместо того, чтобы качать я подключу их через Maven.
Для полноценной работы с веб сокетами мне нужны быблиотеки:
Для оформления и стилизации кода я подключу bootstrap и jquery.
Мой полный файл pom.xml теперь выглядит так:
Для того, чтобы подключиться к веб сокетам на сервере нужно создать экземпляр класса SockJS: var socket = new SockJS ( ‘ /chat-messaging ‘ );
Чтобы не мучить Вас утомительными комментариями даю полный код клиентской части. Файл script.js имеет вид:
После того, как мы создали stompClient — вызывается метод connect в котором клиент подписывается на урл /chat/messages. Таким образом он будет слушать все, что придет по этому адресу без перезагрузки страницы. С информацией, которая придет от сервера можно делать все что угодно. В данном случае я ее распарсиваю var data = JSON.parse(response.body); и передаю в метод draw(«left», data.message);.
Метод draw нас в этой теме не интересует. Он выполняет функцию красивого наполнения странички информацией. Более интересен метод sendMessage. Когда он вызывается — идет отправление сообщение по адресу /app/message. Если Вы вернетесь к Java коду то увидите, что app — это destination prefix (смотримWebSocketConfiguration), а message конечный адрес, по котором слушает контроллер.
Для полноты картины я добавлю код файла index.html в который подключен наш script.js:
Стили оформления CSS файл style.css:
Эти файлы нужно поместить в src/main/resources/static тогда Spring Boot будет по умолчанию открывать файл index.html в котором и будет наш чат с подключенными стилями и js.
Ну а теперь сама работа приложения:
Я записал видео с пошаговыми инструкциями создания приложение на Spring Websocket. Можете посмотреть его, если все еще не понятно, как сделать чат на веб сокетах:
Это все, что касается Spring Websocket. Тема очень обширная и интересная. Указанный пример не единственный способ работы с данным фреймворком. В нем есть еще очень много полезных методов, которым можно передавать информацию с сервера на клиент и обратно.
Чат на Spring Boot и WebSocket
В этой статье мы напишем простой чат с использованием Spring Boot и Websocket.
Готовый чат можно попробовать тут https://spring-ws-chat.herokuapp.com/. Если там никого нет, то просто откройте приложение на двух вкладках браузера, войдите под разными именами и пишите.
Как выглядит чат
Что такое Websocket
Websocket — протокол, который позволяет устанавливать двустороннюю связь между клиентом и сервером.
Переключение на Websocket происходит после специального http-запроса от клиента. Чтобы переключиться на вебсокет, клиент высылает в качестве одного из заголовков http-запроса:
Если сервер поддерживает вебсокеты, то он отвечает «да», и дальше общение идет по протоколу Websocket. Он не имеет ничего общего с протоколом http, хотя они оба — протоколы самого верхнего уровня Application в системе протоколов OSI, но просто они разные.
Большинство браузеров поддерживают протокол Websocket.
Итак, перейдем к примеру.
Создание приложения
Сначала создадим шаблон проекта с помощью сайта-инициализатора:
Далее разархивируем и импортируем проект в редактор как проект Maven:
Тут на картинке у нас уже созданы дополнительно три пакета — config, controller и model, они нам понадобятся.
Настройка Websocket
Итак, первым делом надо настроить конечную точку и брокер сообщений. Все это сделано в пакете конфигурации config, его надо предварительно создать.
Аннотация @Configuration необходима, как известно, в любом классе конфигурации Spring.
Аннотация @EnableWebSocketMessageBroker включает Websocket сервер. Обратите внимание, мы реализуем интерфейс WebSocketMessageBrokerConfigurer и переопределяем два из его default-методов.
В первом методе registerStompEndpoints() мы регистрируем конечную точку, которую клиенты будут использовать, чтобы подключиться к нашему Websocket-серверу. SockJS — для браузеров, которые не поддерживают Websocket.
Обратите внимание на Stomp в названии метода. STOMP — это Simple Text Oriented Messaging Protocol. Это протокол обмена сообщениями, задающий формат и правила обмена.
Зачем нужен Stomp? Дело в том, что сам по себе WebSocket не дает таких вещей (более высокого уровня), как отправка сообщений пользователям, подписанным на тему, или отправка сообщений конкретному пользователю.
Во втором методе configureMessageBroker() мы настраиваем брокер сообщений, который будет использоваться для направления сообщений от одного клиента к другому.
В первой строке мы говорим, что сообщения, чей адрес (куда отправлены) начинается с «/app«, должны быть направлены в методы, занимающиеся обработкой сообщений.
Во второй строке мы говорим, что сообщения, чей адрес начинается с «/topic«, должны быть направлены в брокер сообщений. Брокер перенаправляет сообщения всем клиентам, подписанным на тему.
В примере у нас используется встроенный брокер, но можно использовать и полноценный брокер, такой как RabbitMQ или ActiveMQ.
Модель сообщения
Далее надо создать пакет model, а в нем класс ChatMessage:
Создание контроллера для отправки и получения сообщений
Теперь создадим пакет controller и класс ChatController. В классе ChatController есть методы, отвечающие за получение сообщения от одного клиента и трансляцию его всем остальным. Добавление пользователя и его сообщения транслируются всем, кто подключен к чату:
Как вы помните, в конфигурации мы указали, что все сообщения от клиентов, направленные по адресу, начинающемуся с /app, будут перенаправлены в соответствующие методы. Имелись в виду как раз методы, аннотированные @MessageMapping.
Например, сообщение, направленное по адресу /app/chat.sendMessage будет перенаправлено в метод sendMessage(). А например, сообщение, направленное по адресу/app/chat.addUser будет перенаправлено в метод addUser().
Создание WebSocket Event listeners
Здесь мы слушаем события соединения с сервером и отсоединения. Это нужно для того, чтобы логировать эти события и передавать в чат на всеобщее обозрение. Так все видят, когда кто-то заходит в чат и выходит из него.
Кстати, вход в чат мы уже обрабатываем в методе addUser() в ChatController, так что в SessionConnectedEvent ничего делать не нужно.
А в SessionDisconnectEvent мы извлекаем имя пользователя из сессии и транслируем его всем.
Создание Front-End
Теперь надо создать статику, и хотя это уже не Java, без нее приложение не заработает.
Для начала создадим папку static в src/main/resources. Впрочем, чтобы не расписывать все по кусочкам, вот вам структура папок файлов целиком:
Создание HTML — файл index.html
Обратите внимание, что в файл включены библиотеки sockjs и stomp.
JavaScript — main.js
Теперь давайте добавим Javascript-код. Он необходим для соединения с конечной точкой и отправки/получения сообщений.
Для начала его скопируйте в файл main.js, а ниже мы рассмотрим, что он делает.
Функция connect() использует SockJS и клиент Stomp, чтобы подключиться к конечной точке /ws, которую мы настроили выше в Spring Boot.
После успешного подключения, клиент подписывается на адрес /topic/public и сообщает серверу имя пользователя по адресу /app/chat.addUser.
Функция stompClient.subscribe() принимает аргументом callback-функцию, которая вызывается каждый раз, когда в тему приходит сообщение.
Добавим стили CSS — main.css
Наконец, внешний вид приложения задается тут:
Запуск приложения
Все готово, теперь приложение можно запускать — запускаем сгенерированный Spring Boot-ом файл с функцией main в корне иерархии папок.
Запустится веб-сервер, и можно переходить по адресу http://localhost:8080 и наслаждаться работающим чатом.
Использование брокера RabbitMQ
Если вы не хотите пользоваться встроенным брокером, а хотите подключить полноценный, то в зависимости Maven надо добавить:
Использование WebSocket для создания интерактивных web-приложений
В этом уроке освещается процесс создания «hello world» приложения, которое отправляет сообщения назад и вперед, между сервером и браузером. WebSocket является очень тонким и легковесным слоем над TCP. Это делает его очень подходящим при использования «подпротоколов» для вставки сообщений. В этом уроке мы изучим и используем обмен сообщений через STOMP c использованием Spring для создания интерактивного web приложения.
Что вы создадите
Вы создадите сервер, который будет принимать сообщение, содержащее имя пользователя. В ответ, он будет отправлять приветствие в очередь, на которую подписан клиент.
Что вам потребуется
Как проходить этот урок
Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.
Чтобы начать с нуля, перейдите в Настройка проекта.
Настройка проекта
Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.
Создание структуры каталогов
Создание файла сборки Gradle
Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.
Spring Boot gradle plugin предоставляет множество удобных возможностей:
Создание класса представления ресурса
Теперь, когда вы настроили проект, вы можете создать ваш STOMP сервис сообщений.
Начнем с процесса взаимодействия с сервисом.
Сервис будет принимать содержащие имя STOMP сообщения, тела которых представляют собой в JSON объекты:
Чтобы смоделировать сообщение, содержащее имя, вы можете создать POJO с полем name и соответствующим методом getName() :
После получения сообщения и извлечении имени, сервис создаст на его основе приветствие и опубликует его в отдельной очереди, на которую подписан клиент. Приветствие также будет в форме JSON объекта, который выглядит примерно так:
Чтобы смоделировать представление приветствия, вы добавляете другой POJO с полем content и соответствующим методом getContent() :
Spring будет использовать библиотеку Jackson JSON для автоматической упаковки экземпляров типа Greeting в JSON.
Далее вы создадите контроллер для приема hello сообщения и отправки сообщения приветствия.
Создание контроллера обработки сообщения
контроллер краток и прост, но там много чего происходит. Давайте подробнее рассмотрим шаг за шагом.
Внутри реализации метода симулируется обработка сообщения, останавливая поток выполнения на три секунды. Это демонстрирует, что после того, как клиент отправил сообщение, серверу понадобится сколь угодно много времени для обработки сообщения асинхронно. Клиент может продолжить свою работу без необходимости ожидания ответа.
Настройка Spring для STOMP обмена сообщениями
Теперь, когда основные компоненты сервиса созданы, вы можете настроить Spring, чтобы включить WEbSocket и обмен сообщениями по STOMP.
Создайте Java класс WebSocketConfig как показано ниже:
Создание браузерного клиента
Серверная часть на месте, теперь давайте обратим наше внимание на Javascript клиент, который будет отправлять сообщения к и получать от сервера. Создайте index.html, как показано ниже:
Функция sendName() получает имя, введенное пользователем и используется STOMP клиентом для отправки к /app/hello (а GreetingController.greeting() получит его).
Создание приложения исполняемым
Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и WAR файлов, более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение. Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый старый main() Java-метод. Попутно, вы используете поддержку Spring для встроенного Tomcat контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.
Сборка исполняемого JAR
Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.
Затем вы можете запустить JAR-файл:
Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:
Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:
Сервис должен быть поднят и запущен через несколько секунд.
Тестирование сервиса
Теперь, когда сервис поднят и запущен, зайдите по адресу http://localhost:8080 и нажмите кнопку «Connect».
после открытия соединения вас попросят ввести свое имя. Введите его и нажмите кнопку «Send». Ваше имя отправится серверу как JSON сообщение поверх STOMP. После 3-х секундной задержки сервер отправит обратно сообщение с «Hello» приветствием, которое отобразится на странице. На данном этапе вы можете отправить другое имя или нажать на кнопку «Disconnect» для закрытия соединения.
Поздравляем! Вы только что разработали STOMP-сервис обмена сообщениями, используя Spring.
Введение в WebSockets с Spring
Краткое введение в использование WebSockets с Spring от клиента JS.
1. Обзор
Типичным примером использования может быть, когда приложение включает в себя несколько пользователей, общающихся друг с другом, например, в чате. В нашем примере мы построим простой чат-клиент.
2. Зависимости Maven
Поскольку это проект на основе Maven, мы сначала добавим необходимые зависимости в pom.xml :
3. Включите WebSocket весной
Как следует из его названия, он позволяет обрабатывать сообщения WebSocket при поддержке брокера сообщений:
W e завершите нашу простую конфигурацию, указав префикс “/app” для фильтрации назначений, ориентированных на аннотированные методы приложения (через @MessageMapping ).
Он также включает SockJS резервные опции, чтобы можно было использовать альтернативные варианты обмена сообщениями, если веб-сайты недоступны. Это полезно, так как WebSocket еще не поддерживается во всех браузерах и может быть исключен ограничительными сетевыми прокси-серверами.
Резервные варианты позволяют приложениям использовать API WebSocket, но при необходимости во время выполнения изящно деградируют до альтернатив, отличных от WebSocket.
4. Создайте модель сообщения
Теперь, когда мы настроили проект и настроили возможности WebSocket, нам нужно создать сообщение для отправки.
Сообщение может выглядеть следующим образом:
Чтобы смоделировать сообщение, несущее текст, мы можем создать простой объект Java со свойствами from и text :
По умолчанию Spring будет использовать библиотеку Jackson для преобразования нашего объекта модели в JSON и из него.
5. Создайте контроллер обработки сообщений
Связь между конечной точкой и контроллером дает нам возможность обрабатывать сообщение при необходимости:
6. Создайте клиент браузера
После создания наших конфигураций на стороне сервера мы будем использовать sockjs-клиент библиотеку для создания простой HTML-страницы, которая взаимодействует с нашей системой обмена сообщениями.
Прежде всего, нам нужно импортировать клиентские библиотеки sockjs и stomp Javascript. Затем мы можем создать функцию connect() для открытия связи с нашей конечной точкой, функцию SendMessage() для отправки сообщения STOMP и функцию disconnect() для закрытия связи:
7. Тестирование примера
Чтобы проверить наш пример, мы можем открыть несколько окон браузера и получить доступ к странице чата по адресу:
Как только это будет сделано, мы сможем присоединиться к чату, введя ник и нажав кнопку подключения. Если мы составим и отправим сообщение, мы сможем увидеть его во всех сеансах браузера, которые присоединились к чату.
Взгляните на скриншот, чтобы увидеть пример:
8. Заключение
В этом уроке мы изучили Поддержку WebSocket Spring. Мы видели его конфигурацию на стороне сервера и построили простой клиентский аналог | с использованием библиотек sockjs и stomp Javascript.
Пишем чат с использованием Spring Boot и WebSockets
Всем привет. В преддверии старта курса «Разработчик на Spring Framework» мы подготовили для вас еще один полезный перевод. Но, прежде чем перейти к статье, хотим поделиться с вами бесплатной записью урока от наших преподавателей по теме: «Рефакторинг кода приложений на Spring», а также предлагаем посмотреть запись вебинара из которого вы сможете подробно узнать о программе курса и формате обучения.
А теперь перейдем к статье
В статье Building Scalable Facebook-like Notification using Server-Sent Event and Redis для отправки сообщений от сервера клиенту мы использовали Server-sent Events. Также там было упомянуто о WebSocket — технологии двунаправленной связи между сервером и клиентом.
В этой статье мы посмотрим на один из распространенных примеров использования WebSocket. Мы напишем приложение для обмена приватными сообщениями.
Ниже на видео продемонстрировано то, что мы собираемся сделать.
Введение в WebSockets и STOMP
WebSocket — это протокол для двусторонней связи между сервером и клиентом.
WebSocket, в отличие от HTTP, протокола прикладного уровня, является протоколом транспортного уровня (TCP). Хотя для первоначальной установки соединения используется HTTP, но потом соединение «обновляется» до TCP-соединения, используемого в WebSocket.
WebSocket — протокол низкого уровня, который не определяет форматы сообщений. Поэтому WebSocket RFC определяет подпротоколы, описывающие структуру и стандарты сообщений. Мы будем использовать STOMP поверх WebSockets (STOMP over WebSockets).
Протокол STOMP (Simple / Streaming Text Oriented Message Protocol) определяет правила обмена сообщениями между сервером и клиентом.
STOMP похож на HTTP и работает поверх TCP, используя следующие команды:
Архитектура
Модель сообщения
Первое, о чем нужно подумать — это модель сообщения. ChatMessage выглядит следующим образом:
Класс ChatMessage довольно простой, с полями, необходимыми для идентификации отправителя и получателя.
В нем также есть поле статуса, указывающее доставлено ли сообщение клиенту.
Когда сервер получает сообщение из чата, он не отправляет сообщение адресату напрямую, а отправляет уведомление (ChatNotification), чтобы оповестить клиента о получении нового сообщения. После этого клиент сам может получить новое сообщение. Как только клиент получит сообщение, оно помечается как доставленное (DELIVERED).
Уведомление выглядит следующим образом:
В уведомлении есть идентификатор нового сообщения и информация об отправителе для того, чтобы клиент мог показать информацию о новом сообщении или о количестве новых сообщений, как показано ниже.
Настройка WebSocket и STOMP в Spring
Первым делом настраиваем конечную точку STOMP и брокер сообщений.
Последний метод настраивает конвертер JSON, который используется Spring’ом для преобразования сообщений из/в JSON.
Контроллер для обработки сообщений
В этом разделе мы создадим контроллер, который будет обрабатывать запросы. Он будет получать сообщение от пользователя и отправлять его получателю.
Этот метод сохраняет сообщение в MongoDB, а затем вызывает метод convertAndSendToUser для отправки уведомления адресату.
Все подписчики данного адреса (в нашем случае один) получат сообщение.
Генерация chatId
Класс ChatRoom выглядит следующим образом:
JavaScript-клиент
В этом разделе мы создадим JavaScript-клиента, который будет отправлять сообщения на WebSocket/STOMP-сервер и получать их оттуда.
Мы будем использовать SockJS и Stomp.js для общения с сервером с использованием STOMP over WebSocket.
Метод onConnected() подписывается на определенный адрес и получает все отправляемые туда сообщения.
Заключение
В этой статье мы рассмотрели все важные моменты создания чата с использованием Spring Boot и STOMP over WebSocket.