이제 stomp를 통해서 챗팅을 구현을 해보자
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:sockjs-client:1.1.2'
implementation 'org.webjars:stomp-websocket:2.3.3-1'
위 의존성들은 웹소켓을 사용할 수 있도록 해주는 패키지와 SockJS를 사용하게 하는 패키지, STOMP를 사용할 수 있도록 해주는 패키지 이다.
이 피키지들을 의존성 추가를 해준다.
package com.github.riset_backend.global.config.webSocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 구독 요청
registry.enableSimpleBroker("/sub");
// 발행
registry.setApplicationDestinationPrefixes("/send");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-stomp")
.setAllowedOrigins("*");
}
}
WebSocketMessageBrokerConfigurer를 구현체를 통해서 config 설정을 해준다.
그리고 @EnableWebSocketMessageBroker를 통해서 메세지 브로커를 활성화 시켜준다.
configureMessageBroker메소드는 STOMP에서 사용할 메세지 브로커를 설정하는 부분이다.
enableSimpleBroker메소드를 통해서 내장 메세지 브로커를 사용하겠다는 것을 의미하며 /sub 라는 prefix를 설정을 해주어서 이 prefix가 붙은 경로로 메세지를 보내면 메세지 브로커로 보내서 처리 후에 이를 구독하고 있는 구독자에게 전달을 해주는 설정이다.
setApplicationDestinationPrefixes메소드는 메세지가 가공이 될 수 있는 핸들러로 보낼 수 있는 설정이다. 그래서 이 prefix로 /send를 하면 이와 연결된 핸들러로 이동을 해서 메세지를 가공을 시킨다.
registerStompEndpoints메소드는 stomp의 엔드 포인트를 설정하는 메소드이다.
이 엔드포인트로 클라이언트와 서버와 웹소켓을 연결한다.
addEndpoint는 엔드 포인트의 이름을 설정을 하고 setAllowedOrigins는 어떤 도메인을 허용해 줄 지 설정을 하는 것이다.
참고로 *는 모든 도메인을 설정한다는 뜻이다.
package com.github.riset_backend.chating.controller;
import com.github.riset_backend.chating.dto.MessageSendDto;
import com.github.riset_backend.chating.dto.MongoMessageSendDto;
import com.github.riset_backend.chating.dto.chatDto.ChatResponseDto;
import com.github.riset_backend.chating.service.ChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RequiredArgsConstructor
@RestController
@Slf4j
public class ChatController {
private final SimpMessageSendingOperations messagingTemplate;
@MessageMapping("/chat/message/{roomId}")
public void message(@DestinationVariable("roomId") Long roomId, MessageSendDto messageSendDto) throws IOException {
messagingTemplate.convertAndSend("/sub/chat/message/" + roomId, messageSendDto);
}
}
stomp를 사용하면 message Handler를 controller로 사용하는 것이 가능하다.
@MessageMapping("")는 @RequestMapping처럼 경로를 설정을 해주면 설정한 경로로 메세지를 보낼 때
message메소드가 실행이 된다.
SimpMessageSendingOperations는 메세지를 전송해주는 역할로 convertAndSend를 통해서 지정된 주소로 메세지를 보내주는 역할을 한다.
이를 통해서 stomp를 사용하면 연결 주소마다 handler를 만들어줄 필요가 없다.