// 메시지 브로커가 지원하는 WebSocket 메시지 처리 활성화
@EnableWebSocketMessageBroker
@Configuration
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
// 소켓 연결과 관련된 설정
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/{endpoint}") // Handshake와 통신을 담당할 endpoint 지정
// cors 허용
.setAllowedOriginPatterns("로컬경로", "서버경로") // 서버 경로
.withSockJS(); // 소켓을 지원하지 않을 경우 대체
}
// stomp 사용을 위한 메시지 브로커 설정
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// 메시지를 보낼 때, 관련 경로를 설정해주는 함수
config.setApplicationDestinationPrefixes("/pub");
// 메시지를 받을 때, 경로를 설정해주는 함수
/* **/sub** , “/topic”가 api에 prefix로 붙은 경우, **messageBroker**가 해당 경로를 가로챔 */
config.enableSimpleBroker("/sub");
// 발행된 순서를 보존할지 결정
config.setPreservePublishOrder(true);
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration){
registration.interceptors(stompHandler);
}
}
Controller 구현
@Controller
@RequiredArgsConstructor
@CrossOrigin(origins = "*", allowCredentials = "true")
@Slf4j
public class StompPersonalChatController {
// 개인 메시지 전송
//stompConfig에서 설정한 applicationDestinationPrefixes와 @MessageMapping 경로가 병합됨
@MessageMapping(value = "/{endpoint}/send/{roomId}") // 메시지 전송 경로 설정
public void sendMessage(@DestinationVariable String personalChatId, Message messageReq)
throws IOException {
log.debug("[StompChatController - sendMessage]: room id = {}", roomId);
Message message = messageService.registMessage(roomId, messageReq);
template.convertAndSend("/sub/" + roomId, message); // 구독중인 다른 사용자들에게 해당 메시지 전송
}
Spring Security
jwt 인증시 websocket은 인증 방식을 다르게 설정하므로, 기존 jwt 인증 filter에서 websocket은 제외