@Configuration
@EnableWebSocketMessageBroker
public class StompConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app"); // @MessageMapping 를 이용해서 메시지 수신할 destination prefix
config.enableSimpleBroker("/topic", "/queue"); // 위 목적 외 destination prefix
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// registry.addEndpoint("/helloworld"); // websocket
registry.addEndpoint("/helloworld").withSockJS(); // sockjs
}
}
@Controller
public class StompController {
@MessageMapping("/hello")
@SendTo("/topic/hello")
public ResDto basic(ReqDto request) {
return new ResDto(request.getMessage().toUpperCase(), LocalDateTime.now());
}
@MessageMapping("/multi")
@SendTo({"/topic/hello", "/topic/hello2"})
public ResDto nulti(ReqDto request) {
return new ResDto(request.getMessage().toUpperCase(), LocalDateTime.now());
}
@MessageMapping("/hello1")
@SendTo("/topic/hello")
public ResDto annotations(Message<ReqDto> message, MessageHeaders headers, ReqDto request) {
return new ResDto(request.getMessage().toUpperCase(), LocalDateTime.now());
}
@MessageMapping("/hello/{detail}")
@SendTo("/topic/hello")
public ResDto detail(@DestinationVariable("detail") String detail, ReqDto request) {
return new ResDto("[" + detail + "]_" + request.getMessage().toUpperCase(), LocalDateTime.now());
}
@MessageMapping("/sessions")
@SendToUser("/queue/sessions")
public ResSessionsDto sessions(ReqDto request, MessageHeaders headers) {
String sourceSessionId = headers.get("simpSessionId").toString();
return new ResSessionsDto(생략);
}
}
@Autowired
SimpMessagingTemplate messagingTemplate;
// @SendTo
messagingTemplate.convertAndSend("/topic/hello", resDto);
// @SendToUser
messagingTemplate.convertAndSendToUser(sourceSessionId, "/queue/sessions", resSessionsDto, createHeaders(sourceSessionId));
///////////////////////////////////////////////
MessageHeaders createHeaders(@Nullable String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}
@EventListener
public void listener(SessionConnectEvent sessionConnectEvent) {
log.info("sessionConnectEvent. {}", sessionConnectEvent);
}
@ControllerAdvice
public class StompExceptionHandler {
@MessageExceptionHandler
@SendTo("/topic/hello")
public String handleException(IOException exception, MessageHeaders headers) {
log.error("exception: {}", exception.getClass());
return "error!!";
}
}
https://docs.spring.io/spring-framework/reference/web/websocket.html
https://spring.io/guides/gs/messaging-stomp-websocket