파피루스

SockJs 적용하기 (React/typescript) 본문

Today I Learned/in dev

SockJs 적용하기 (React/typescript)

떼굴펜 2024. 12. 23. 16:38

WebSocket만 써보고 SockJs는 처음 써보기에, 하나씩 기록해보려 한다.

 

 

1. install sockjs-client

yarn add sockjs-client @types/sockjs-client

 

 

2. socket 연결부의 예제 코드 추가

import React, { useEffect, useRef, useState } from 'react';
import SockJS from 'sockjs-client';

const SocketTest = () => {
  const [messages, setMessages] = useState([]);
  const socketRef = useRef(null);

  useEffect(() => {
    socketRef.current = new SockJS('서버주소 넣는 곳');

    socketRef.current.onopen = () => {
      console.log('WebSocket onopen');
    };

    socketRef.current.onmessage = (e) => {
      const message = JSON.parse(e.data);
      console.log('WebSocket onMessage', message);
      setMessages((prevMessages) => [...prevMessages, message]);
    };

    socketRef.current.onclose = () => {
      console.log('WebSocket onClose');
    };

    return () => {
      socketRef.current.close();
    };
  }, []);

  return (
    <div className="flex flex-col py-10 justify-center items-center ">
      <h2>SockJs 테스트</h2>
      <div>
        {messages.map((msg, index) => (
          <p key={`${index * 1}`}>{msg.message}</p>
        ))}
      </div>
    </div>
  );
};

export default SocketTest;

 

 

[Error] global is not defined

문제 화면 해결방안

vite.config.js 에 global 참조 오류 안나도록 선언 추가

 

 

[Error] Access to fetch at A from origin has been blocked by CORS policy

global 참조 오류를 해결하니, 이제는 CORS 에러가 난다고 한다. 음?

Access to fetch at 'http://dev.server.com/socket?t=1734930896707'
 from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:3000, http://localhost:3000', but only one is allowed. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

 

위처럼 오류가 나서 Network 탭을 열어보니 메세지 그대로 동일한 Access-Control-Allow-Origin key 값을 가진 데이터가 있었다.

 

찾아보니 SockJs 내부에 CORS 설정이 포함되어 있었다.

 

Backend JAVA 쪽 코드에 아마 아래와 같은 코드가 포함되어 있을 것이다.

내 케이스에서는 Gateway에서 CORS 설정이 들어가있었는데, SockJS 쪽에도 CORS가 들어있어서 문제였다.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

 

 

정리하자면 현재 상태는?

1. SockJs CORS 설정을 빼면, 내 개발 도메인을 403 forbidden 으로 내친다. (CORS 설정이 안되어 있으니까 거부!)

2. SockJs CORS 설정을 유지하면, CORS 설정이 2중으로 들어간다. (SockJs, Gateway)
       a. SockJs가 CORS 설정을 response header 에 추가해 응답을 내리면 
       b. Gateway가 CORS 설정을 response header에 추가해서 응답을 내려준다.

 

 

지금 내가 할 수 있는 행동은?

1. SockJs CORS 설정을 빼고, 나를 받아드려라 -> ?? 이게 가능하면 CORS 의미가 있나?

2. SockJs를 Gateway 타지 않는 방법 모색

2-1. Gateway 영향 받지 않는 별도의 서버로 분리하기

2-2. path prefix를 검사하여 socket 관련 연결은 gateway의 interceptor 들의 영향을 받지 않게 하기

2-3. 뭐가 있을까? 

 

 

여기까지 우선 기록하고, 이후 변경점이 생기면 추가로 글을 달아 놓겠다.