I am trying to implement Web Socket communication between my client and Server Applications. My backend service is a Spring Boot Application which sends a custom message object over the socket on a topic and my front end Angular based application should subscribe to the topic on the socket Endpoint and receive data. I am using @stomp/stompjs
(v7.0.0) package in my Angular app to achieve web socket messaging through STOMP. However, it seems to fail when initializing the WebSocket Object in the stompjs code.
The backend application code goes as follows: pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocketConfig:
package com.jh.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint");
registry.addEndpoint("/ws-endpoint").withSockJS();
registry.addEndpoint("/ws-endpoint").setAllowedOrigins("*").withSockJS();
}
}
My Service Class code where messages are being emitted (through a scheduled cron job):
import org.springframework.messaging.simp.SimpMessagingTemplate;
// other imports here...
@Service
@Transactional
public class MyServiceImpl implements MyService {
private final SimpMessagingTemplate messagingTemplate;
public MyServiceImpl (SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
// some code here...
@Scheduled(fixedDelay = 5000)
public void longRunningTask()
{
System.out.println("This is a cron job running");
JobStatusMessage jobStatusMessage = new JobStatusMessage(
Instant.now().toEpochMilli(),
"Job is Running",
JobStatus.RUNNING
);
messagingTemplate.convertAndSend("/topic", jobStatusMessage );
}
}
In my Angular app, I installed stomp/stompjs v7.0.0 using node:
$ npm install @stomp/stompjs
And I created a plain angular component to initiate connection to the web socket Endpoint to receive data:
import { Component, OnInit } from '@angular/core';
import { Client, Message } from '@stomp/stompjs';
@Component({
selector: 'jhi-web-socket-impl',
templateUrl: './web-socket-impl.component.html',
styleUrls: ['./web-socket-impl.component.scss'],
})
export class WebSocketImplComponent implements OnInit {
public message: string;
private client: Client;
constructor() {
this.client = new Client();
this.message = '';
this.client.configure({
brokerURL: 'ws://localhost:8090/ws-endpoint',
onConnect: () => {
this.client.subscribe('/topic', (message: Message) => {
this.message = message.body;
console.log('Received message:', this.message);
});
},
onChangeState(state) {
console.log('State Changed to: ', state); // 0=active, 1=deactivating,2=inactive
},
onStompError(frame) {
console.log("Stomp Error Ocurred with frame: ",frame.body);
},
onUnhandledFrame(frame) {
console.log("Unhandled frame: ", frame.body);
},
onUnhandledReceipt(frame) {
console.log("Unhandled Recept: ", frame.body);
},
onUnhandledMessage(frame) {
console.log("Unhandled Message: ", frame.body);
},
onWebSocketClose() {
"Web Socket Closed"
},
onWebSocketError() {
"Web Socket Error Occurred"
},
onDisconnect(frame) {
console.log("Disconnected :", frame.body);
},
});
}
ngOnInit(): void {
console.log('WebSocketImplComponent ngOnInit() called');
this.client.activate();
}
}
Now when I run the applications, the backend application runs just fine without any errors but on the front end no data is received. Here is what the console shows:
when clicking on the source of error, it shows the line of code where problem occurs:
0 getting printed means that ActivationStatus
was set to "ACTIVE" according to this documentation https://stomp-js.github.io/api-docs/develop/miscellaneous/enumerations.html but nothing else is happening after that, it keeps printing the Connection failure log to console without a message.
One thing to be noted here is that I can successfully connect to the server socket Endpoint using Postman:
What could've gone wrong or missing in my implementation if anyone can point that out? Thanks.