Introduction
Websocket is useful to establish data communication between web browser and web server. Generally web servers process HTTP requests only, but websocket is another way to establish two way communication among web server and web browser.Websocket is based on publish and subscribe model of communication between browser and server
Websockets are used to send data between web client( from browser ) and serverWeb socket is an asynchronous way to establish communication between web browser and server.
Websocket is a TCP for Web
STOMP over Websocket ( Web Socket client )
STOMP ( Simple Text Oriented Messaging Protocol ) is a protocol to implement webscoket in our application. STOMP client is browser which connects with Web server by using javascript code. In the following sections you can notice clear details about using javascript code for STOMP. We are going to use SocketJS java script API in this example as a Web socket client.Steps to Create STOMP based Websocket Spring Boot application ( Web Socket Server )
Before dig into steps first we need to familiar with some terminology words related Web Socket ProtocolWebSocket endpoint: this is the url pattern must be created or configured at Webserver
Application prefix: this is the fixed url path prefix to enter into application
Message Broker/Simple Broker: this is the type of message distribution system like based on topic or queue etc..Via this broker messages will be delivered to all destinations which subscribed to a particular topic
First add the following dependency for enabling websocket
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
We can do all the above configuration with WebSocketMessageBrokerConfigurer, we need to create a configuration bean which implements WebSocketMessageBrokerConfigurer with @EnableWebScoketMessageBroker annotation
import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer{ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // The following line is to add socketJS endpoint which will be used at web socket client registry.addEndpoint("/msgapp").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // Enable a simple message broker and configure one or more prefixes to filter destinations targeting the broker //(e.g. destinations prefixed with "/topic"). registry.enableSimpleBroker("/topic"); // this is for setting prefix for processing methods mapping registry.setApplicationDestinationPrefixes("/appgo"); } }
In the above code we have to focus on three things mainly, one is Socket Client End point ( /msgapp ) created in line 14 which will be used at client( probably with STOMP javascript client code) code to connect with the websocket server, and second one is application prefix ( /appgo ) created in line 23, which will be used at message mapping handler methods in controller class and third one is broker desitnation prefix ( /topic ) which created in line 21, which specify destination of the message to be delivered, that means message can be delivered to all the users who are subscribed to this destination.
Controller with mapping messages handler methods
In this section we are going to create a controller class with message mapping handler methods which annotated with @MessageMapping and @SendToUsing @SendTo
@MessageMapping("/broadcastGroupChat") @SendTo("/topic/groupChat") public ChatMsg send(@Payload ChatMsg chatMsg) throws Exception {
return new ChatMsg(chatMsg.getFrom(), chatMsg.getText(), "ALL"); }In the above code we have used @SendTo annotation where we passed destination as a parameter, so all messages will be delivered to given destination, we can do same thing without @SendTo annotation, you can see in the bellow code that
Using SimpMessagingTemplate
@Autowired private SimpMessagingTemplate webSocket; @MessageMapping("/broadcast") public void send(@Payload ChatMsg chatMessage) throws Exception { ChatMsg message = new ChatMsg(chatMessage.getFrom(), chatMessage.getText(), "ALL"); webSocket.convertAndSend("/topic/broadcast", message); }In the above code we are using SimpMessagingTemplate and convertAndSend( ) method by passing destination address and message.
Payload class/model
In the above snippets of code we have used a model class named as ChatMsg which is a payload class ( that means a class which transfers between client and server as JSON mapping object ), now we have to create our payload class ChatMsg.import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class ChatMsg { private String from; private String text; private String recipient; private String time; public ChatMsg(String from, String text, String recipient) { super(); final String TIME_FORMATTER= "HH:mm:ss"; this.from = from; this.text = text; this.recipient = recipient; DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMATTER); this.time = LocalDateTime.now().format(formatter); } // add setter and getter methods here }
Creating Websocket client with STOMP by using SockJS javascript library
In the previous sections we have done a code at server side, to setup WebSocket environment and handler methods. Now in this section we are going to create WebSocket client by using SockJS javascript library<!-- https://mvnrepository.com/artifact/org.webjars/sockjs-client --> <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.webjars/stomp-websocket --> <dependency> <groupId>org.webjars</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.1</version> </dependency>
Adding javascript files to html code
Here add the following lines of code to your thymeleaf template file<script th:src="@{/webjars/sockjs-client/1.1.2/sockjs.js}" type="text/javascript"></script> <script th:src="@{/webjars/stomp-websocket/2.3.1/stomp.js}" type="text/javascript"></script>
Reason to use the above custom socket API is some old browsers do not support inbuilt websocket API so we are going to use this custom webscoket API sockjs. Before proceeding to know how to use sockJS we need to recall socket endpoint, application prefix, messagemapping value and subscribe destination.From the previous examples
- socket endpoint is : msgapp
- application prefix is: appgo
- messagmapping value is: broadcast
- subscribe destination is: /topic/broadcast
Create Socket client with endpoint
var socket = new SockJS('/msgapp'); var stompClient = Stomp.over(socket);in the above we have used socket endpoint msgapp
Connecting to the server
After creating STOMP client we need to connect to the server. Remember while connecting to the server we need to subscribe to the destination and we need to send message to messagemapping endpoint ( we see these two steps in the next sections )stompClient.connect({}, connectCallback); stompClient.connect({}, connectCallback, errorCallback); stompClient.connect(login, passcode, connectCallback); stompClient.connect(login, passcode, connectCallback, errorCallback);connectCallback functions must include code for destination subscription and sending message to messagemapping endpoint
Subscribe to destination
var subscription = stompClient.subscribe("/topic/broadcast", callback); callback = function(message) { // called when the client receives a STOMP message from the server if (message.body) { alert("got message with body " + message.body) } else { alert("got empty message"); } });
Subscribing more than one destination
var sub1 = stompClient.subscribe("/topic/broadcast", onmessage1); var sub2 = stompClient.subscribe("queue/another", onmessage2);in the above onmessage1 and onmessage2 are callback functions
Sending message to messagemapping endpoint
stompClient.send("/appgo/broadcast", {}, JSON.stringify(json));in the above code first parameter is messagemapping endpoint which is the combination of application prefix and @MessageMapping method value, second parameter is a header body, here we are not sending any value along header so we are giving empty braces, as a third parameter we need to send json string as a message to the server( which will be a payload model class )
This is a comment from admin
ReplyDeleteThis is a reply from admin
Delete