I am trying to send a private message between users using spring-websocket.
I found the following:
https://github.com/rstoyanchev/springx2013-websocket/blob/master/spring-messaging/slides.md
which includes:
Send Reply To User
@Controller
public class GreetingController {
// Message sent to "/user/{username}/queue/greetings"
@MessageMapping("/greetings")
@SendToUser
public String greet(String greeting) {
return "[" + getTimestamp() + "]: " + greeting;
}
}
The above seems to imply that a message sent to "/user/{username}/queue/greetings" will invoke the greet method before sending the return value on to the specified user.
When I send a message to this destination, it gets sent to the directly to the user without being processed by the greet controller method.
Do I understand the expected flow correctly? If I don't, what do I need to do to be able to process the message using a controller method before it's sent to a user.
The @SendToUser
annotation defines that the return value of the method should be send to a user destination prefixed with /user/{username}
where the user name is extracted from the headers of the input message being handled (current user).
In Spring 4.2 you can use placeholders in @SendTo
(only destination variable placeholders, see SPR-12170), if you pass the username as a destination variable you could do something like this:
@MessageMapping("/greetings/{u}")
@SendTo("/user/{u}/queue/greetings")
public String greet(String greeting) {
return "[" + getTimestamp() + "]: " + greeting;
}
This approach uses the SimpMessagingTemplate
internally, so if you are using a version previous to 4.2, there's nothing wrong in using the SimpMessagingTemplate
for dynamic destinations:
@MessageMapping("/greetings/{username}")
public void greet(@Payload String greeting, @DestinationVariable("username") String username) {
String message = "[" + getTimestamp() + "]: " + greeting;
simpMessagingTemplate.convertAndSend("/user/" + username + "/queue/greetings", message);
}