Websocket跟踪Spring中的连接

Syt*_*ham 5 java spring stomp sockjs spring-websocket

今天,我已经搜索了几个小时的实现或教程,以了解如何在Spring中跟踪Websocket连接。

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

因此,我的设置是什么,我有一个带有Spring后端的Ionic Hybrid应用,我想在后端出现新的通知事件时向客户端发送通知。所有这些代码已经实现,并且连接正常,但是现在无法指定通知需要到达的位置。

在Spring教程的结构中,没有关于此问题的教程或解释(至少不经过5个小时的研究),而且我对有关Websocket和Web安全性的所有信息有些不知所措。(我已经学习了2天的websockets)

因此,对于之前和之后的所有工作,我认为按照Spring教程的结构进行紧凑而轻巧的回答非常有用。

我在StackOverflow上发现了这个未解决的问题,该问题与我遇到的问题相同,因此,我相信这些问题将证明它是值得的。

TL; DR

如何基于Spring WebSocket教程在后端中实现一个列表来跟踪连接?

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

Syt*_*ham 3

所以我自己想出了办法。

我的通知有一个收件人 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");
  }
Run Code Online (Sandbox Code Playgroud)

接下来,我们将“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();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用内部 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!"));
}
Run Code Online (Sandbox Code Playgroud)

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