Вступ до WebSockets з Spring

1. Огляд

У цій статті ми створимо просту веб-програму, яка реалізує обмін повідомленнями за допомогою нових можливостей WebSocket, представлених у Spring Framework 4.0.

WebSockets - це двонаправлений , повнодуплексний , постійний зв’язок між веб-браузером та сервером. Після встановлення з’єднання WebSocket з’єднання залишається відкритим, доки клієнт або сервер не вирішить закрити це з’єднання.

Типовим випадком використання може бути, коли програма включає в себе спілкування кількох користувачів, як у чаті. У нашому прикладі ми створимо простий клієнт чату.

2. Залежності Мейвена

Оскільки це проект на основі Maven, ми спочатку додаємо необхідні залежності до pom.xml :

 org.springframework spring-websocket 5.2.2.RELEASE   org.springframework spring-messaging 5.2.2.RELEASE 

Окрім того, оскільки ми будемо використовувати JSON для побудови тіла наших повідомлень, нам потрібно додати залежності Джексона . Це дозволяє Spring перетворити наш об'єкт Java у / з JSON :

 com.fasterxml.jackson.core jackson-core 2.10.2   com.fasterxml.jackson.core jackson-databind 2.10.2 

Якщо ви хочете отримати останню версію бібліотек вище, знайдіть їх на Maven Central.

3. Увімкніть WebSocket навесні

Перше, що потрібно зробити, це включити можливості WebSocket. Для цього нам потрібно додати конфігурацію до нашого додатку та анотувати цей клас @EnableWebSocketMessageBroker .

Як випливає з назви, він забезпечує обробку повідомлень WebSocket за підтримки посередника повідомлень:

@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat"); registry.addEndpoint("/chat").withSockJS(); } } 

Тут ми бачимо, що метод configureMessageBroker використовується для налаштування брокера повідомлень . По-перше, ми дозволяємо брокеру повідомлень в пам’яті переносити повідомлення назад клієнту за адресами з префіксом “/ topic”.

Ми завершимо нашу просту конфігурацію, призначивши префікс “/ app” для фільтрування цільових напрямків, націлених на анотовані методи програми (через @MessageMapping ).

RegisterStompEndpoints метод реєструє «/ чат» кінцевої точки, що дозволяє підтримку Stomp весни . Майте на увазі, що ми також додаємо сюди кінцеву точку, яка працює без SockJS заради еластичності.

Ця кінцева точка, якщо вона має префікс “/ app”, є кінцевою точкою, яку обробляє метод ChatController.send () .

Це також включає резервні опції SockJS, так що альтернативні варіанти обміну повідомленнями можуть бути використані, якщо WebSockets недоступні. Це корисно, оскільки WebSocket ще не підтримується у всіх браузерах і може бути заборонений обмежувальними мережевими проксі.

Резервні копії дозволяють програмам використовувати API WebSocket, але витончено переходять на альтернативи, не пов’язані з WebSocket, коли це необхідно під час виконання.

4. Створіть модель повідомлення

Тепер, коли ми створили проект і налаштували можливості WebSocket, нам потрібно створити повідомлення для надсилання.

Кінцева точка прийме повідомлення, що містять ім'я відправника та текст у повідомленні STOMP, тіло якого є об'єктом JSON .

Повідомлення може виглядати так:

{ "from": "John", "text": "Hello!" } 

Для моделювання повідомлення, що несе текст, ми можемо створити простеОб'єкт Java із властивостями from та text :

public class Message { private String from; private String text; // getters and setters } 

За замовчуванням Spring використовуватиме бібліотеку Джексона для перетворення об'єкта нашої моделі в JSON і з нього.

5. Створіть контролер обробки повідомлень

Як ми вже бачили, підхід Spring до роботи з обміном повідомленнями STOMP полягає у прив'язуванні методу контролера до налаштованої кінцевої точки. Це стало можливим завдяки анотації @MessageMapping .

Асоціація між кінцевою точкою та контролером дає нам можливість обробляти повідомлення, якщо це необхідно:

@MessageMapping("/chat") @SendTo("/topic/messages") public OutputMessage send(Message message) throws Exception { String time = new SimpleDateFormat("HH:mm").format(new Date()); return new OutputMessage(message.getFrom(), message.getText(), time); } 

Для цілей нашого прикладу ми створимо інший об'єкт моделі з назвою OutputMessage, який представлятиме вихідне повідомлення, надіслане до налаштованого пункту призначення. Ми заповнюємо наш об’єкт відправником та текстом повідомлення, взятим із вхідного повідомлення, і збагачуємо його міткою часу.

Після обробки нашого повідомлення ми надсилаємо його у відповідне місце призначення, визначене анотацією @SendTo . Усі абоненти пункту призначення / / тема / повідомлення отримають повідомлення.

6. Створіть клієнт браузера

Зробивши наші конфігурації на стороні сервера, ми використаємо клієнтську бібліотеку sockjs для створення простої сторінки HTML, яка взаємодіє з нашою системою обміну повідомленнями.

Перш за все, нам потрібно імпортувати sockjs і топати клієнтські бібліотеки Javascript. Далі ми можемо створити функцію connect () для відкриття зв'язку з нашою кінцевою точкою, функцію sendMessage () для надсилання нашого повідомлення STOMP та функцію disconnect () для закриття зв'язку:

  Chat WebSocket    var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').innerHTML = ''; } function connect() { var socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/messages', function(messageOutput) { showMessageOutput(JSON.parse(messageOutput.body)); }); }); } function disconnect() { if(stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendMessage() { var from = document.getElementById('from').value; var text = document.getElementById('text').value; stompClient.send("/app/chat", {}, JSON.stringify({'from':from, 'text':text})); } function showMessageOutput(messageOutput) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(messageOutput.from + ": " + messageOutput.text + " (" + messageOutput.time + ")")); response.appendChild(p); }

Connect Disconnect

Send

7. Перевірка прикладу

Щоб перевірити наш приклад, ми можемо відкрити пару вікон браузера та отримати доступ до сторінки чату за адресою:

//localhost:8080

Після цього ми можемо приєднатися до чату, ввівши псевдонім та натиснувши кнопку підключення. Якщо ми створимо та надішлемо повідомлення, ми зможемо побачити його у всіх сеансах браузера, які приєдналися до чату.

Погляньте на знімок екрана, щоб побачити приклад:

8. Висновок

У цьому посібнику ми вивчили підтримку WebSocket компанії Spring. Ми побачили його конфігурацію на стороні сервера і створили простий аналог на стороні клієнта з використанням бібліотек Javascript sockjs і stomp .

Приклад коду можна знайти в проекті GitHub.