spring boot – Web Socket send private notification to a specific user from database

i am working for my first time with websockets , i am trying to create an application that sends global notifications that everyone can see and also private notifications for specific users from Database. So i have implemented a WebSocket Configuration and sending notifications to everyone works fine but sending private notifications messages to specific user from database did not work , when i open two browsers windows i can not see the private notification coming while i can see the global one.

Here My WebSocket Configuration file:

@Configuration @EnableWebSocketMessageBroker public class
WebSocketConfig implements WebSocketMessageBrokerConfigurer {


    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //web sockets starts communication with /notification
        registry.enableSimpleBroker("/topic");
        //web socket prefix
        registry.setApplicationDestinationPrefixes("/ws");
    }


    //to use in front end
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //front end  starts with this url to communicate with web socket
        registry.addEndpoint("/ws-notifications")
                .withSockJS();
    } }

NotificationsController:

@Controller 
public class NotificationsController {

    @Autowired
    private NotificationService notificationService;

    @Autowired
    NotificationRepository notificationRepository;


    @MessageMapping("/message")
    @SendTo("/topic/messages")
    public ResponseNotification getMessage(final NotificationDAO notificationDAO) throws InterruptedException {
      Thread.sleep(1000);
      notificationService.sendGlobalNotification();
      return new ResponseNotification("Hello, " + HtmlUtils.htmlEscape(notificationDAO.getMessageContent()) + "!");
    }


    @MessageMapping("/private-message")
    @SendTo("/topic/private-messages")
    public ResponseNotification getPrivateMessage(final NotificationDAO notificationDAO, final Principal principal) throws
InterruptedException {
        Thread.sleep(1000);
        notificationService.sendPrivateNotification(principal.getName());
        return new ResponseNotification("Sending private message to user  "+principal.getName()+ " :  " +
HtmlUtils.htmlEscape(notificationDAO.getMessageContent()) + "!");
    }

}

NotificationsService:

@Service 
public class NotificationService implements INotificationService {

    String apiBaseUrl = "https://api.github.com";

    private final SimpMessagingTemplate messagingTemplate;

    @Autowired  public NotificationService(SimpMessagingTemplate
messagingTemplate) {        this.messagingTemplate = messagingTemplate;
    }

    public void sendGlobalNotification() {      ResponseNotification
message = new ResponseNotification("Global Notification");

        messagingTemplate.convertAndSend("/topic/global-notifications",
message);   }

    public void sendPrivateNotification(final String userId) {
        ResponseNotification message = new ResponseNotification("Private
Notification");

        messagingTemplate.convertAndSendToUser(userId,"/topic/private-notifications",
message);   }    }

WebSocketController:

@RestController 
@RequestMapping("api/websocket") public class
WebSocketController {

    @Autowired
    WebSocketService webSocketService;


    @PostMapping("/send-message")
    public void sendMessage(@RequestBody final NotificationDAO notificationDAO) {
    webSocketService.notifyFrontend(notificationDAO.getMessageContent());
    }

    @PostMapping("/send-private-message/{id}")
    public void sendPrivateMessage(@PathVariable final String id, @RequestBody final 
    NotificationDAO notificationDAO) {
        webSocketService.notifyUser(id,notificationDAO.getMessageContent());
    }

  My WebSocketService:

  @Service
  public class WebSocketService {

    private final SimpMessagingTemplate messagingTemplate;
    private final NotificationService notificationService;

    @Autowired
    public WebSocketService(SimpMessagingTemplate messagingTemplate, NotificationService notificationService) {
        this.messagingTemplate = messagingTemplate;
        this.notificationService = notificationService;
    }


    public void notifyFrontend(final String message) {
        ResponseNotification responseNotification = new ResponseNotification(message);
        notificationService.sendGlobalNotification();
        messagingTemplate.convertAndSend("topic/messages",responseNotification);
    }


    public void notifyUser(final String id, final String message) {
        ResponseNotification responseNotification = new ResponseNotification(message);
        notificationService.sendPrivateNotification(id);
        messagingTemplate.convertAndSendToUser(id,"topic/private-messages",responseNotification);
    }

}

My WebSocketService:

    @Service public class WebSocketService {

    private final SimpMessagingTemplate messagingTemplate;
    private final NotificationService notificationService;

    @Autowired
    public WebSocketService(SimpMessagingTemplate messagingTemplate, NotificationService notificationService) {
        this.messagingTemplate = messagingTemplate;
        this.notificationService = notificationService;
    }


    public void notifyFrontend(final String message) {
        ResponseNotification responseNotification = new ResponseNotification(message);
        notificationService.sendGlobalNotification();
        messagingTemplate.convertAndSend("topic/messages",responseNotification);
    }


    public void notifyUser(final String id, final String message) {
        ResponseNotification responseNotification = new ResponseNotification(message);
        notificationService.sendPrivateNotification(id);
        messagingTemplate.convertAndSendToUser(id,"topic/private-messages",responseNotification);
    }

}

my js file:

var stompClient = null; var notificationCount = 0;


$(document).ready( function () {

    console.log("document is ready")
    $("form").on('submit', function (e) {
        e.preventDefault();
    });
    $( "#connect" ).click(function() { connect(); });
    $( "#disconnect" ).click(function() { disconnect(); });
    $( "#send" ).click(function() { sendMessage(); });
    $( "#send-private" ).click(function() { sendPrivateMessage(); });
    $( "#notifications" ).click(function() { resetNotificationCount(); });


});


function setConnected(connected) {
    $("#connect").prop("disabled", connected);
    $("#disconnect").prop("disabled", !connected);
    if (connected) {
        $("#conversation").show();
    }
    else {
        $("#conversation").hide();
    }
    $("#greetings").html(""); }

function connect() {
    var socket = new SockJS('/ws-notifications');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        console.log('Connected: ' + frame);
        updateNotificationDisplay();
        stompClient.subscribe('/topic/messages', function (message) {
            showMessage(JSON.parse(message.body).content);
        });

        stompClient.subscribe('/topic/private-messages', function (message) {
            showMessage(JSON.parse(message.body).content);
        });

        stompClient.subscribe('/topic/global-notifications', function (message) {
            notificationCount = notificationCount + 1;
            updateNotificationDisplay();
        });

        stompClient.subscribe('/topic/private-notifications', function (message) {
            notificationCount = notificationCount + 1;
            updateNotificationDisplay();
        });

    });

}

function disconnect() {
    if (stompClient !== null) {
        stompClient.disconnect();
    }
    setConnected(false);
    console.log("Disconnected"); }

function showMessage(message) {
    $("#messages").append("<tr><td>" + message + "</td></tr>"); }

function sendMessage() {
    console.log("sending message");
    stompClient.send("/ws/message", {}, JSON.stringify({'messageContent': $("#message").val()})); }

function sendPrivateMessage() {
    console.log("sending private message");
    stompClient.send("/ws/private-message", {}, JSON.stringify({'messageContent': $("#private-message").val()})); }

function updateNotificationDisplay() {
    if (notificationCount == 0) {
        $('#notifications').hide();
    } else {
        $('#notifications').show();
        $('#notifications').text(notificationCount);
    } }

function resetNotificationCount() {
    notificationCount = 0;
    updateNotificationDisplay(); }

My question is how to send a private message to a user with username for example david20 and how david20 can see his private notifications and on what url?

i have already spring security implemented on the application and i am not sure if authentication is required or not to send/get private messages. I am fully lost and i almost understand a little about webSocket. Any help will be so appreciated.

Leave a Comment