使用Spring来跟踪Websocket连接

8

今天我花了几个小时搜索Spring中如何跟踪WebSocket连接的实现或教程。

我已经完成了(非常好的)关于Websockets和STOMP的Spring教程。 链接在这里

所以我的设置是什么,我有一个带有Spring后端的Ionic Hybrid应用程序,并且我想在后端出现新通知事件时向客户端发送通知。所有这些代码都已经实现并且连接工作正常,但现在没有办法指定通知需要去哪里。

没有教程或解释跟随Spring教程结构处理此事(至少经过5小时的研究之后),我对网络上关于websockets和安全性的所有信息感到有些不知所措。(我只学习了两天Websockets)

因此,对于所有曾经走过我这条路或即将走过我这条路的人来说,我认为遵循Spring教程所教授的结构提供一份简洁而轻量级的答案可能非常有用。

我在StackOverflow上找到了这个未答复的问题,与我有相同的问题,所以我确定这些问题将证明其价值。

TL;DR

如何根据Spring WebSocket教程在后端实现一个跟踪连接的列表?

在建立连接时如何从客户端向后端发送数据? (例如用户ID或令牌)


你是否真正花时间阅读了参考指南 - M. Deinum
2
我已经尝试过了,正如我所说的那样,这一切都让人不知所措,因此我认为一个简单而通用的答案对像我这样的新学习者非常有用。 - Sytham
3个回答

2

所以我自己弄明白了。

我的通知有一个接收者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");
  }

接下来,在WebSocketConfig.java类的MessageBrokerRegistry中添加“setUserDestinationPrefix”:

@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!"));
}

请查看我的代码,如果您发现任何问题和/或安全问题,请告诉我。

你能分享代码吗?你如何知道要使用哪个套接字将消息发送给客户端? - N Jay
@Sytham,你能分享一下代码吗?我卡在向客户端发送消息的地方。谢谢。 - Toluwalemi

0

对于基于用户的WebSocket传递,您可以使用Spring Security中的Principle对象。这里有一个很好的实现示例:

https://github.com/rstoyanchev/spring-websocket-portfolio

Spring Security 会检查同源策略,并且你可以从客户端发送带有 user-id 指定的 stomp 标头。

希望这可以帮助到你。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接