저희는 사용자간 친구를 맺고 서로 채팅을 할 수 있는 기능을 추가해 사용자간 경기 매칭에 있어 원활한 소통을 할 수 있도록 했습니다.

이 과정에서 친구를 맺고 끊고 하는 부분이 실시간으로 반영되면 좋을 거 같다는 생각을 하게 되었고

기존 새로고침을 해야 반영되었던 부분을 WebSocket을 통해 실시간 반영되도록 수정했습니다.

채팅 기능 또한 WebSocket을 사용해 실시간 소통이 가능하도록 하였습니다.

처음 시도한 방법은 어노테이션을 활용한 방법이였습니다.

Annotation 설명
@OnOpen 클라이언트가 접속할 때마다 실행
@OnMessage 메세지 수신 시
@OnClose 클라이언트가 접속을 종료할 시

위와 같은 세개의 어노테이션을 통해 사용자가 @ServerEndpoint 로 지정해 놓은 경로로 최초 접속시 @OnOpen 을 붙인 메서드로 접속되게 되고 사용자에게 세션을 발급합니다.

@OnOpen
public void onOpen(Session session) {
    if(!clients.contains(session)) {
        clients.add(session);
    }
}

이후 메세지가 들어오면 @OnMessage 가 해당 메세지를 수신하고 세션이 발급된 사용자에게 해당 메시지를 전달해줍니다.

@OnMessage
public void onMessage(String message, Session session) throws IOException {
  for(Session s : clients) {
      s.getBasicRemote().sendText(message);
  }

처음에는 위 방법을 사용해 실시간으로 반영될 수 있도록 구현했으나, 이 경우 1대다 통신이 되기 때문에 내가 지정한 상대가 아닌 다른 사용자 또한 변경에 대한 메세지를 받게 되기 때문에 불편함을 줄 수 있다는 문제점이 있었습니다.

그래서 두번째로 시도한 방법은 아래와 같은 방법이였습니다.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/friend").setAllowedOrigins("<http://localhost:3000>").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {

        registry.enableSimpleBroker("/queue");
        registry.setApplicationDestinationPrefixes("/app");

    }
}

저희는 리액트를 통해 3000포트에서 요청을 받기 때문에 해당 경로로 접근이 가능하도록 설정해줍니다.

그 후 /topic/queue 를 통해 1대다, 1대1로 설정이 가능합니다. 친구 기능의 경우 1대다 소통이 필요하지 않기 때문에 1대1 통신만을 가능하도록 설정했습니다.