1. 소개
Spring WebSocket을 사용하여 단일 사용자에게 STOMP 메시지를 보내는
방법을 설명합니다 . 우리는 때때로 모든 메시지를 모든 사용자에게 브로드캐스트하고 싶지 않기 때문에 이는 중요합니다. 그 외에도 이러한 메시지를 안전한 방법으로 보내는 방법을 보여줍니다.WebSocket에 대한 소개 는 시작 및 실행 방법에 대한 훌륭한 사용방법(예제)를 확인하십시오 . 그리고 Security에 대해 더 자세히 알아보려면 문서에서 WebSocket 구현을 보호하세요.2. 대기열, 주제 및 끝점
를
사용하여 메시지가 전송되는 위치와 구독 방법을 말하는 세 가지 주요 방법 이 있습니다 .- 주제 – 모든 클라이언트 또는 사용자에게 열려 있는 일반적인 대화 또는 채팅 주제
- 대기열 – 특정 사용자 및 현재 세션용으로 예약됨
- 엔드포인트 – 일반 엔드포인트
- “/주제/영화”
- "/사용자/대기열/특정 사용자"
- "/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 매핑
"/user/queue/updates"
이 매핑은
UserDestinationMessageHandler
에 의해 사용자 세션별 주소로 자동 변환됩니다 .예를 들어"user123"
이라는 사용자가 있는 경우 해당 주소는 다음과 같습니다."/queue/updates-user123"
서버 측에서는 다음 URL 매핑 패턴을 사용하여 사용자별 응답을 보냅니다.
"/user/{username}/queue/updates"
이것도 이미 클라이언트 측에서 구독한 올바른 URL 매핑으로 변환됩니다.따라서 여기에서 필수 성분이 두 가지 임을 알 수
있습니다.
- 지정된 사용자 대상 접두사를 앞에 추가합니다( AbstractWebSocketMessageBrokerConfigurer 에 구성됨 ).
- 매핑 내의 어딘가에 "/queue"를 사용하십시오 .
5. convertAndSendToUser() 호출
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
}
모든 것이 설정되면 다음이 표시됩니다.
그리고 서버 콘솔에서: