Websocket 跟踪 Spring 中的连接
Websocket keep track of connections in Spring
今天,我搜索了几个小时来寻找有关如何在 Spring 中跟踪 websocket 连接的实现或教程。
我已经完成了关于 websockets 和 STOMP 的(非常好)Spring 教程。
linkhere
那么我的设置是什么,我有一个带有 Spring 后端的 Ionic Hybrid 应用程序,我想在后端出现新的通知事件时向客户端发送通知。所有这些代码都已实现并且连接正常,但现在无法指定通知需要发送到哪里。
在Spring教程中没有关于这个问题的教程或解释(至少在研究了5个小时之后没有)我对所有关于websockets和安全的信息有点不知所措在网上。 (我学习 websockets 才 2 天)
因此,对于我之前和之后的所有内容,我认为按照 Spring 教程教授的结构获得一个紧凑轻量级的答案会非常有用。
我在 Whosebug 上发现了 this unanswered question 与我遇到的问题相同的问题,所以我相信这个问题会证明它的价值。
TL;DR
如何在后端实现一个列表来跟踪基于 Spring WebSocket Tutorial 的连接?
连接建立后如何从客户端向后台发送数据? (例如用户 ID 或令牌)
对于 websocket 中基于用户的交付,您可以使用具有 spring 安全性的原则 objects。这是一个很好的例子:
https://github.com/rstoyanchev/spring-websocket-portfolio
Spring 安全性将检查 SAME ORIGIN,您可以从您的客户端发送指定 used-id 的 stomp header。
希望这对您有所帮助。
所以我自己想通了。
我的通知有一个收件人 ID(通知需要发送到的用户 ID)
所以我要发送到 '/ws-user/'+id+'/greetings' 其中 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 class 中的 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 调用来访问我的控制器方法,该方法向订阅的客户端发送通知。这是由事件消费者完成的class(要求查看代码,它只是为了触发控制器功能,可以以不同的方式完成)
@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!"));
}
请检查我的代码,如果您发现任何问题请警告我and/or 安全问题。
看看这个答案:How to get all active sessions in Spring 5 WebSocket API?
您可以使用 Spring 的 SimpUserRegistry
API.
检索连接的用户
今天,我搜索了几个小时来寻找有关如何在 Spring 中跟踪 websocket 连接的实现或教程。
我已经完成了关于 websockets 和 STOMP 的(非常好)Spring 教程。 linkhere
那么我的设置是什么,我有一个带有 Spring 后端的 Ionic Hybrid 应用程序,我想在后端出现新的通知事件时向客户端发送通知。所有这些代码都已实现并且连接正常,但现在无法指定通知需要发送到哪里。
在Spring教程中没有关于这个问题的教程或解释(至少在研究了5个小时之后没有)我对所有关于websockets和安全的信息有点不知所措在网上。 (我学习 websockets 才 2 天)
因此,对于我之前和之后的所有内容,我认为按照 Spring 教程教授的结构获得一个紧凑轻量级的答案会非常有用。
我在 Whosebug 上发现了 this unanswered question 与我遇到的问题相同的问题,所以我相信这个问题会证明它的价值。
TL;DR
如何在后端实现一个列表来跟踪基于 Spring WebSocket Tutorial 的连接?
连接建立后如何从客户端向后台发送数据? (例如用户 ID 或令牌)
对于 websocket 中基于用户的交付,您可以使用具有 spring 安全性的原则 objects。这是一个很好的例子:
https://github.com/rstoyanchev/spring-websocket-portfolio
Spring 安全性将检查 SAME ORIGIN,您可以从您的客户端发送指定 used-id 的 stomp header。
希望这对您有所帮助。
所以我自己想通了。
我的通知有一个收件人 ID(通知需要发送到的用户 ID)
所以我要发送到 '/ws-user/'+id+'/greetings' 其中 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 class 中的 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 调用来访问我的控制器方法,该方法向订阅的客户端发送通知。这是由事件消费者完成的class(要求查看代码,它只是为了触发控制器功能,可以以不同的方式完成)
@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!"));
}
请检查我的代码,如果您发现任何问题请警告我and/or 安全问题。
看看这个答案:How to get all active sessions in Spring 5 WebSocket API?
您可以使用 Spring 的 SimpUserRegistry
API.