Create a Spring boot + Angular WebSocket using SockJS and Stomp

Hasitha Amarathunga
5 min readNov 14, 2019

Today I am going to develop a Spring boot WebSocket that use to angular chat application. So First I will explain about what is a WebSocket and why we use a web socket.

What is a WebSocket ?

From the definition of wikipedia WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the Web Socket API in Web IDL is being standardized by the W3C.

Why WebSocket ?

In many web applications, websockets are used to push messages to a client for real-time updates. Usually we recommend using a websocket connection when getting started with Feathers because you get real-time updates for free and it is faster than a traditional HTTP connection. For more click here.

Let’s start developing with Spring Boot and Angular.

First I will show the back-end development with Spring boot. This is the project structure of my back-end project.

Back-end Project structure.

I use maven as my back-end compiler. So I added following dependencies to pom.xml file.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>

In here spring-boot-starter-websocket dependency is required to use SockJS and Stomp in our project.

First I configured that dependency with creating WebSocketConfig class in my config package as below.

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

In here @Configuration annotation is required to any class that if it is configuration class. This class extends the class AbstractWebSocketMessageBrokerConfigurer. So we can @Override any method of that class. So I added a SockJS endpoint called /socket that can access any host. And also I configured the message broker with named ‘message’ can uniquely access with that name.

Then I created a controller called WebSocketController to access that message broker with Simple Messaging Template as below .

@Controller
public class WebSocketController {

private final SimpMessagingTemplate template;

@Autowired
WebSocketController(SimpMessagingTemplate template){
this.template = template;
}

@MessageMapping("/send/message")
public void sendMessage(String message){
System.out.println(message);
this.template.convertAndSend("/message", message);
}
}

From that Simple Messaging Template I used convertAndSend() method to asynchronous data communication with that message broker. If there is any data comes to that message broker it will automatically send that data using above configured endpoint called /socket with SockJS and Stomp.

Finally, I change the tomcat port as 8081 in application.properties file.

server.port = 8081

Now I will run the back-end using tomcat in port 8081. Then I will check that endpoint in my web browser or testing tool as below.

Postman test

So that is about the Spring boot back-end. Let move to front-end part. Following image show the project structure of Angular 8 front-end web application.

Front-end project structure.

I downloaded sockjs.min.js and stomp.min.js and put it into assets file as above. Then added these two .js files to index.html page as below.

<script src="assets/sockjs.min.js"></script>
<script src="assets/stomp.min.js"></script>

Then I created a service called MessageService and configure that SockJS, Stomp properties and back-end API’s with following Steps.

// Declare SockJS and Stomp
declare var SockJS;
declare var Stomp;

Then Following added inside of MessageService.

constructor() {
this.initializeWebSocketConnection();
}
public stompClient;
public msg = [];
initializeWebSocketConnection() {
const serverUrl = 'http://localhost:8081/socket';
const ws = new SockJS(serverUrl);
this.stompClient = Stomp.over(ws);
const that = this;
// tslint:disable-next-line:only-arrow-functions
this.stompClient.connect({}, function(frame) {
that.stompClient.subscribe('/message', (message) => {
if (message.body) {
that.msg.push(message.body);
}
});
});
}

sendMessage(message) {
this.stompClient.send('/app/send/message' , {}, message);
}

Inside of InitializeWebSocketConnection() method first create a SockJS server with created back-end endpoint called /socket and added it over Stomp. Then connect to stomp client and subscribe that created message broker called ‘message’ asynchronously with stomp client and if is there any message it will push that message body into msg array. This method is called inside of constructor() because it is the initialize method of that service.

That sendMessage() is used to send a message to that message broker called ‘message’ using stomp client.

Let’s move to app.component.ts

export class AppComponent {
title = 'websocket-frontend';
input;
constructor(private messageService: MessageService) {}
sendMessage() {
if (this.input) {
this.messageService.sendMessage(this.input);
this.input = '';
}
}
}

In here I defined a variable called input to bind data from html input and if that input value is not empty it will called the sendMessage() of Message Service.

app.component.html

<input class="form-control" type="text" placeholder="message" [(ngModel)]="input">
<button class="btn btn-success" (click)="sendMessage()">Send</button>
<div class="content">
<div *ngFor="let msg of messageService.msg">
{{msg}}
</div>
</div>

Here, I use ngModel to two way binding of input field data and called the sendMessage() if the send button and view the msg of Messages Service in content.

So you can test the application with two browser or two tabs as below.

Image 1
image 2
image 3

So that is about Spring boot + Angular web socket. You can download the source code from my github.

My Apps on Google Play => https://play.google.com/store/apps/details?id=com.hasee.scan.app

--

--

Hasitha Amarathunga

Graduated Computer Science Student at University Of Colombo School of Computing & Still working as Specialist - Senior Software Engineer at Scicom Msc Bhd.