我有以下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 :(得分:1)
我认为不将REST请求与此消息传递模式混合会更有意义。
您是否考虑过发送" updateClients"通过SockJS命令进入" / apps / updateClients"回复" / topic / clients"的频道渠道?
答案 1 :(得分:1)
正如@ light_303已经提到的,将HTTP请求与通知机制混合起来并不好。您可以在客户端连接时注册时刻(/clients
上的GET请求),但是当他断开连接时您无法注册。
你应该考虑下一种方式。当用户订阅/topic/clients
:
/clients
的GET请求中使用给定的时间/ ID,并在该时刻收到完整的客户列表。当你有增量更新(即向列表中添加新元素)时,此选项可能会很好,但不是很好。请检查此问题: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
配置为here和here,则服务器端代码如下所示:
@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));
});