In Spring Boot (Websockets)
I just saw this example:
messaging.convertAndSendToUser( username, "/queue/notifications",
new Notification("You just got mentioned!"));
Where does the guy get a username from? I can't find any mention about where to get that username...
STOMP is the Simple (or Streaming) Text Oriented Messaging Protocol. It uses a set of commands like CONNECT, SEND, or SUBSCRIBE to manage the conversation. STOMP clients, written in any language, can talk with any message broker supporting the protocol.
public class SimpMessagingTemplate extends AbstractMessageSendingTemplate<String> implements SimpMessageSendingOperations. An implementation of SimpMessageSendingOperations . Also provides methods for sending messages to a user.
This answer is written based on this application: https://github.com/spring-guides/gs-messaging-stomp-websocket
In order to register a user, you must first create an object that will represent it, for example:
public final class User implements Principal {
private final String name;
public User(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
Then you'll need a way to create these User
objects. One way of doing it is when SockJS
sends you the connect message headers. In order to do so, you need to intercept the connect message. You can do that by creating our your interceptor, for example:
public class UserInterceptor extends ChannelInterceptorAdapter {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
Object raw = message
.getHeaders()
.get(SimpMessageHeaderAccessor.NATIVE_HEADERS);
if (raw instanceof Map) {
Object name = ((Map) raw).get("name");
if (name instanceof LinkedList) {
accessor.setUser(new User(((LinkedList) name).get(0).toString()));
}
}
}
return message;
}
}
Once you have that, you must also register this UserInterceptor
. I'm guessing somewhere in your application you have defined a configuration AbstractWebSocketMessageBrokerConfigurer
class. In this class you can register your user interceptor by overriding configureClientInboundChannel
method. You can do it like this:
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new UserInterceptor());
}
And then finally, when your clients connect, they'll have to provide their usernames:
stompClient.connect({
name: 'test' // Username!
}, function () {
console.log('connected');
});
After you have all this setup, simpUserRegistry.getUsers()
will return a list of users and you'll be able to use convertAndSendToUser
method:
messaging.convertAndSendToUser("test", ..., ...);
Edit
Testing this out a bit further, when subscribing, you'll have to prefix your topics with /user
as SimpMessagingTemplate
uses this as a default prefix, for example:
stompClient.subscribe('/user/...', ...);
Also I had made a mistake in UserInterceptor
and corrected it (name parsing part).
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