如何等待订阅?

时间:2017-06-09 15:27:04

标签: javascript spring-mvc websocket stomp sockjs

我有以下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);放在代码中 - 一切正常。

你能解释一下如何等待订阅吗?

3 个答案:

答案 0 :(得分:1)

我认为不将REST请求与此消息传递模式混合会更有意义。

您是否考虑过发送" updateClients"通过SockJS命令进入" / apps / updateClients"回复" / topic / clients"的频道渠道?

答案 1 :(得分:1)

正如@ light_303已经提到的,将HTTP请求与通知机制混合起来并不好。您可以在客户端连接时注册时刻(/clients上的GET请求),但是当他断开连接时您无法注册。

你应该考虑下一种方式。当用户订阅/topic/clients

  1. 您单独向他发送包含所有客户列表的回复,然后仅推送更新。
  2. 您分别向他发送当前服务器时间或某种ID,然后仅推送更新。用户在/clients的GET请求中使用给定的时间/ ID,并在该时刻收到完整的客户列表。当你有增量更新(即向列表中添加新元素)时,此选项可能会很好,但不是很好。
  3. 请检查此问题:Sending message to specific user on Spring Websocket

    这实际上是荒谬的,Spring如何使事情复杂化。我建议您查看另一个用于实时Web通信的框架,例如Vert.x或Netty以及Go编程语言。使用WebSockets或SockJS代替STOMP。所有这些技术都能以明显的方式为您提供更灵活,更高效的解决方案。另外,请检查Centrifugo项目,也许它与您的任务相关。

答案 2 :(得分:0)

您可以使用@SubscribeMapping中的spring-messaging注释。

如果spring-messaging配置为herehere,则服务器端代码如下所示:

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

这样您就不必调用$.get("/clients", null);,因为JS消息处理程序在订阅发生后立即收到loadClients()调用的结果。 JS代码看起来像:

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