Spring WebSocket @SendToSession: send message to specific session

Is it possible to send a message to specific session?

I have an unauthenticated websocket between clients and a Spring servlet. I need to send an unsolicited message to a specific connection when an async job ends.

public class WebsocketTest {

    public SimpMessageSendingOperations messagingTemplate;

    ExecutorService executor = Executors.newSingleThreadExecutor();

    public void start(SimpMessageHeaderAccessor accessor) throws Exception {
        String applicantId=accessor.getSessionId();        
        executor.submit(() -> {
            //... slow job

    public void jobEnd(String sessionId){
        messagingTemplate.convertAndSend("/queue/jobend"); //how to send only to that session?

As you can see in this code, the client can start an async job and when it finishes, it needs the end message. Obviously, I need to message only the applicant and not broadcast to everyone. It would be great to have an @SendToSession annotation or messagingTemplate.convertAndSendToSession method.


I tried this:

messagingTemplate.convertAndSend("/queue/jobend", true, Collections.singletonMap(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId));

But this broadcasts to all sessions, not only the one specified.


Test with convertAndSendToUser() method. This test is and hack of the official Spring tutorial: https://spring.io/guides/gs/messaging-stomp-websocket/

This is the server code:

public class WebsocketTest {

    public void init(){
        ScheduledExecutorService statusTimerExecutor=Executors.newSingleThreadScheduledExecutor();
        statusTimerExecutor.scheduleAtFixedRate(new Runnable() {                
            public void run() {
                messagingTemplate.convertAndSendToUser("1","/queue/test", new Return("test"));
        }, 5000,5000, TimeUnit.MILLISECONDS);

        public SimpMessageSendingOperations messagingTemplate;

and this is the client code:

function connect() {
            var socket = new WebSocket('ws://localhost:8080/hello');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe('/user/queue/test', function(greeting){

Unfortunately client doesn't receive its per-session reply every 5000ms as expected. I'm sure that "1" is a valid sessionId for the 2nd client connected because I see it in debug mode with SimpMessageHeaderAccessor.getSessionId()


I want to create a progress bar for a remote job, client asks server for an async job and it checks its progress by websocket message sent from server. This is NOT a file upload but a remote computation, so only server knows the progress of each job. I need to send a message to specific session because each job is started by session. Client asks for a remote computation Server starts this job and for every job step reply to applicant client with its job progress status. Client gets messages about its job and build up a progress/status bar. This is why I need a per-session messages. I could also use a per-user messages, but Spring does not provide per user unsolicited messages. (Cannot send user message with Spring Websocket)


 __      __ ___   ___  _  __ ___  _  _   ___      ___   ___   _    _   _  _____  ___  ___   _  _ 
 \ \    / // _ \ | _ \| |/ /|_ _|| \| | / __|    / __| / _ \ | |  | | | ||_   _||_ _|/ _ \ | \| |
  \ \/\/ /| (_) ||   /| ' <  | | | .` || (_ |    \__ \| (_) || |__| |_| |  | |   | || (_) || .` |
   \_/\_/  \___/ |_|_\|_|\_\|___||_|\_| \___|    |___/ \___/ |____|\___/   |_|  |___|\___/ |_|\_|

Starting from the UPDATE2 solution I had to complete convertAndSendToUser method with last param (MessageHeaders):

messagingTemplate.convertAndSendToUser("1","/queue/test", new Return("test"), createHeaders("1"));

where createHeaders() is this method:

private MessageHeaders createHeaders(String sessionId) {
        SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
        return headerAccessor.getMessageHeaders();


No need to create specific destinations, it's already done out of the box as of Spring 4.1 (see SPR-11309).

Given users subscribe to a /user/queue/something queue, you can send a message to a single session with:

As stated in the SimpMessageSendingOperations Javadoc, since your user name is actually a sessionId, you MUST set that as a header as well otherwise the DefaultUserDestinationResolver won't be able to route the message and will drop it.

SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor

messagingTemplate.convertAndSendToUser(sessionId,"/queue/something", payload, 

You don't need users to be authenticated for this.

It is very complicated and in my opinion, isn't worth it. You need to create a subscription for every user (even unauthenticated ones) by their session id.

Let's say that every user subscribes to a unique queue only for him:

stompClient.subscribe('/session/specific' + uuid, handler);

On the server, before the user subscribes you will need to notify and send a message for the specific session and save to a map:

    public void start(@DestinationVariable sessionId) throws Exception {
        anonymousUserSession.put(key, sessionId);

After that, when you want to send message to the user you will need to:

messagingTemplate.convertAndSend("/session/specific" + key); 

But I don't really know what you are trying to do and how you will find the specific session (who is anonymous).

You need to simply add the session id in

  • Server Side


  • Client Side


Note: Dont forget to add '/user' in your end point in server side.

Need Your Help

Why collection literals?

java collections java-7

From the various online articles on Java 7 I have come to know that Java 7 will be having collection literals1 like the following:

How to include server-side script in Jade template?

node.js express pug

I've just installed moment.js; now I want to access moment inside my Jade template. Example: