2017-06-09 4 views
10

Ich habe folgendes js Code:Wie warten Abonnements?

stompClient.subscribe('/topic/clients', function (calResult) { 
    updateClientsTable(JSON.parse(calResult.body)); 
}); 
$.get("/clients", null); 

und folgenden Servercode (letzte Zeile ruft sie):

@GetMapping(value = {"/clients"}) 
@ResponseBody 
public void loadClients() { 
     brokerMessagingTemplate.convertAndSend("/topic/clients", clientService.getClientList()); 
} 

Irgendwann Front-End verpasst Ergebnis $.get("/clients", null);

Wie ich Problem zu verstehen : Im Moment des Ergebnisses auf Front-End, Abonnements ist nicht passiert.

wenn $.get("/clients", null); unten in den Code zu setzen - alles funktioniert gut.

Können Sie erklären, wie Abonnements eingerichtet werden?

+0

Ich nehme an, Sie haben bereits eine funktionierende Stomp-Verbindung über hergestellt.connect(), aber das spätere Abonnement kann keine Nachrichten empfangen, bis Sie den Host einmal abgefragt haben? STOMP bietet keinen Rückruf für ein "erfolgreiches" Abonnement. – DooMMasteR

+0

Es reproduziert nicht konstant. Ich habe den Ausdruck nicht verstanden: ** bis Sie den Host einmal abfragen ** – gstackoverflow

Antwort

1

Ich denke, es wäre sinnvoller, REST-Anfragen nicht mit diesem Messaging-Muster zu mischen.

Haben Sie in Betracht gezogen, den Befehl "updateClients" über SockJS an einen Kanal "/ apps/updateClients" zu senden, der auf den Kanal "/ topic/clients" antwortet?

2

Wie @light_303 bereits erwähnt, ist das Mischen von HTTP-Anfragen mit Benachrichtigungsmechanismus nicht gut. Sie können einen Moment registrieren, wenn der Client eine Verbindung herstellt (GET-Anforderung unter /clients), aber Sie können sich nicht registrieren, wenn er die Verbindung trennt.

Sie sollten auf eine der folgenden Arten denken. Wenn Benutzer abonniert /topic/clients:

  1. Sie senden ihm einzeln Antwort mit allen Client-Liste und dann Push-Updates nur.
  2. Sie senden ihm individuell aktuelle Serverzeit oder eine Art von ID und dann nur Push-Updates. Der Benutzer verwendet die angegebene Zeit/ID in der GET-Anforderung an /clients und erhält in diesem Moment die vollständige Client-Liste. Diese Option kann in Situationen gut sein, wenn Sie inkrementelle Updates haben (d. H. Neue Elemente zur Liste hinzufügen) und ansonsten nicht so gut.

Überprüfen Sie diese Frage: Sending message to specific user on Spring Websocket.

Das ist eigentlich lächerlich, wie Spring Dinge komplizieren kann. Ich empfehle Ihnen, auf andere Frameworks für Echtzeit-Web-Kommunikation zu schauen, wie Vert.x oder Netty und auf Go-Programmiersprache. Verwenden Sie WebSockets oder SockJS anstelle von STOMP. All diese Technologien können Ihnen auf eine offensichtliche Weise eine flexiblere und performantere Lösung bieten. Überprüfen Sie auch Centrifugo Projekt, vielleicht ist es für Ihre Aufgabe relevant.

0

Sie können @SubscribeMapping Annotation von spring-messaging verwenden.

Wenn Sie spring-messaging als here und here beschrieben konfiguriert haben, könnte der serverseitigen Code aussehen wie folgt:

@Controller 
public class MessagingController { 
    @SubscribeMapping("/clients") 
    public List<Client> loadClients() { 
     return clientService.getClientList(); 
    } 
} 

Auf diese Weise müssen Sie $.get("/clients", null); nicht nennen, weil JS Nachrichtenhandler Ergebnis erhält Anruf direkt nach dem Abonnement passiert. JS-Code würde wie aussehen:

stompClient.subscribe('/topic/clients', function (calResult) { 
    updateClientsTable(JSON.parse(calResult.body)); 
});