본문 바로가기

백엔드/메세지 브로커

Redis를 채팅 기능에 적용하며 겪은 시행착오들

반응형

**개요

- 채팅 기능을 처음 구현해보면서 많은 시행착오를 겪었다.

있었던 문제점들과 해결방법들을 공유하려한다.

 

  • Web Socket을 이용하여 구현 > 브라우저간 호환 문제, 지나치게 많은 코드 (채팅 데이터 관리, 채팅방 입장 등등)
  • SockJS와 STOMP를 적용 > 많은 코드들이 절약됐지만, 단일 서버 통신, MySql로 데이터를 관리하다보면 성능 면에서 Redis와의 차이, 채팅 데이터가 날아가는 문제
  • Redis 적용 > stomp broker 설정으로만 채팅이 될 줄 알았지만 클라이언트가 서로 다른 서버에 연결이 됬을때 채팅을 하려면 redis가 필요했다. 또한 인-메모리 기반의 캐시가 디스크에 접근하는 기존의 RDB보다 성능이 좋았다.

나는 마지막의 이유 때문에 Redis라는 것을 적용해서 채팅 기능을 구현했고, 현재 서비스 런칭 직전이다.

 

** 에러 종류

access-control-allow-origin' header is present on the requested resource


권한 문제다. CORS 문제 해결을 해야 웹소켓을 정상적으로 열어서 통신할 수 있는데,

나는 총 3가지 부분을 수정해주어서 프론트단과 협업했다.

@Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://triplan.co.kr"));
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        configuration.setAllowCredentials(true);

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

스프링 시큐리티를 적용했다면, 이렇게 빈으로도 등록을 따로 해주어야한다.

 

 

 

 

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .exposedHeaders("authorization", "refreshToken");
    }
}

만약 헤더 값에 담긴 토큰을 인식하지 못 할 수도 있기에, 위와 같이 CorsConfig에도 열어주도록 하자.

(모두다 열어주었는데, 보안상 좋지 못한 것은 인지하고 있다. 이를 감안해서 어느 것을 허용해줄지는 각자 정해보자.)

 

 

 

@Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 클라이언트에서 websocket을 연결할 api를 설정
        // 채팅 포인트
        registry.addEndpoint("/endpoint")
                .setAllowedOrigins("https://triplan.co.kr")
                .withSockJS();
        // 알림 포인트
        registry.addEndpoint("/alarmpoint")
                .setAllowedOrigins("https://triplan.co.kr")
                .withSockJS();
    }
ChannelInterceptor

위의 친구를 implement하는 STOMPHANDLER를 사용한다면, 각각의 엔드포인트들에도 Origin을 추가해주자.

 

 

 

이로써 총 3가지에 달하는 것들에 모두 권한 설정을 해주었고, 그 후에야 통신이 원활하게 되었다.

누군가에게는 도움이 되었기를 바란다.

 

 

 

** 참고 블로그

 

https://velog.io/@jifrozen/Dining-together-web-socket-stomp-spring-boot-Redis-%EB%A1%9C-rest-%EC%B1%84%ED%8C%85%EC%84%9C%EB%B9%84%EC%8A%A4-micro-service

 

[Dining-together] web socket && stomp && spring boot && Redis 로 rest 채팅서비스 (micro service)

WebSocket은 서버와 클라이언트 간에 Socket Connection을 유지해서 언제든 양방향 통신 또는 데이터 전송이 가능하도록 하는 기술이다.Real-time web application구현을 위해 널리 사용되어지고 있다. (SNS어플

velog.io

 

 

반응형