I have create a thread in spring application which is called at the start of the spring boot application.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
Thread th = new Thread(new Countdown());
th.start();
}
}
Inside that I have created a variable which decreases by 1 every second.
public class Countdown implements Runnable{
private static volatile int count=0;
@Override
public void run() {
this.runTimer();
}
public void runTimer(){
count=60;
while(count>0){
System.out.println("Countdown : "+count+" "+Thread.currentThread().getId());
try{
count--;
Thread.sleep(1000);
}
catch (Exception e){
System.out.println(e);
}
}
}
}
What I wanted to achieve is that after count-- operation I should be able to send the count value to all the clients connected to the server. The count value should be send without any request from the client.
Here is the WebSocket configuration
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
}
I tried using SimpMessageTemplate object to send the count. But it is only working when the client sends a request. I tried to use the SimpMessageTemplate object in Countdown class after count-- operation but its giving me null exception.
@Controller
public class CountdownWSController {
private Countdown countdown;
private SimpMessagingTemplate template;
public CountdownWSController(Countdown cnt, SimpMessagingTemplate template){
this.template = template;
countdown = cnt;
}
@MessageMapping("/client")
@SendTo("/topic/greetings")
public void countDownService(int count) throws Exception{
this.template.convertAndSend("/topic/greetings", new CountdownModel(count));
}
}
}
One of the ways to do that without using multi threading
@Controller
public class CountdownWSController {
private int countdown;
private SimpMessagingTemplate template;
public CountdownWSController(Countdown cnt, SimpMessagingTemplate template){
this.template = template;
countdown = 60; /* Choose the starting value */
}
@Scheduled(fixedRate = 1000)
public void countDownService() {
this.template.convertAndSend("/topic/greetings", this.count);
this.count=this.count-1;
}
}
However, with this way if there are two clients the timer will be the same even if they join the communication at different time