I try to use Spring with websocket. I started my investigation with this tutorial.
In my side client I have something like that to initialize the connection to the server :
function connect() {
var socket = new SockJS('/myphotos/form');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function(greeting){
showGreeting(JSON.parse(greeting.body).content);
});
});
}
It works great, in my controller I’m able to do my process in the following class :
@Controller
@RequestMapping("/")
public class PhotoController {
@MessageMapping("/form")
@SendTo("/topic/greetings")
public Greeting validate(AddPhotosForm addPhotosForm) {
return new Greeting("Hello world !");
}
}
Now what I want to do it’s having a thread sending a message to the client listening on “/topic/greeting”. I wrote my Runnable class like this :
public class FireGreeting implements Runnable {
private PhotoController listener;
public FireGreeting(PhotoController listener) {
this.listener = listener;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep( 2000 );
listener.fireGreeting();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
}
}
And completed my controller like that :
@Controller
@RequestMapping("/")
public class PhotoController {
@MessageMapping("/form")
@SendTo("/topic/greetings")
public Greeting validate(AddPhotosForm addPhotosForm) {
// added this part
FireGreeting r = new FireGreeting( this );
new Thread(r).start();
return new Greeting("Hello world !");
}
// added this method
@SendTo("/topic/greetings")
public Greeting fireGreeting() {
System.out.println("Fire");
return new Greeting("Fire");
}
}
The method PhotoController.fireGreeting is called as I want but nothing happened on the client side. Any suggestions ? Thank you.
The Message event takes place usually when the server sends some data. Messages sent by the server to the client can include plain text messages, binary data, or images. Whenever data is sent, the onmessage function is fired.
To send a message through the WebSocket connection you call the send() method on your WebSocket instance; passing in the data you want to transfer. socket. send(data); You can send both text and binary data through a WebSocket.
Spring Boot includes the spring-WebSocket module, which is compatible with the Java WebSocket API standard (JSR-356). Implementing the WebSocket server-side with Spring Boot is not a very complex task and includes only a couple of steps, which we will walk through one by one.
I was able to solve my problem thanks to @Boris the Spider. The correct solution is to do something like that :
@Controller @RequestMapping("/") public class PhotoController { @Autowired private SimpMessagingTemplate template; @MessageMapping("/form") @SendTo("/topic/greetings") public Greeting validate(AddPhotosForm addPhotosForm) { FireGreeting r = new FireGreeting( this ); new Thread(r).start(); return new Greeting("Hello world !"); } public void fireGreeting() { System.out.println("Fire"); this.template.convertAndSend("/topic/greetings", new Greeting("Fire")); } }
A better way to schedule periodic tasks is, as suggested by @Boris the Spider, to use Spring scheduling mechanisms (see this guide).
For the sake of Separation of Concerns, I would also separate scheduled-related code from controller code.
In your case you could use a class like this one:
@Component public class ScheduledTasks { @Autowired private SimpMessagingTemplate template; @Scheduled(fixedRate = 2000) public void fireGreeting() { this.template.convertAndSend("/topic/greetings", new Greeting("Fire")); } }
And add the @EnableScheduling
tag to your Application class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With