Spring WebSocket @SendToSession: Senden einer Nachricht an eine bestimmte Sitzung

Ist es möglich, eine Nachricht zu senden, um bestimmte session?

Habe ich ein nicht authentifizierter websocket zwischen den clients und dem Spring-servlet. Ich muss senden Sie unaufgefordert eine Nachricht an eine bestimmte Verbindung, wenn ein asynchroner job endet.

@Controller
public class WebsocketTest {


     @Autowired
    public SimpMessageSendingOperations messagingTemplate;

    ExecutorService executor = Executors.newSingleThreadExecutor();

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

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

Wie Sie sehen in diesem code, kann der client beginnen, einen asynchronen job und wenn es fertig ist, es braucht eine end-Nachricht. Natürlich, ich muss die Nachricht nur der Antragsteller und nicht-broadcast an alle.
Es wäre toll, einen @SendToSession annotation oder messagingTemplate.convertAndSendToSession Methode.

UPDATE

Habe ich versucht, dieses:

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

Aber diese Sendungen zu allen Sitzungen, nicht nur die angegebene.

UPDATE 2

Test mit convertAndSendToUser () - Methode.
Dieser test ist und hacken auf der offiziellen Spring-tutorial: https://spring.io/guides/gs/messaging-stomp-websocket/

Dies ist der server-code:

@Controller
public class WebsocketTest {

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

     @Autowired
        public SimpMessageSendingOperations messagingTemplate;
}

- und dies ist der client-code:

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

Client leider nicht erhalten Ihre pro-Sitzungs-Antwort, die jeder 5000ms als erwartet. Ich bin mir sicher, dass "1" eine gültige sessionId für den 2. client angeschlossen, da sehe ich es im debug-Modus mit SimpMessageHeaderAccessor.getSessionId()

HINTERGRUND SZENARIO

Möchte ich das erstellen einer Statusanzeige für eine remote-job, client fragt server für eine asynchrone job und prüft es seinen Fortschritt durch websocket-Nachricht von server. Dies ist NICHT eine Datei hochladen, aber ein remote-Berechnung, so dass nur der server weiß, der Fortschritt der einzelnen Jobs.
Ich brauche, um eine Nachricht senden zu bestimmten Sitzung, weil jeder job wird gestartet durch die Sitzung.
Client fragt eine remote-Berechnung
Server startet diese Aufgabe und für jeden job-step-Antwort an Antragsteller AUFTRAGGEBER mit der job-status.
Client ruft die Nachrichten über seine Arbeit und bauen ein Fortschritt/status-bar.
Dies ist, warum brauche ich eine pro-session.
Ich könnte auch eine pro-user-Meldungen, aber der Frühling nicht pro Benutzer unerwünschte Nachrichten. (Kann nicht senden, Benutzer-Nachricht mit Spring Websocket)

FUNKTIONIERENDE LÖSUNG

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

Ab dem UPDATE2 Lösung musste ich komplett convertAndSendToUser Methode mit last param (MessageHeaders):

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

wo createHeaders() ist diese Methode:

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

InformationsquelleAutor der Frage Tobia | 2016-01-21

Schreibe einen Kommentar