1. Общ преглед
В този бърз урок ще илюстрираме как да изпратим съобщение до определена сесия или конкретен потребител, използвайки Spring WebSockets .
За въведение в горния модул вижте тази статия.
2. Конфигуриране на WebSocket
На първо място, трябва да конфигурираме нашия посредник за съобщения и крайна точка на приложението WebSocket :
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic/", "/queue/"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/greeting"); } }
С @EnableWebSocketMessageBroker ние активиран брокер ценни съобщения над WebSocket използване Stomp , което е съкращение от Streaming Текст Oriented Съобщения протокол. Важно е да се отбележи, че тази анотация трябва да се използва заедно с @Configuration .
Не е задължително да се разширява AbstractWebSocketMessageBrokerConfigurer, но за бързия пример е по-лесно да персонализирате импортираната конфигурация.
При първия метод създадохме прост посредник на съобщения, базиран на паметта, за да пренасяме съобщенията обратно до клиента по дестинации с префикс „/ topic“ и „/ queue“ .
И във второто регистрирахме крайни точки при „/ приветствие“ .
В случай че искаме да активираме SockJS, трябва да изменим частта от регистъра:
registry.addEndpoint("/greeting").withSockJS();
3. Вземете идентификатор на сесията от Interceptor
Един от начините да получите идентификатора на сесията е добавянето на Spring Interceptor, който ще се задейства по време на ръкостискането и ще получи информацията от данните на заявката.
Този прехващач може да бъде добавен директно в WebSocketConfig:
@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry .addEndpoint("/greeting") .setHandshakeHandler(new DefaultHandshakeHandler() { public boolean beforeHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest .getServletRequest().getSession(); attributes.put("sessionId", session.getId()); } return true; }}).withSockJS(); }
4. Крайна точка на WebSocket
Започвайки с Spring 5.0.5.RELEASE, не е необходимо да правите персонализация поради подобрението на анотацията @SendToUser , която ни позволява да изпращаме съобщение до дестинация на потребител чрез „ / user / {sessionId} / ... “, а отколкото „ / потребител / {потребител} /… “.
Това означава, че анотацията работи, разчитайки на идентификатора на сесията на входното съобщение, като ефективно изпраща отговор до частния дестинация на сесията:
@Controller public class WebSocketController { @Autowired private SimpMessageSendingOperations messagingTemplate; private Gson gson = new Gson(); @MessageMapping("/message") @SendToUser("/queue/reply") public String processMessageFromClient( @Payload String message, Principal principal) throws Exception { return gson .fromJson(message, Map.class) .get("name").toString(); } @MessageExceptionHandler @SendToUser("/queue/errors") public String handleException(Throwable exception) { return exception.getMessage(); } }
Импортът е да се отбележи, че @SendToUser посочва, че връщаната стойност на метод за обработка на съобщения трябва да бъде изпратена като Съобщение до посоченото (ите) местоназначение (я), добавено с „ / user / {username} “ .
5. Клиент на WebSocket
function connect() { var socket = new WebSocket('ws://localhost:8080/greeting'); ws = Stomp.over(socket); ws.connect({}, function(frame) { ws.subscribe("/user/queue/errors", function(message) { alert("Error " + message.body); }); ws.subscribe("/user/queue/reply", function(message) { alert("Message " + message.body); }); }, function(error) { alert("STOMP error " + error); }); } function disconnect() { if (ws != null) { ws.close(); } setConnected(false); console.log("Disconnected"); }
Създава се нов WebSocket, сочещ към “ / поздрав ” за картографирането в WebSocketConfiguration .
Когато абонираме клиента за „ / потребител / опашка / грешки “ и „ / потребител / опашка / отговор “ използваме отбелязаната информация от последния раздел.
Както виждаме, @SendToUser сочи към „ опашка / грешки “, но съобщението ще бъде изпратено на „ / потребител / опашка / грешки “.
6. Заключение
В тази статия проучихме начин за изпращане на съобщение директно до потребител или идентификатор на сесия с Spring WebSocket
Както винаги, пълният изходен код на примерите е достъпен в GitHub.