The frontend is not updating when there is an update in backend. For real time updates I am using Websockets

32 Views Asked by At

I am trying to build an application for my organization which gives real time data of current open incidents from the ServiceNow. I am using websocket for that. I am new to websocket so please help me find where I am wrong.

I have created a backend using spring boot which updates the backend with open incidents and send message to the frontend accordingly. But the frontend is not getting updated. moreover i think it is not receiving the message at all. When i run my backend and frontend for few seconds the coonnection does not establish. Later websocket opens connection gets established but still the frontend doesn't receive messages(i guess).

Here is my WebSocket configuration:

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 configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry){
        messageBrokerRegistry.enableSimpleBroker("/topic");
        messageBrokerRegistry.setApplicationDestinationPrefixes("/app");
    }
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry){
        registry.addEndpoint("/ws");
        registry.addEndpoint("/ws")
                .setAllowedOrigins("http://localhost:4200")
                .withSockJS();
    }

}

Here is the service where I send the message to frontend whenever there is an update:

package com.openinicidentslivetracker.incidentmanagement.service;

import com.openinicidentslivetracker.incidentmanagement.model.OpenIncidents;
import com.openinicidentslivetracker.incidentmanagement.repository.OpenIncidentsRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OpenIncidentService {

    private final OpenIncidentsRepository openIncidentsRepository;

    private final SimpMessagingTemplate messagingTemplate;

    public void saveOpenIncidents(List<OpenIncidents> openIncidentsList){

        List<String> existingIncidentNumbers = openIncidentsRepository.findIncidentNumberByIncidentNumberIn
                (openIncidentsList
                .stream().map(OpenIncidents::getIncidentNumber).collect(Collectors.toList()));

        List<OpenIncidents> openIncidentsToSave = openIncidentsList.stream().filter(openIncidents -> !existingIncidentNumbers.contains(openIncidents.getIncidentNumber())).collect(Collectors.toList());

        openIncidentsRepository.saveAll(openIncidentsToSave);

        messagingTemplate.convertAndSend("/topic/incidents",openIncidentsToSave);
    }

    public List<String> fetchPreviouslyOpenIncidents(){
        return openIncidentsRepository.findAll().stream().map(OpenIncidents::getIncidentNumber).collect(Collectors.toList());
    }


    public void deleteIncidents(List<String> newlyClosedIncidents) {
        openIncidentsRepository.deleteByIncidentNumberIn(newlyClosedIncidents);
        messagingTemplate.convertAndSend("/topic/incidents/close",newlyClosedIncidents);
    }
}

So basically I am using a logic to segregate New open incidents and closed incidents respectively and send them as message to Angular frontend so that it can update it accordingly.

Here is my frontend code:

websocket.service.ts:

import { Injectable } from '@angular/core';
import * as Stomp from 'stompjs';
import * as SockJS from 'sockjs-client';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class WebSocketService {
  private stompClient: any;
  private webSocketUrl = 'http://localhost:8989/ws'; // WebSocket endpoint

  private incidentsSubject = new Subject<any>();

  constructor() { }

  connect() {
    const socket = new SockJS(this.webSocketUrl);
    this.stompClient = Stomp.over(socket);
    this.stompClient.connect({}, () => {
      console.log('WebSocket connected');
    },(error : any) => {
        console.error('Error during Websocket Connection:',error);
        
    });
  }

  isConnected() : boolean{
    return this.stompClient && this.stompClient.connected;
  }

  getIncidents(): Observable<any> {
    if (!this.isConnected) {
        console.error('WebSocket is not connected.');
        return new Observable();
      }

    this.stompClient.subscribe('/topic/incidents', (message: { body: string }) => {
      const incidents = JSON.parse(message.body);
      this.incidentsSubject.next(incidents);
    });
    return this.incidentsSubject.asObservable();
  }

  getClosedIncidents(): Observable<any> {
    const closedIncidentsSubject = new Subject<any>();
    this.stompClient.subscribe('/topic/incidents/close', (message: { body: string }) => {
      const closedIncidents = JSON.parse(message.body);
      closedIncidentsSubject.next(closedIncidents);
    });
    return closedIncidentsSubject.asObservable();
  }
}
0

There are 0 best solutions below