今天我已经搜索了几个小时的实现或教程,了解如何在Spring中跟踪websocket连接。
我已经完成了关于websockets和STOMP的(非常好的)Spring教程。 链接here
那么我的设置是什么,我有一个带有Spring后端的Ionic Hybrid应用程序,我想在后端出现新的通知事件时向客户端发送通知。所有这些代码都已实现且连接正常,但是现在无法指定通知需要去的位置。
没有关于此问题的教程或解释遵循Spring教程中的结构(至少在研究5小时后没有),并且我对Web上的websockets和安全性的所有信息感到有些不知所措。 (我已经学习了仅仅2天的websockets)
因此,对于我之前的所有事情,并且将会追随我,我认为根据Spring Tutorial教授的结构,提供紧凑而轻量的答案非常有用。
我在StackOverflow上发现了this unanswered question与我相同的问题,所以我相信这些问题会证明它是值得的。
TL; DR
如何在后端实现一个基于Spring WebSocket Tutorial跟踪连接的列表?
如何在建立连接时将数据从客户端发送到后端? (例如用户标识或令牌)
答案 0 :(得分:1)
所以我自己弄清楚了。
我的通知有一个收件人ID(需要发送通知的用户ID)
所以我要发送给' / ws-user /' + id +' /问候'其中id是登录的用户。
在客户端,这很容易实现。
var stompClient = null;
// init
function init() {
/**
* Note that you need to specify your ip somewhere globally
**/
var socket = new SockJS('http://127.0.0.1:9080/ws-notification');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
/**
* This is where I get the id of the logged in user
**/
barService.currentBarAccountStore.getValue().then(function (barAccount) {
subscribeWithId(stompClient,barAccount.user.id);
});
});
}
/**
* subscribe at the url with the userid
**/
function subscribeWithId(stompClient,id){
stompClient.subscribe('/ws-user/'+id+'/greetings', function(){
showNotify();
});
}
/**
* Broadcast over the rootscope to update the angular view
**/
function showNotify(){
$rootScope.$broadcast('new-notification');
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
// setConnected(false);
console.log("Disconnected");
}
接下来我们添加" setUserDestinationPrefix"到WebSocketConfig.java类中的MessageBrokerRegistry:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
private final static String userDestinationPrefix = "/ws-user/";
@Override
public void configureMessageBroker(MessageBrokerRegistry config){
config.enableSimpleBroker("/ws-topic","/ws-user");
config.setApplicationDestinationPrefixes("/ws-app");
config.setUserDestinationPrefix(userDestinationPrefix);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-notification").setAllowedOrigins("*").withSockJS();
}
}
请注意,我使用内部RestTemplate调用来访问我的控制器方法,该方法向订阅的客户端发送通知。这是由一个事件消费者类完成的(要求查看代码,它只是为了触发控制器功能,可以不同的方式完成)
@RequestMapping(value = "/test-notification", method = RequestMethod.POST)
public void testNotification(@RequestBody String recipientId) throws InterruptedException {
this.template.convertAndSendToUser(recipientId,"/greetings", new Notify("ALERT: There is a new notification for you!"));
}
如果您发现任何问题和/或安全问题,请查看我的代码并提醒我。
答案 1 :(得分:0)
对于websocket中基于用户的交付,您可以使用具有弹簧安全性的Principle对象。这是一个很好的例子:
https://github.com/rstoyanchev/spring-websocket-portfolio
Spring安全性会检查SAME ORIGIN,并且您可以从客户端发送带有指定used-id的stomp标头。
希望这对你有所帮助。
答案 2 :(得分:0)
看看这个答案:How to get all active sessions in Spring 5 WebSocket API?
您可以使用Spring的SimpUserRegistry
API检索连接的用户。