[Spring][TroubleShooting] WebSocket + React 연동시 SockJs & CORS 오류

CodeKong의 기술 블로그·2023년 9월 15일
3

SPRING BOOT

목록 보기
10/24
post-thumbnail

[진행중인 포스트입니다.]

지난 WebSocket을 스프링에서 구현한 이후 React와의 연동에서 발생한 오류들을 해결했습니다

링크 : https://velog.io/@joonoo3/Spring-WebSocket을-이용한-실시간-채팅


기존의 웹 브라우저는 request를 보내면 response를 받는 방식으로 이루어집니다.
그래서 클라이언트는 "요청을 보내야지만" 응답을 받을 수 있는 구조입니다.

하지만 요청을 보내지 않는 상황에서도 데이터를 받아야하는 상황이 있죠
실시간 채팅이나 알림이 그런 상황들 입니다.

#환경 1. SockJS

SockJS는 WebSocket을 지원하지 않는 브라우저에서 polling과 같은 여러 기술들을 테스트하여 WebSocket과 비슷한 동작을 할 수 있도록 지원해줍니다.

또한 heartbeat 메세지를 통해 연결을 유지합니다.

지난 post에서는 stomp까지 사용하였습니다!!


먼저 react에서 작성한 오류 코드 입니다.

const client = useRef({});

// 소켓 연결
const connect = () => {
        
        client.current = Stomp.over(() => {
            const sock = new SockJS('ws://localhost:8080/ws');
            return sock;
        });
        client.current.connect(
            {},
            () => {
                // callback 함수로 sub을 해줍니다.
                client.current.subscribe(
                    '/sub/chat/1',
                    (message) => {
                       
                      ---console.log(message.body);
                        sendChat();
                    },
                    {
                       //header
                    }
                );
            }
        );
    };

1. useRef

client의 값이 바뀌어도 불필요한 랜더링을 하지 않기 위해서 useRef를 사용했습니다.


2. SockJs

SockJs("주소")를 기반으로 sockJs 객체를 생성하였습니다.

여기가 첫번째 trouble이 발생한 부분입니다.


Trouble 1. ws://localhost:8080/ws

지금은 알지만 며칠동안 반복되는 오류와 구글링을 하며 간과하고 있던 점이 있었습니다.

먼저 지난 포스트의 spring에서의 WebSocket Config 부분중 일부입니다.

 @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }

여기서 addEndpoint("/ws")는 ws://localhost:8080/ws 라고 생각했습니다.

하지만 이는 "http://localhost:8080/ws"를 통해 handshaking을 하고 ws://~ 을 통해 통신하는 것이였습니다.

# 수 많은 오류들 중 가끔 보이던 오류였지만 생각을 못하고 있었다,,


Trouble 2. cors

지난 포스트에서 setAllowedOriginPatterns("*")를 사용해주었지만 여전히 해결해주지 못해 proxy 설정을 해주었습니다!

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = (app) => {
    app.use(
        "/api",
        createProxyMiddleware({
            target: "http://localhost:8080",
            changeOrigin: true,
        })
    );
    app.use(
        "/ws",
        createProxyMiddleware({ target: "http://localhost:8080", ws: true })
    );
};

동작완료!!


사실 이 trouble 말고도 여러 오류가 발생했지만 막상 해결하고 이전 오류들을 발생시키고자 했을 때 막상 발생하지 않았습니다,,

주요 trouble은 1번 trouble로 해결이 된거같아 이 부분을 나중에 잘 기억하도록 하겠습니다~~~

0개의 댓글