Search code examples
javaspring-websocketspring-rabbit

The message consumer component of the system processes each message and notifies asynchronously using WebSockets the caregiver application


I am trying to send some notifications from Consumer of the rabbitmq through a websocket and publish them on the angular application.

I am new with both rabbitmq and websocket and I don't know how to configure the websocket to get the messages from the Consumer

Here is my consumer:

@Override
@RabbitListener(queues = "${rabbitmq.queue}")
public void onMessage(Message message) {
    String timi = new String(message.getBody());
    JsonObject jsonObject = new Gson().fromJson(timi, JsonObject.class);

    MonitoredData monitoredData = new MonitoredData();
    monitoredData.setIdPatient((jsonObject.get("Id patient")).getAsString());
    monitoredData.setActivity((jsonObject.get("Activity")).getAsString());
    monitoredData.setStartTime((jsonObject.get("Start time")).getAsString());
    monitoredData.setEndTime((jsonObject.get("End time")).getAsString());
    monitoredDataRepo.save(monitoredData);

    if (monitoredData.getActivity().contains("Sleeping")) {
        DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime date1 = LocalDateTime.from(f.parse(monitoredData.getStartTime()));
        LocalDateTime date2 = LocalDateTime.from(f.parse(monitoredData.getEndTime()));
        Duration d = Duration.between(date1, date2);
        if ((d.getSeconds() / 3600) > 9) {
            System.out.println("The patient slept more than 9 hours");
        }
    }

    if (monitoredData.getActivity().contains("Leaving\t")) {
        DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime date1 = LocalDateTime.from(f.parse(monitoredData.getStartTime()));
        LocalDateTime date2 = LocalDateTime.from(f.parse(monitoredData.getEndTime()));
        Duration d = Duration.between(date1, date2);
        if ((d.getSeconds() / 3600) > 3) {
            System.out.println("The patient was out more than 3 hours");
        }
    }

    if (monitoredData.getActivity().contains("Toileting\t") || monitoredData.getActivity().contains("Showering\t")) {
        DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime date1 = LocalDateTime.from(f.parse(monitoredData.getStartTime()));
        LocalDateTime date2 = LocalDateTime.from(f.parse(monitoredData.getEndTime()));
        Duration d = Duration.between(date1, date2);
        if ((d.getSeconds() / 60) >= 30) {
            System.out.println("The patient was in the bathroom more than 30 minutes");
        }
    }

// System.out.println("Received message" + message); }

The messages I take from the System.out.println are the messages that I want to put on a pop up in the Angular app.

I also have this rabbit controller:

@GetMapping("/send")
public String sendMessage() throws InterruptedException {
    producer.produceMsg();
    return "Message successfully sent";
}

Solution

  • I am also new to RabbitMq, but this is my configuration for WebSocket.

      @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
        static final String MESSAGE_PREFIX = "/topic";
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();
        }
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.enableSimpleBroker(MESSAGE_PREFIX, "/queue");
            registry.setApplicationDestinationPrefixes("/app");
        }
    }
    

    In the consumer class you can inject SimpMessagingTemplate websocket; and then you can use the this in RabbitListener : this.websocket.convertAndSend("/topic" , json);

    As for the frontend part, i used React but i think it's similar. You cand google sockJs and try to receive messages. Good luck!