Virat
Virat

Reputation: 581

Real time notifications in spring boot web socket

In my application, I need to send real time notifications to a specific user. My WebSocketConfig class is as below,

    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
        @Override
        public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
            stompEndpointRegistry.addEndpoint("/websocket-example")
                    .withSockJS();
        }

        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.enableSimpleBroker("/topic");
    }
}

Most of the time information will be sent by the server side. So I have not set the application destination.

In the client side, I am subscribing to the destination '/topic/user`,

function connect() {
    var socket = new SockJS('/websocket-example');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/user', function (greeting) {
//            showGreeting(JSON.parse(greeting.body).content);
console.log("Received message through WS");
        });
    });
}

In one of my RestController I have a method which broadcasts the message to all connected clients.

    @GetMapping("/test")
    public void test()
    {
        template.convertAndSend("/topic/user", "Hurray");
    }

Until this part everything works fine. I receive the message and is logging to the console.

Now If I want to send the notification only to specific users, I have to use template.convertAndSendToUser(String user, String destination, String message). But I am not understanding what I should pass to the user parameter. Where and when will I get the user?

I went through couple of questions related to this, but I am not understanding the concepts clearly.

Upvotes: 5

Views: 9059

Answers (2)

Vadim Dissa
Vadim Dissa

Reputation: 1011

Before sending any messages to a user you need to authenticate it by the server first. There are different ways for doing this. Spring Security is a key phrase here

https://docs.spring.io/spring-security/site/docs/current/guides/html5/helloworld-boot.html

When authentication is completed you can simply get user name by calling:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

https://www.baeldung.com/get-user-in-spring-security

Upvotes: 2

Devratna
Devratna

Reputation: 1008

This username is part of a java.security.Principal interface. Each StompHeaderAccessor or WebSocket session object has an instance of this principle and you can get the username from it. it is not generated automatically. It has to be generated manually by the server for every session.

You can check here for more info about generating a unique id for every session.

then use like this:

@MessageMapping('/test')
public void test(SimpMessageHeaderAccessor sha)
{
  String userName = sha.session.principal.name;
  template.convertAndSend(userName, '/topic/user', "Hurray");
}

Upvotes: 0

Related Questions