Spring中的@SendToUser是不是仅在集成了Spring Security时才有效?

Posted

技术标签:

【中文标题】Spring中的@SendToUser是不是仅在集成了Spring Security时才有效?【英文标题】:Does @SendToUser in Spring only works when Spring Security is integrated?Spring中的@SendToUser是否仅在集成了Spring Security时才有效? 【发布时间】:2018-10-23 11:51:37 【问题描述】:

我开始使用带有 springboot 的 websockets。所以起初我成功地创建了一个演示聊天应用程序,其中消息被广播给每个用户。 现在,我不想向所有用户广播消息,而是想向一个特定用户发送消息,所以我偶然发现了 @SendToUser 注释。现在,我无法弄清楚这个注释是如何工作的。我的应用程序目前缺少任何类型的注册过程,包括 Spring Security 框架。

谁能给我一些关于这个主题的好文章,是否可以在不实现 Spring Security 的情况下使用这个注释发送一对一的消息?

这是我到目前为止所做的:

//Controller
@Controller
public class MessageController


   @Autowired
   private SimpMessagingTemplate messagingTemplate;

   //This broadcasts to all users
   @MessageMapping("/send")
   @SendTo("/topic/greeting")
   public MessageBean send(MessageBean message)
   
      message.setDate( ZonedDateTime.now() );
      return message;
   

   //This is intended to particular user
   @MessageMapping("/message")
   @SendToUser("/topic/greeting")
   public MessageBean processMessage(@Payload MessageBean message)
   
      message.setDate( ZonedDateTime.now() );
      return message;
    

//WebSocket配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer


   /* (non-Javadoc)
    * @see org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer#configureMessageBroker(org.springframework.messaging.simp.config.MessageBrokerRegistry)
    */
   @Override
   public void configureMessageBroker( MessageBrokerRegistry config )
   
      config.enableSimpleBroker( "/topic/", "/queue/" );
      config.setApplicationDestinationPrefixes( "/app" );
      config.setUserDestinationPrefix("/user"); 
   

   /* (non-Javadoc)
    * @see org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer#registerStompEndpoints(org.springframework.web.socket.config.annotation.StompEndpointRegistry)
    */
   @Override
   public void registerStompEndpoints( StompEndpointRegistry registry )
   
      StompWebSocketEndpointRegistration registration = registry.addEndpoint( "/secretum" );
      registration.setHandshakeHandler( new DefaultHandshakeHandler()
      
         @SuppressWarnings("unused")
         public boolean beforeHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Map< String, String > attributes )
               throws Exception
         
            if ( request instanceof ServletServerHttpRequest )
            
               ServletServerHttpRequest servletRequest = ( ServletServerHttpRequest ) request;
               HttpSession session = servletRequest.getServletRequest().getSession();
               attributes.put( "sessionId", session.getId() );
            
            return true;

         

       );
      registration.setAllowedOrigins( "*" ).withSockJS();
   

//客户端:

var clentModule = angular.module('clentModule', []);

//Main Controller
clentModule.controller('clentController', function($scope) 
    var client;
    $scope.connectAndSubscribe = function()
    
        var url = "ws://localhost:8080/secretum/websocket";
        client = webstomp.client(url);
        connected = function()
        
            console.log("connected");
        

        var headers = ;
        client.connect(headers,function()
            console.log("successfuly connected");
            var subscription = client.subscribe("/topic/greetings",subscriptionCallback);
        );

        subscriptionCallback = function(data) 
            console.log("subscription data", data);
        

        //var subscription = client.subscribe("/topic/greetings",subscriptionCallback);
        //console.log(subscription);
    ;

    $scope.sendMessage = function()
    
        //var subscription = client.subscribe("/topic/greetings",subscriptionCallback);
        $scope.message = ;
        $scope.message.sender = "xyz";
        $scope.message.reciever = "abc";
        var sendObject = JSON.stringify($scope.message);
        client.send("/topic/greetings", priority: 9, sendObject);
    ;

);

我的问题来自客户端,我应该如何发送请求以向特定用户发送消息,因为我没有存储在服务器中的用户信息。所以这是我最初的问题,这个注释在没有弹簧安全性的情况下是否有效?

【问题讨论】:

【参考方案1】:

@Paras...一旦你有想法就看看这个

订阅时使用@SendToUser 并在队列前添加“/user/”(仅限订阅方)。休息很神奇:-)

代替

Java Server: @SendTo("/topic/showResult")

JS Client: stompClient.subscribe('/topic/showResult', function(calResult)  ....

使用:

Java Server: @SentToUser("/topic/showResult")

JS Client: stompClient.subscribe('/user/topic/showResult', function(calResult) ....

感谢@RS...

并覆盖

WebSocketMessageBrokerConfigurer 接口中的configureClientInboundChannel() 方法

【讨论】:

嗨@kumar,我做了一些编辑,并包含了我到目前为止所做的代码sn-p。

以上是关于Spring中的@SendToUser是不是仅在集成了Spring Security时才有效?的主要内容,如果未能解决你的问题,请参考以下文章

Spring 批处理作业应仅在 Spring 集成文件轮询器轮询文件后执行一次

Spring 批处理作业应仅在 Spring 集成轮询器之后执行一次

仅在 8080 上运行的 Spring Boot docker?

NextJS 是不是包含仅在包中的 getServerSideProps 中引用的库?

Android 中的 Fused Location Provider 是不是仅在启用数据的情况下工作?

如果部署在 HoloLens2 上,Unity 中的蒙面精灵和模板缓冲区是不是仅在一只眼睛上可见?