복붙노트

[SPRING] spring websocket에 연결할 때 사용자에게 메시지를 보내는 방법

SPRING

spring websocket에 연결할 때 사용자에게 메시지를 보내는 방법

스프링 websocket에 연결할 때 사용자에게 메시지를 보내고 싶습니다.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Autowired
    private GenervicSerice<User> userService;
    @Autowired 
    private SimpMessagingTemplate template; 
    private CurrentUser currnetUser;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        // TODO Auto-generated method stub
        stompEndpointRegistry.addEndpoint("/ws").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/queue/", "/topic/", "/exchange/");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {

        registration.setInterceptors(myChannelInterception());
        try {
            updateNotificationAndBroadcast();

        } catch (Exception e) {
            return;
        }
    }

    @Bean
    public MyChannelInterception myChannelInterception() {
        return new MyChannelInterception();
    }


    private void updateNotificationAndBroadcast() {    
        try {               
            template.convertAndSend("/queue/notify", "Greetings");
        } catch (Exception e) {
            System.out.println("Error message is " + e.getMessage() + "\n\n\n" + "Caused by " + e.getCause()
                    );
        }

    }

}

MyChannelInterception 클래스

public class ImtehanChannelInterception extends ChannelInterceptorAdapter {     

    private CurrentUser currnetUser;

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {

        MessageHeaders headers = message.getHeaders();
        SimpMessageType type = (SimpMessageType) headers.get("simpMessageType");
        String simpSessionId = (String) headers.get("simpSessionId");
        currnetUser = new CurrentUser();
        if (type == SimpMessageType.CONNECT) {
            Principal principal = (Principal) headers.get("simpUser");
            currnetUser.setCurrentUserEmail(principal.getName());
            System.out.println("WsSession " + simpSessionId
                    + " is connected for user " + principal.getName());
        } else if (type == SimpMessageType.DISCONNECT) {
            System.out.println("WsSession " + simpSessionId
                    + " is disconnected");
        }

        return message;
    }

}

이를 통해 새로운 연결된 사용자에 대한 정보를 얻을 수 있지만 WebSocketConfig의 updateNotificationAndBroadcast () 메소드는 새로운 로그인 한 사용자에게 메시지를 보내지 않습니다.

해결법

  1. ==============================

    1.SessionSubscribeEvent 리스너를 만들고 SimpMessagingTemplate을 내부적으로 사용합니다.

    SessionSubscribeEvent 리스너를 만들고 SimpMessagingTemplate을 내부적으로 사용합니다.

    Btw, configureClientInboundChannel은 한 번만 호출됩니다 (연결된 모든 사용자가 아님). 따라서 인터셉터 내부에서 메시지를 보내야합니다.

    다음과 같이 시도해보십시오.

    @Service
    public class SomeSubscribeListener {
    
        private SimpMessagingTemplate template;
    
        @Autowired
        public SomeSubscribeListener(SimpMessagingTemplate template) {
            this.template = template;
        }
    
        @EventListener
        public void handleSubscribeEvent(SessionSubscribeEvent event) {
            template.convertAndSendToUser(event.getUser().getName(), "/queue/notify", "GREETINGS");
        }
    }
    

    이게 도움이되기를 바랍니다.

  2. ==============================

    2.Websocketconfig 파일이 필요합니다.

    Websocketconfig 파일이 필요합니다.

    package mx.config.ws;
    @EnableScheduling
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
       @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
           registry.addEndpoint("/chat").withSockJS()
        }
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
        ...
        }
    }
    

    그리고 nother @Configuration 파일을 선언하십시오.

    package mx.config.ws;
    @Configuration
    public class WebSocketHandlersConfig {
    
        @Bean
        public StompConnectEvent webSocketConnectHandler() {
            return new StompConnectEvent();
        }
    
        @Bean
        public StompDisconnectEvent webSocketDisconnectHandler() {
            return new StompDisconnectEvent();
        }
    }
    

    다음으로 ApplicationListener 인터페이스 구현을 작성하십시오. 자동으로 STOMP 연결을 차단합니다.

    package mx.config.ws;
    public class StompConnectEvent implements ApplicationListener<SessionConnectEvent> {
    
        @Override
        public void onApplicationEvent(SessionConnectEvent event) {
    
             StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
    
             System.out.println("StompConnectEvent::onApplicationEvent()    sha.getSessionId(): "+sha.getSessionId()+" sha.toNativeHeaderMap():"+sha.toNativeHeaderMap());
    
    
             //String  company = sha.getNativeHeader("company").get(0);
             //logger.debug("Connect event [sessionId: " + sha.getSessionId() +"; company: "+ company + " ]");
    
    
    
             // HERE YOU CAN MAYBE SEND A MESSAGE
    
        }
    
    }
    

    정보 링크를 확인하려면 다음 링크를 확인하십시오. http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in-spring-4/

  3. from https://stackoverflow.com/questions/37340271/how-to-send-message-to-user-when-he-connects-to-spring-websocket by cc-by-sa and MIT license