21

I'm trying to make a connection between client and server via Spring webSocket and I'm doing this by the help of this link. I want Controller to send a "hello" to client every 5 seconds and client append it to the greeting box every time. This is the controller class:

@EnableScheduling
@Controller
public class GreetingController {

    @Scheduled(fixedRate = 5000)
    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting() throws Exception {
        Thread.sleep(1000); // simulated delay
        System.out.println("scheduled");
        return new Greeting("Hello");
    }

}

and This is Connect() function in app.jsp:

function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.send("/app/hello", {}, JSON.stringify({'name': "connect"}));
        stompClient.subscribe('/topic/greetings', function (message) {
            console.log("message"+message);
             console.log("message"+(JSON.parse(message.body)));

            showGreeting(JSON.parse(message.body).content);
        });
    });
}

when the index.jsp loads and I press the connect button, only one time it appnds hello in greeting, how should I make client to show "hello" message every 5 seconds?

ShakibaZar
  • 727
  • 3
  • 9
  • 27
  • The message "Scheduled" is visible? I mean the Scheduled annotation is working? – cralfaro Feb 13 '17 at 16:00
  • I think the problem is, what you are trying to do dont make sense, I mean the messageMapping you need to think in it as a dispatcher, when somebody send a messsage to the particular topic the make a broadcast to all listeners, but adding the Schedule actually nobody is sending a real message. I propose you to to remove the Scheduled annotation and do the same from some dummy html with some setTimeout() JS function and connect to the topic and send some message, then you will see the message in your other html page. – cralfaro Feb 14 '17 at 09:44

1 Answers1

39

Please reffer to this portion of the documentation. The way you are trying to send a message is totally wrong. I would modify your above class as follows:

@EnableScheduling
@Controller
public class GreetingController {

    @Autowired
    private SimpMessagingTemplate template;

    @Scheduled(fixedRate = 5000)
    public void greeting() {
        Thread.sleep(1000); // simulated delay
        System.out.println("scheduled");
        this.template.convertAndSend("/topic/greetings", "Hello");
    }

}
Andrei Balici
  • 749
  • 5
  • 12
  • The way he is using is correct, check this docs https://spring.io/guides/gs/messaging-stomp-websocket/ – cralfaro Feb 14 '17 at 09:41
  • 9
    By using @SendTo, the method will only publish the message to that topic when the method is invoked as a message handler (that is when the message came from the websocket itself). If you want the container to invoke the method every 5 seconds and get the messages published to the topic, you'll have to use the messaging template. There's no way around it. – Andrei Balici Feb 14 '17 at 09:47
  • Ahh sorry i didn't see you remove some annotations, yes this method i think also could work – cralfaro Feb 14 '17 at 09:49
  • Is there any way to use this method to subscribe to a specific piece of information, e.g., `"/topic/greetings/{id}`"? Please see my question here for more details: https://stackoverflow.com/questions/54942000/how-can-i-schedule-a-push-of-client-specified-data-every-few-seconds-using-a-s – AnonymousAngelo Mar 01 '19 at 10:09