본문 바로가기
프로젝트/USports

[USports] Websocket 구현

by JayAlex07 2023. 12. 25.

[USports] Websocket 구현

 

 

build.gradle

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'

 

WebSocketConfig

@Configuration
@EnableWebSocketMessageBroker // STOMP를 사용 안 하고 EnableWebSocket으로 사용할 수 있다
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry
                .addEndpoint("/ws/chat")  // URL 또는 URI
                .setAllowedOriginPatterns("*")
                .withSockJS(); // 소켓을 지원하지 않는 브라우저라면, sockJS를 사용
    }
    // message 브로커를 활성화 시키는 설정
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 메세지 구독 url (topic을 구독)
        registry.enableSimpleBroker("/sub"); // topic
        // 메세지 발행 url
        registry.setApplicationDestinationPrefixes("/pub"); //
    }
}
  • STOMP를 사용 안 하고 WebSocket만 사용할 때에는 @EnableWebSocket 어노테이션을 사용해도 된다
  • registerStompEndpoints
    • 해당 endpoint를 설정함으로서, 웹소켓과 연결하기 위한 endpoint를 설정해주는 것이다
  • configureMessageBroker
    • 브로커, 즉 구독과 발행을 할 수 있도록 브로커를 활성화 시키는 설정이다
    • enableSimpleBroker
      • 클라이언트가 서버로 메세지를 보내는 URI 다
    • setApplicationDestinationPrefixes
      • 구독 경로를 설정할 수 있다
      • 구독 경로를 설정하는 것은, 같은 채팅방에 구독되어 있는 유저만 메세지를 받을 수 있다

 

  • 노란색 : 클라이언트가 메세지를 보내게 된다
  • 초록색 : 클라이언트가 설정한 특정 구독 ID (여기에서는 chatroomId = chatId)를 통해서, 어느 채팅방에 메세지를 보낼지 알 수 있다

 

 

ChatController

@RestController
@RequiredArgsConstructor
@Slf4j
public class ChatController {

    private final SimpMessageSendingOperations template;

    /**
     * 메세지를 보낼 때
     */
    @MessageMapping("/chat/message/{chatRoomId}")
    public void sendMessage(
            ChatMessageDto chat,
        	@DestinationVariable Long chatRoomId
    ) {
         return chatMessageDto;
        log.info("Chat {}", chat);
        chat.setContent(chat.getContent());
        template.convertAndSend("/sub/chat/room/" + chat.getChatRoomId(), chat);
    }

    @MessageMapping("chat/enter/{chatRoomId}")
    public void addUser(
            ChatMessageDto chat,
        	@DestinationVariable Long chatRoomId
    ) {
        // Add username in WebSocket session
        headerAccessor.getSessionAttributes().put("username", chatMessageDto.getSender());
        return chatMessageDto;
        log.info("{} 입장", chat.getSender());
        chat.setContent(chat.getSender() + "님이 입장하셨습니다");
        template.convertAndSend("/sub/chat/room/" + chat.getChatRoomId(), chat);
    }
}
  • MessageMapping
    • /pub/chat... 형태로 해당 메세지를 발행해준다
  • SimpleMessageSendingOperations
    • STOMP 같이, 매세지를 보내는 작업에 특화된 인터페이스다. MessageSendingOperation을 특화한 것 (docs.spring)
    • MessageSendingOperations : 특정 도착지에 메세지를 보내는 인터페이스다

 

채팅방 만들기

 

위의 작업은 '채팅' 기능을 구현하는 것이다

 

제대로된 채팅 기능을 구현하기 위해서는 추가로 채팅방을 만들어야 하고, 이것은 간단한 CRUD로 만들 수 있다

 

'채팅방'에 들어가면, 그 방 안에서, 위에서 구현한 채팅 기능을 넣어주면 된다

 


 

 

RabbitMQ, Kafka?

 

외부 브로커다

 

STOMP만 사용했을 경우, 이용자 수가 적으면 성능적으로 문제가 없다

  • 하지만, 이용자 수가 증가하고 데이터가 많아지면 STOMP가 내장하고 있는 SimpleBroker는 Spring Boot가 실행되는 공의 메모리를 잡아 먹을 수 있다 (즉 서버에 부담을 가지게 되는 것이다)

 

Spring Docs

  • You can (optionally) use message brokers (such as RabbitMQ, ActiveMQ, and others) to manage subscriptions and broadcast messages.
  • 구독과 메세지를 전달하는데에 선택적으로 메세지 브로커들을 사용할 수 있다

'프로젝트 > USports' 카테고리의 다른 글

[USports] Spring AWS 배포  (0) 2024.01.14
[USports] Member OAuth with 프론트엔드  (0) 2024.01.11
[USports] Websocket 소개  (0) 2023.12.18
[USports] Member OAuth2  (0) 2023.12.09
[USports] Member 단위 테스트  (1) 2023.12.07