Spring websocket send to specific people

前端 未结 2 1661
醉梦人生
醉梦人生 2020-12-23 18:02

I have added custom token based authentication for my spring-web app and extending the same for spring websocket as shown below

public class WebSocketConfig          


        
相关标签:
2条回答
  • 2020-12-23 18:29

    In your Websocket controller you should do something like this :

    @Controller
    public class GreetingController {
    
        @Autowired
        private SimpMessagingTemplate messagingTemplate;
    
        @MessageMapping("/hello")
        public void greeting(Principal principal, HelloMessage message) throws  Exception {
            Greeting greeting = new Greeting();
            greeting.setContent("Hello!");
            messagingTemplate.convertAndSendToUser(message.getToUser(), "/queue/reply", greeting);
        }
    }
    

    On the client side, your user should subscribe to topic /user/queue/reply.

    You must also add some destination prefixes :

    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableSimpleBroker("/topic", "/queue" ,"/user");
            config.setApplicationDestinationPrefixes("/app");
            config.setUserDestinationPrefix("/user");
        }
    /*...*/
    }
    

    When your server receive a message on the /app/hello queue, it should send a message to the user in your dto. User must be equal to the user's principal.

    I think the only problem in your code is that your "/user" is not in your destination prefixes. Your greetings messages are blocked because you sent them in a queue that begin with /user and this prefixe is not registered.

    You can check the sources at git repo : https://github.com/simvetanylen/test-spring-websocket

    Hope it works!

    0 讨论(0)
  • 2020-12-23 18:46

    In my previous project I sent messages to one specific user; in detail I wrote the following:

    CLIENT SIDE:

    function stompConnect(notificationTmpl) 
    {
        var socket = new SockJS('/comm-svr');
        stompClient = Stomp.over(socket);
        var theUserId 
        stompClient.connect({userId:theUserId}, function (frame) {
                debug('Connected: ' + frame);
                stompClient.subscribe('/topic/connect/'+theUserId, function (data)                   {
    //Handle data
                  } 
            });
    }
    

    SERVER SIDE

    Spring websocket listener:

    @Component
    public class WebSocketSessionListener
    {
        private static final Logger logger = LoggerFactory.getLogger(WebSocketSessionListener.class.getName());
        private List<String> connectedClientId = new ArrayList<String>();
    
        @EventListener
        public void connectionEstablished(SessionConnectedEvent sce)
        {
            MessageHeaders msgHeaders = sce.getMessage().getHeaders();
            Principal princ = (Principal) msgHeaders.get("simpUser");
            StompHeaderAccessor sha = StompHeaderAccessor.wrap(sce.getMessage());
            List<String> nativeHeaders = sha.getNativeHeader("userId");
            if( nativeHeaders != null )
            {
                String userId = nativeHeaders.get(0);
                connectedClientId.add(userId);
                if( logger.isDebugEnabled() )
                {
                    logger.debug("Connessione websocket stabilita. ID Utente "+userId);
                }
            }
            else
            {
                String userId = princ.getName();
                connectedClientId.add(userId);
                if( logger.isDebugEnabled() )
                {
                    logger.debug("Connessione websocket stabilita. ID Utente "+userId);
                }
            }
        }
    
        @EventListener
        public void webSockectDisconnect(SessionDisconnectEvent sde)
        {
            MessageHeaders msgHeaders = sde.getMessage().getHeaders();
            Principal princ = (Principal) msgHeaders.get("simpUser");
            StompHeaderAccessor sha = StompHeaderAccessor.wrap(sde.getMessage());
            List<String> nativeHeaders = sha.getNativeHeader("userId");
            if( nativeHeaders != null )
            {
                String userId = nativeHeaders.get(0);
                connectedClientId.remove(userId);
                if( logger.isDebugEnabled() )
                {
                    logger.debug("Connessione websocket stabilita. ID Utente "+userId);
                }
            }
            else
            {
                String userId = princ.getName();
                connectedClientId.remove(userId);
                if( logger.isDebugEnabled() )
                {
                    logger.debug("Connessione websocket stabilita. ID Utente "+userId);
                }
            }
        }
    
        public List<String> getConnectedClientId()
        {
            return connectedClientId;
        }
        public void setConnectedClientId(List<String> connectedClientId)
        {
            this.connectedClientId = connectedClientId;
        }
    }
    

    Spring websocket message sender:

    @Autowired
        private SimpMessagingTemplate msgTmp;
        private void propagateDvcMsg( WebDeviceStatusInfo device )
        {
            String msg = "";
            String userId =((Principal)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName()
            msgTmp.convertAndSend("/topic/connect"+userId, msg);
        }
    

    I hope it's useful

    0 讨论(0)
提交回复
热议问题