useWebSocket으로 웹소켓 구현하기
이번 프로젝트에서 웹소켓을 통해 게시물의 좋아요 수 및 댓글의 실시간 업데이트 기능을 구현하였다.프론트엔드에서는 웹소켓을 통해 전송하는 데이터의 형태를 정확히 설정하고,웹소켓을 통
seyoonagain.tistory.com
😎 useWebSocket으로 웹소켓을 구현하기이~
이번 프로젝트에서 웹소켓을 통해 여행 후기의 좋아요 수 및 댓글의 실시간 업데이트 기능을 구현했당.
그런데 문제점 발견!
🚨 다중 컴포넌트에서의 연결
좋아요 관련 컴포넌트와 댓글 관련 컴포넌트들에서 각각 useWebSocket 훅을 호출하다보니,
하나의 연결이 아닌 사용하는 컴포넌트 개수만큼 연결이 생성된 것!
이렇게 불필요한 연결이 많아지게 되면 성능 저하가 발생할 수 있어 수정이 필요하다고 생각했당.
💡 웹소켓 연결을 전역 상태로 관리함으로써 해결!
위의 문제를 해결하기 위해 하나의 useWebSocket 호출로 통신을 하기 위해 전역상태로 만들고자 했다.
현재 상태관리를 Redux Toolkit으로 하고 있었지만 Redux Toolkit으로 하기엔 너무 복잡해 보였다 ^_^
리듀서 안에서는 훅을 못쓰기 때문에 많은 코드 수정이 요구되었고, 마감 기한이 정해진 프로젝트라 효율을 높이기 위해
간단하게 할 수 있는 useContext를 사용하기루 결정!
✨ Context로 웹소켓 관리하기 ^_^
Context를 사용하니 원래 쓰던 코드에서 수정이 거의 필요없어서 굉장히 간단하고 직관적이라 맘에 들었당.
나는 웹소켓 주소가 reviewId에 따라 동적으로 변동이 되어, 이를 설정할 상태 변경함수(setReviewId)를 함께 제공하도록 만들었다.
const WebSocketContext = createContext<
| {
sendJsonMessage: SendJsonMessage;
lastMessage: MessageEvent | null;
isSocketOpen: boolean;
setReviewId: Dispatch<SetStateAction<string>>;
}
| undefined
>(undefined);
const WebSocketContextProvider = ({ children }: { children: React.ReactNode }) => {
const [reviewId, setReviewId] = useState<string>('');
const socketUrl = reviewId ? `${SOCKET_URL}?review_id=${reviewId}` : null;
const { sendJsonMessage, lastMessage, readyState } = useWebSocket(
socketUrl,
{
onOpen: () => console.log('✨ WebSocket 연결 열림'),
onError: error => console.log('🚨 WebSocket 에러', error),
onClose: () => console.log('💀 WebSocket 연결 닫힘'),
shouldReconnect: () => true,
},
!!socketUrl,
);
const isSocketOpen = readyState === 1;
return (
<WebSocketContext.Provider value={{ sendJsonMessage, lastMessage, isSocketOpen, setReviewId }}>
{children}
</WebSocketContext.Provider>
);
};
🌝 Context를 사용하며 느낀 장점
- 코드의 모듈화
웹소켓 연결 로직을 Context로 분리함으로써 관리가 편해짐 - 불필요한 연결 방지
하나의 useWebSocket 호출로 모든 컴포넌트가 동일한 연결을 공유할 수 있어 불필요한 연결 방지 및 성능 저하 방지 - 코드의 간결함과 직관성
Redux Toolkit을 사용한다면 middleware나 thunk를 사용해야 해서 복잡할 수 있던 코드를
Context로 대체함으로써 간결하고 직관적으로 만들 수 있었음
이상 끝 🤓
'Error Log' 카테고리의 다른 글
| #3. useRouter() from next/router vs. next/navigation (0) | 2024.12.28 |
|---|---|
| #2. Supabase 테이블의 특정 column에 대해 중복값 처리하기 (1) | 2024.09.24 |
| #1. margin: auto로 가운데 정렬이 안되는 경우 (0) | 2024.09.06 |