Loading...
Spring Framework Reference Documentation 7.0.2의 User Destinations의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
애플리케이션은 특정 user를 대상으로 하는 message를 전송할 수 있으며, Spring의 STOMP 지원은 이 목적을 위해 /user/ prefix가 붙은 destination을 인식합니다.
예를 들어, client는 /user/queue/position-updates destination을 subscribe할 수 있습니다.
UserDestinationMessageHandler는 이 destination을 처리하고 이를 user session에 고유한 destination(예: /queue/position-updates-user123)으로 변환합니다.
이는 일반적인 이름의 destination에 subscribe하는 편의성을 제공하는 동시에, 동일한 destination에 subscribe하는 다른 user와 충돌이 발생하지 않도록 하여 각 user가 고유한 주식 포지션 업데이트를 받을 수 있게 합니다.
user destination을 사용할 때는 Enable STOMP에 나와 있는 것처럼 broker와<br>애플리케이션 destination prefix를 설정하는 것이 중요합니다. 그렇지 않으면<br>broker가 원래는
UserDestinationMessageHandler만 처리해야 하는 "/user" prefix가 붙은 message를<br>처리하게 됩니다.
전송 측에서는 /user/{username}/queue/position-updates와 같은 destination으로 message를 전송할 수 있으며, 이는 UserDestinationMessageHandler에 의해 user와 연결된 각 session마다 하나씩 하나 이상의 destination으로 변환됩니다.
이는 애플리케이션 내의 어떤 컴포넌트든, 이름과 일반적인 destination 외에는 아무것도 알 필요 없이 특정 user를 대상으로 하는 message를 전송할 수 있게 해 줍니다. 이는 어노테이션과 messaging 템플릿을 통해서도 지원됩니다.
message를 처리하는 메서드는 다음 예제에서 보듯이, 처리 중인 message와 연결된 user에게 @SendToUser 어노테이션(공통 destination을 공유하기 위해 클래스 레벨에서도 지원됨)을 통해 message를 전송할 수 있습니다:
1@Controller 2public class PortfolioController { 3 4 @MessageMapping("/trade") 5 @SendToUser("/queue/position-updates") 6 public TradeResult executeTrade(Trade trade, Principal principal) { 7 // ... 8 return tradeResult; 9 } 10}
user에게 둘 이상의 session이 있는 경우, 기본적으로 주어진 destination에 subscribe한 모든 session이 대상이 됩니다. 그러나 때로는 처리 중인 message를 전송한 session만을 대상으로 해야 할 필요가 있을 수 있습니다.
다음 예제에서 보듯이, broadcast 속성을 false로 설정하여 그렇게 할 수 있습니다:
1@Controller 2public class MyController { 3 4 @MessageMapping("/action") 5 public void handleAction() throws Exception{ 6 // raise MyBusinessException here 7 } 8 9 @MessageExceptionHandler 10 @SendToUser(destinations="/queue/errors", broadcast=false) 11 public ApplicationError handleException(MyBusinessException exception) { 12 // ... 13 return appError; 14 } 15}
일반적으로 user destination은 인증된 user를 의미하지만, 엄격하게 요구되는 것은 아닙니다.<br>인증된 user와 연결되지 않은 WebSocket session도<br>user destination을 subscribe할 수 있습니다. 이런 경우,
@SendToUser어노테이션은<br>broadcast=false일 때와 정확히 동일하게 동작합니다 (즉, 처리 중인 message를 전송한<br>session만을 대상으로 합니다).
Java 설정 또는 XML 네임스페이스에 의해 생성된 SimpMessagingTemplate을 주입하는 방식으로, 어떤 애플리케이션 컴포넌트에서든 user destination으로 message를 전송할 수 있습니다. (bean 이름은 @Qualifier로 한정해야 하는 경우 brokerMessagingTemplate입니다.) 다음 예제는 그 방법을 보여 줍니다:
1@Service 2public class TradeServiceImpl implements TradeService { 3 4 private final SimpMessagingTemplate messagingTemplate; 5 6 @Autowired 7 public TradeServiceImpl(SimpMessagingTemplate messagingTemplate) { 8 this.messagingTemplate = messagingTemplate; 9 } 10 11 // ... 12 13 public void afterTradeExecuted(Trade trade) { 14 this.messagingTemplate.convertAndSendToUser( 15 trade.getUserName(), "/queue/position-updates", trade.getResult()); 16 } 17}
external message broker와 함께 user destination을 사용할 때는 user session이<br>종료되었을 때 모든 고유한 user queue가 제거되도록, 비활성 queue를 어떻게 관리하는지에 대해<br>broker 문서를 확인해야 합니다. 예를 들어, RabbitMQ는
/exchange/amq.direct/position-updates와 같은 destination을 사용할 때<br>auto-delete queue를 생성합니다.<br>따라서 그 경우 client는/user/exchange/amq.direct/position-updates를 subscribe할 수 있습니다.<br>유사하게, ActiveMQ에는<br>비활성 destination을 정리하기 위한<br>설정 옵션이 있습니다.
멀티 애플리케이션 서버 시나리오에서, user가 다른 서버에 연결되어 있기 때문에 user destination이 resolve되지 않은 상태로 남을 수 있습니다. 이런 경우, 다른 서버가 시도해 볼 수 있도록 resolve되지 않은 message를 broadcast하는 destination을 설정할 수 있습니다.
이는 Java 설정에서 MessageBrokerRegistry의 userDestinationBroadcast 속성과 XML에서 message-broker 요소의 user-destination-broadcast 속성을 통해 수행할 수 있습니다.
Authorization
Order of Messages