2017-06-09 32 views
10

我有以下js代碼:如何等待訂閱建立?

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

和下面的服務器代碼(最後一行調用它):

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

有時前端射門的$.get("/clients", null);

結果正如我明白問題:在結果進入前端時,訂閱不會發生。

如果在代碼中放置$.get("/clients", null);以下 - 一切正常。

你能解釋一下如何等待已建立的訂閱?

+0

我假設您已經有一個通過建立工作的腳跟連接。connect()但稍後的訂閱無法獲取消息,直到您查詢主機一次? STOMP不提供「成功」訂閱的回調。 – DooMMasteR

+0

它不會重現一致。我不明白短語:**直到你查詢主機一次** – gstackoverflow

回答

1

我認爲將REST請求與此消息傳遞模式混合會更有意義。

您是否考慮過通過SockJS將「updateClients」命令發送到回覆「/ topic/clients」頻道的「/ apps/updateClients」頻道?

2

由於@ light_303已經提到,混合HTTP請求和通知機制並不好。您可以在客戶端連接(/clients上的GET請求)時註冊時間,但是當他斷開連接時無法註冊。

你應該考慮下一種方法。當用戶訂閱/topic/clients

  1. 你單獨送他響應所有的客戶名單,然後只推送更新。
  2. 您單獨向他發送當前服務器時間或某種ID,然後僅推送更新。用戶使用GET請求中的給定時間/ ID到/clients,並在那一刻收到完整的客戶列表。如果您有增量更新(即向列表中添加新元素),則此選項可能很好,否則就不太好。

檢查該問題:Sending message to specific user on Spring Websocket

這實際上是荒謬的,Spring如何使事情複雜化。我建議你看看另一個實時網絡通信框架,比如Vert.x或Netty和Go編程語言。使用WebSockets或SockJS代替STOMP。所有這些技術都能以明顯的方式爲您提供更靈活和高性能的解決方案。另外,請檢查Centrifugo項目,可能與您的任務有關。

0

您可以使用@SubscribeMapping註釋spring-messaging

如果你有spring-messaging描述herehere配置,服務器端代碼可能類似於以下:

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

這種方式,你不必叫$.get("/clients", null);因爲JS消息處理程序接收的結果在訂閱發生後立即致電。 JS代碼將如下所示:

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