1. 소개

 
이 예제에서는

Spring WebSocket을 사용하여 단일 사용자에게 STOMP 메시지를 보내는

방법을 설명합니다 . 우리는 때때로 모든 메시지를 모든 사용자에게 브로드캐스트하고 싶지 않기 때문에 이는 중요합니다. 그 외에도 이러한 메시지를 안전한 방법으로 보내는 방법을 보여줍니다.WebSocket에 대한 소개  는 시작 및 실행 방법에 대한

훌륭한 사용방법(예제)를 확인하십시오 . 그리고 Security에 대해 더 자세히 알아보려면 

 문서에서 WebSocket 구현을 보호하세요.

2. 대기열, 주제 및 끝점

 
 Spring WebSocket과 STOMP

사용하여 메시지가 전송되는 위치와 구독 방법을 말하는 세 가지 주요 방법 이 있습니다 .
  1. 주제 – 모든 클라이언트 또는 사용자에게 열려 있는 일반적인 대화 또는 채팅 주제
  2. 대기열 – 특정 사용자 및 현재 세션용으로 예약됨
  3. 엔드포인트 – 일반 엔드포인트
이제 각각에 대한 예제 컨텍스트 경로를 간단히 살펴보겠습니다.
  • “/주제/영화”
  • "/사용자/대기열/특정 사용자"
  • "/Security/채팅"

 토픽과 엔드포인트가 이 기능을 지원하지 않기 때문에 특정 사용자에게 메시지를 보내려면 큐를 사용해야

한다는 점에 유의하는 것이 중요 합니다 .

3. 구성

 
이제 특정 사용자에게 메시지를 보낼 수 있도록 애플리케이션을 구성하는 방법을 알아보겠습니다.
public class SocketBrokerConfig extends 
  AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/secured/user/queue/specific-user");
        config.setApplicationDestinationPrefixes("/spring-security-mvc-socket");
        config.setUserDestinationPrefix("/secured/user");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/secured/room").withSockJS();
    }
}

단일 사용자를 위해 예약된 끝점을 결정하므로 사용자 대상을 포함해야 합니다.

또한 인증을 요구하도록 모든 대기열과 사용자 대상에

"/secured"

접두사를 붙 입니다. 보호되지 않는 끝점의 경우

"/secured"

접두사를 삭제할 수 있습니다 (다른 Security 설정의 결과).A로부터

의 pom.xml

관점, 추가 의존성이 필요하지 않습니다.

4. URL 매핑

 
우리는 클라이언트가 다음 패턴을 준수하는 URL 매핑을 사용하여 대기열을 구독하기를 원합니다.
"/user/queue/updates"
이 매핑은

UserDestinationMessageHandler

 에 의해 사용자 세션별 주소로 자동 변환됩니다 .예를 들어

"user123"

이라는 사용자가 있는 경우 해당 주소는 다음과 같습니다.
"/queue/updates-user123"
서버 측에서는 다음 URL 매핑 패턴을 사용하여 사용자별 응답을 보냅니다.
"/user/{username}/queue/updates"
이것도 이미 클라이언트 측에서 구독한 올바른 URL 매핑으로 변환됩니다.따라서 여기에서 필수 성분이 두 가지 임을 알 수

있습니다.

  1. 지정된 사용자 대상 접두사를 앞에 추가합니다( AbstractWebSocketMessageBrokerConfigurer 에 구성됨  ).
  2. 매핑 내의 어딘가에 "/queue"를 사용하십시오  .
다음 섹션에서는 이 작업을 수행하는 방법을 정확히 살펴보겠습니다.

5. convertAndSendToUser() 호출 

 
SimpMessagingTemplate 또는  SimpMessageSendingOperations   에서 비정적으로

convertAndSendToUser()

를  호출할 수 있습니다 .
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

@MessageMapping("/secured/room") 
public void sendSpecific(
  @Payload Message msg, 
  Principal user, 
  @Header("simpSessionId") String sessionId) throws Exception { 
    OutputMessage out = new OutputMessage(
      msg.getFrom(), 
      msg.getText(),
      new SimpleDateFormat("HH:mm").format(new Date())); 
    simpMessagingTemplate.convertAndSendToUser(
      msg.getTo(), "/secured/user/queue/specific-user", out); 
}
당신은 다음과 같은 사실을 눈치 챘을 것입니다.
@Header("simpSessionId") String sessionId

@Header의 어노테이션 인바운드 메시지에 의해 노출 헤더에 액세스 할 수 있습니다.

예를 들어  복잡한 인터셉터 없이 현재

sessionId

가져올 수 있습니다 . 마찬가지로 Principal 을

통해 현재 사용자에 액세스할 수 있습니다 .

중요하게도 이 기사에서 우리가 취하는 접근 방식은 URL 매핑과 관련 하여

@sendToUser

어노테이션 보다 더 큰 사용자 정의를 제공 합니다. 해당 어노테이션에 대한 자세한 내용은

훌륭한 기사를 확인  하십시오.클라이언트 측에서는 JavaScript에서

connect()

사용  하여 SockJS 인스턴스 를 

초기화하고 STOMP를 사용하여 WebSocket 서버에 연결합니다.

var socket = new SockJS('/secured/room'); 
var stompClient = Stomp.over(socket);
var sessionId = "";

stompClient.connect({}, function (frame) {
    var url = stompClient.ws._transport.url;
    url = url.replace(
      "ws://localhost:8080/spring-security-mvc-socket/secured/room/",  "");
    url = url.replace("/websocket", "");
    url = url.replace(/^[0-9]+\//, "");
    console.log("Your current session is: " + url);
    sessionId = url;
}
또한 제공된

sessionId에

액세스하여 "

secured/room " 

 URL 매핑에 추가합니다.

이를 통해 사용자별 구독 대기열을 동적으로 수동으로 제공할 수 있습니다.

stompClient.subscribe('secured/user/queue/specific-user' 
  + '-user' + that.sessionId, function (msgOut) {
     //handle messages
}
모든 것이 설정되면 다음이 표시됩니다.

 

그리고 서버 콘솔에서:

6. 결론

 
 이 주제에 대한 자세한 내용은 공식 Spring

블로그

공식 문서

를 확인하십시오.항상 그렇듯이 이 문서에 사용된 코드 샘플은

GitHub에서

사용할 수 있습니다 .
Generic footer banner