저희는 사용자간 친구를 맺고 서로 채팅을 할 수 있는 기능을 추가해 사용자간 경기 매칭에 있어 원활한 소통을 할 수 있도록 했습니다.
이 과정에서 친구를 맺고 끊고 하는 부분이 실시간으로 반영되면 좋을 거 같다는 생각을 하게 되었고
기존 새로고침을 해야 반영되었던 부분을 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 통신만을 가능하도록 설정했습니다.