Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring STOMP sending messages from anywhere in the application

I am building an application using Stomp to broker messages over websockets. I am trying to send messages from the server to the client without a request from anywhere in the application. I found two separate choices online for sending messages from anywhere in the application.

The first is found in the Websocket documentation. Section 20.4.5:

@Controller
public class GreetingController {

    private SimpMessagingTemplate template;

    @Autowired
    public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @RequestMapping(value="/greetings", method=POST)
    public void greet(String greeting) {
        String text = "[" + getTimestamp() + "]:" + greeting;
        this.template.convertAndSend("/topic/greetings", text);
    }

}

The second is in a guide written by one of the Spring Bloggers:

@Controller
public class GreetingController {

  @Autowired
  private SimpMessagingTemplate template;


  @RequestMapping(value="/greeting", method=POST)
  public void greet(String greeting) {
    String text = "[" + getTimeStamp() + "]:" + greeting;
    this.template.convertAndSend("/topic/greeting", text);
  }

}

Both are very similar. The first overrides the default constructor and does not autowire the template initialization. The second does not create a new constructor, but does autowire the template initialization. My first question is whether these two actions are equivalent?

The more pressing matter is that I am having trouble calling the "greet" method from anywhere. I have tried doing this a couple of different ways.

Here is the first:

    public class modifier {

    @Autowired
    private HelloController sender;


    public void adder(String words) throws Exception {
        sender.greet(words);

    }
}

In the above case, it seems as if the new HelloController in never initialized. When debugging, I find that when the adder method calls the "greet" method, the sender is null and I receive a null pointer exception.

Here is the other route I have used to set up:

public class modifier {

    public void adder(String words) throws Exception {
        HelloController sender = new HelloController();
        sender.greet(words);
}

}

In this second above case, after debugging, there is also a null pointer exception, however it is not with sender. It is with sender.template. The template of sender is initialized, however it is never given a value, or id. Then when this.template.convertAndSend() is called inside greet, a null pointer exception is raised on this.template.

I have mixed and matched both the two gound implementations of the controller and my two implementations of calling the greet method from a separate class in the application and none work.

Is there anyone that could shed some light on my issue? Any help, tips, or advice would be greatly appreciated!

Thanks in advance.

like image 207
Theo Avatar asked Nov 10 '22 04:11

Theo


1 Answers

As correctly written in the comments, there are multiple ways to autowire dependencies, they are mostly equivalent, you have to choose the ones you prefer depending on your needs.

As per the other question: in Spring the controller is the object (a singleton) that listen to user requests, so the mapping @RequestMapping handles HTTP requests to the designated url.

If you need to push messages from the server to the client using the SimpMessagingTemplate object you must know that the client must using the STOMP protocol (over websockets), and it must be subscribed to the right topic.

In fact using STOMP the server can't push arbitrarily messages to the client, but it can only publish messages to topics, and the client must be subscribed to the right topics to receive them.

like image 90
Alessandro Polverini Avatar answered Nov 15 '22 12:11

Alessandro Polverini