Spring websocket что это
Введение в 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 Websocket + SockJs. How it works?
Доброго времени суток уважаемые хабравчане. В данной статье хочу продолжить рассказ устройства Spring Websocket, рассмотрев серверную реализацию Spring Websocket + SockJs.
SockJs — это JavaScript библиотека, которая обеспечивает двусторонний междоменный канал связи между клиентом и сервером. Другими словами SockJs имитирует WebSocket API. Под капотом SockJS сначала пытается использовать нативную реализацию WebSocket API. Если это не удается, используются различные транспортные протоколы, специфичные для браузера, и представляет их через абстракции, подобные WebSocket. Про порт данной библиотеки в мир Spring Frameworks мы сегодня и поговорим.
Использование Websocket и SockJs доступно в Spring с версии 4.0.
На данный момент, в зависимости от браузера, SockJs может использовать следующие транспортные протоколы:
Browser | Websockets | Streaming | Polling |
---|---|---|---|
IE 6, 7 | no | no | jsonp-polling |
IE 8, 9 (cookies=no) | no | xdr-streaming * | xdr-polling * |
IE 8, 9 (cookies=yes) | no | iframe-htmlfile | iframe-xhr-polling |
IE 10 | rfc6455 | xhr-streaming | xhr-polling |
Chrome 6-13 | hixie-76 | xhr-streaming | xhr-polling |
Chrome 14+ | hybi-10 / rfc6455 | xhr-streaming | xhr-polling |
Firefox Пример использования частичной загрузкиEventSourceВ качестве реализации данного протокола на клиентской стороне используется объект EventSource. Данный объект предназначен для передачи текстовых сообщений используя Http. Главным преимуществом данного подхода является автоматическое переподключение и наличие идентификаторов сообщения для возобновления потока данных. IFrameИдея использования IFrame заключается в возможности последовательной обработки страницы по мере загрузки данных из сервера. Схема взаимодействия довольно проста — создается скрытых IFrame, идет запрос на сервер, который возвращает шапку документа и держит соединение. Каждый раз когда появляются новые данные сервер обрамляет их в тег script и отправляет в IFrame. IFrame получив новый блок script начнет его выполнение. HtmlFileДанный подход используется в IE и заключается в оборачивании IFrame в объект ActiveX. А основное преимущество использования — сокрытие действий в IFrame от пользователя. Структура SockJsИерархия транспортных обработчиковИерархия сессийСоздание конфигурационного классаРеализацию метода withSockJS() можно увидеть в классе AbstractWebSocketHandlerRegistration. Основная задача данного метода создать фабрику SockJsServiceRegistration, из которой создается главный класс обработки Http запросов SockJsService. После создания экземпляра SockJsService происходит связывание данного сервиса с WebSocketHandler и преобразование в HandlerMapping. Адаптером в данном случае выступает класс SockJsHttpRequestHandler. При создании экземпляра SockJsService в него передается планировщик задач (TaskScheduler), который в дальнейшем будет использоваться для отсылки Heartbeat сообщений. В качестве кодека преобразования сообщений по умолчанию используется Jackson2SockJsMessageCodec Для подключения SockJs на клиентской стороне необходимо добавить javascript библиотеку, и создать SockJS объект, при этом изменив протокол нашего endpoint с ws(wss) на http(https) Описание алгоритма взаимодействияРабота начинается с клиентского запроса /info, в ответ на который сервер возвращает объект вида который указывает на доступные url для обработки клиентских запросов. необходимы ли куки и есть ли возможность использовать webSocket. На основании этих данных клиентская библиотека выбирает транспортный протокол. Все клиентские запросы имеют вид Для поддержания совместимости с Websocket Api SockJs использует кастомный протокол обмена сообщениями: Пример fallbackРассмотрим пример когда у нас на сервере нет возможности обработать Websocket, сделать это довольно просто, установив переменную webSocketEnabled в false в классе SockJsServiceRegistration Клиент проверит возможность открытия сокета вызовом /info. Получив негативный ответ, будут использоваться два канала для обмена сообщениями: один для приема сообщений — как правило streaming протокол, и один для отправки сообщений на сервер (http запросы). Данные каналы коммуникации будут связываться одной sessionId передаваемой в URL. При отправке сообщения с клиента запрос попадает на DispatcherServlet, от куда перенаправляется на наш адаптер SockJsHttpRequestHandler. Данный класс преобразовывает запрос и перенаправляет его в SockJsService, который делегирует функцию принятия сообщения на пользовательскую сессию SockJsSession. А так как наша сессия связана к обработчиком WebSocketHandler мы получаем отправленное сообщение в нашем обработчике. Для отправки сообщения клиенту, мы по прежнему используем WebSocketSession. Дело в том что SockJsSession является расширением WebSocketSession. А конкретные реализации SockJsSession привязаны к транспортному протокому. Поэтому на серверной стороне при вызове session.sendMessage(new TextMessage(«some message»)); происходит преобразование сообщения к конкретному типу протокола и отправка форматированного сообщения к клиенту. Вот, собственно, и вся магия возможности fallback при использовании SockJs. Использование 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. Spring Websocket на примере онлайн чатаСегодня будет практичная но очень интересная тема: использование Websocket в Spring Boot приложении на примере онлайн чата. Можно например делать запрос на сервер каждые несколько секунд и смотреть — готов ли сервер дать нам информацию. Такой подход не самое хорошее решение. Особенно когда речь заходит об высоконагруженных системах с большим количеством пользователей. Тогда на помощь приходят веб сокеты. Использование технологии веб сокетов без сторонних фреймворков или библиотек — занятие не самое удобное. Поэтому в данной статье мы рассмотрим 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. Тема очень обширная и интересная. Указанный пример не единственный способ работы с данным фреймворком. В нем есть еще очень много полезных методов, которым можно передавать информацию с сервера на клиент и обратно. Using WebSocket to build an interactive web applicationThis guide walks you through the process of creating a “Hello, world” application that sends messages back and forth between a browser and a server. WebSocket is a thin, lightweight layer above TCP. This makes it suitable for using “subprotocols” to embed messages. In this guide, we use STOMP messaging with Spring to create an interactive web application. STOMP is a subprotocol operating on top of the lower-level WebSocket. What You Will buildYou will build a server that accepts a message that carries a user’s name. In response, the server will push a greeting into a queue to which the client is subscribed. What You NeedA favorite text editor or IDE You can also import the code straight into your IDE: How to complete this guideLike most Spring Getting Started guides, you can start from scratch and complete each step or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code. To start from scratch, move on to Starting with Spring Initializr. To skip the basics, do the following: Download and unzip the source repository for this guide, or clone it using Git: git clone https://github.com/spring-guides/gs-messaging-stomp-websocket.git cd into gs-messaging-stomp-websocket/initial Starting with Spring InitializrYou can use this pre-initialized project and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial. To manually initialize the project: Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java. Click Dependencies and select Websocket. Click Generate. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
Adding DependenciesThe Spring Initializr does not provide everything you need in this case. For Maven, you need to add the following dependencies: The following listing shows the finished pom.xml file: If you use Gradle, you need to add the following dependencies: The following listing shows the finished build.gradle file: Create a Resource Representation ClassNow that you have set up the project and build system, you can create your STOMP message service. Begin the process by thinking about service interactions. To model the message that carries the name, you can create a plain old Java object with a name property and a corresponding getName() method, as the following listing (from src/main/java/com/example/messagingstompwebsocket/HelloMessage.java ) shows: Upon receiving the message and extracting the name, the service will process it by creating a greeting and publishing that greeting on a separate queue to which the client is subscribed. The greeting will also be a JSON object, which as the following listing shows: To model the greeting representation, add another plain old Java object with a content property and a corresponding getContent() method, as the following listing (from src/main/java/com/example/messagingstompwebsocket/Greeting.java ) shows: Spring will use the Jackson JSON library to automatically marshal instances of type Greeting into JSON. Next, you will create a controller to receive the hello message and send a greeting message. Create a Message-handling ControllerIn Spring’s approach to working with STOMP messaging, STOMP messages can be routed to @Controller classes. For example, the GreetingController (from src/main/java/com/example/messagingstompwebsocket/GreetingController.java ) is mapped to handle messages to the /hello destination, as the following listing shows: This controller is concise and simple, but plenty is going on. We break it down step by step. The @MessageMapping annotation ensures that, if a message is sent to the /hello destination, the greeting() method is called. Internally, the implementation of the method simulates a processing delay by causing the thread to sleep for one second. This is to demonstrate that, after the client sends a message, the server can take as long as it needs to asynchronously process the message. The client can continue with whatever work it needs to do without waiting for the response. Configure Spring for STOMP messagingNow that the essential components of the service are created, you can configure Spring to enable WebSocket and STOMP messaging. Create a Java class named WebSocketConfig that resembles the following listing (from src/main/java/com/example/messagingstompwebsocket/WebSocketConfig.java ): The registerStompEndpoints() method registers the /gs-guide-websocket endpoint, enabling SockJS fallback options so that alternate transports can be used if WebSocket is not available. The SockJS client will attempt to connect to /gs-guide-websocket and use the best available transport (websocket, xhr-streaming, xhr-polling, and so on). Create a Browser ClientWith the server-side pieces in place, you can turn your attention to the JavaScript client that will send messages to and receive messages from the server side. Create an index.html file similar to the following listing (from src/main/resources/static/index.html ): The main pieces of this JavaScript file to understand are the connect() and sendName() functions. The sendName() function retrieves the name entered by the user and uses the STOMP client to send it to the /app/hello destination (where GreetingController.greeting() will receive it). Make the Application ExecutableSpring Boot creates an application class for you. In this case, it needs no further modification. You can use it to run this application. The following listing (from src/main/java/com/example/messagingstompwebsocket/MessagingStompWebsocketApplication.java ) shows the application class: @SpringBootApplication is a convenience annotation that adds all of the following: @Configuration : Tags the class as a source of bean definitions for the application context. @ComponentScan : Tells Spring to look for other components, configurations, and services in the com/example package, letting it find the controllers. The main() method uses Spring Boot’s SpringApplication.run() method to launch an application. Did you notice that there was not a single line of XML? There is no web.xml file, either. This web application is 100% pure Java and you did not have to deal with configuring any plumbing or infrastructure. Build an executable JARYou can run the application from the command line with Gradle or Maven. You can also build a single executable JAR file that contains all the necessary dependencies, classes, and resources and run that. Building an executable jar makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth. Logging output is displayed. The service should be up and running within a few seconds. Test the serviceNow that the service is running, point your browser at http://localhost:8080 and click the Connect button. Upon opening a connection, you are asked for your name. Enter your name and click Send. Your name is sent to the server as a JSON message over STOMP. After a one-second simulated delay, the server sends a message back with a “Hello” greeting that is displayed on the page. At this point, you can send another name or you can click the Disconnect button to close the connection. SummaryCongratulations! You have just developed a STOMP-based messaging service with Spring. See AlsoThe following guides may also be helpful: Want to write a new guide or contribute to an existing one? Check out our contribution guidelines.
|