#0 개요
3가지 페이지 (room들을 보고 입장하는 페이지, 게임 시작 대기 페이지, 게임 진행 페이지)에서 socket을 유지하고,
그 외 페이지(로그인, 회원가입, 메인, 공지 등)에서는 socket을 유지하지 않으려고 한다.
최대한 socket을 효율적으로 관리하기 위한 방법으로, 페이지 구조를 변경하고자한다.
#1 SocektProvider 생성
1 createContext
// 1. Context 생성
const SocketContext = createContext<Socket | null>(null);
createContext는 Context 객체를 생성하는 함수이다.
상위 컴포넌트에서 제공하는 값을 하위 컴포넌트들이 props를 넘겨 받지 않아도 직접 사용할 수 있게 해준다.
나중에 <SocketContext.Provider>로 “공유하고 싶은 값”을 주입하면, 하위 컴포넌트에서는 useContext(SocketContext)로 그 값을 꺼내 쓸 수 있음.
2. useRef
useRef는 참조(Ref) 객체를 반환하는 훅으로, 값이 재랜더링 사이에서 유지되어야 하지만, 값이 바뀌어도 컴포넌트를 다시 렌더링할 필요가 없을 때 주로 사용한다.
import React, { createContext, useEffect, useRef } from "react";
import { io, Socket } from "socket.io-client";
const SOCKET_URL = "http://localhost:3000";
// 1. Context 생성
export const SocketContext = createContext<Socket | null>(null);
// 2. Provider 컴포넌트
export const SocketProvider = ({ children }: { children: React.ReactNode }) => {
const socketRef = useRef<Socket | null>(null);
if (!socketRef.current) {
socketRef.current = io(SOCKET_URL, {
// 필요한 옵션들
transports: ["websocket"],
});
}
useEffect(() => {
// 컴포넌트가 마운트될 때 소켓 연결
const socket = socketRef.current;
socket?.on("connect", () => {
console.log("소켓 연결됨:", socket.id);
});
// 언마운트 시 소켓 연결 해제(필요하다면)
return () => {
socket?.disconnect();
};
}, []);
return (
<SocketContext.Provider value={socketRef.current}>
{children}
</SocketContext.Provider>
);
};
3. hook 생성
import { useContext } from "react";
import { SocketContext } from "../components/SocketContext";
export const useSocket = () => {
const socket = useContext(SocketContext);
if (!socket) {
throw new Error("useSocket must be used within a SocketProvider.");
}
return socket;
};
4. 적용 결과
import { Outlet } from "react-router";
import { SocketProvider } from "../components/SocketContext";
function Game() {
return (
<>
<SocketProvider>
<Outlet />
</SocketProvider>
</>
);
}
export default Game;
+++ 주의!
useSocket 으로 socket을 반환 받아서 사용해도, 연결이 끊기곤 했다.
이는 root에 strict mode 때문인데, 이 strict mode는 컴포넌트를 두번 랜더링하게 한다.
그럼 socket이 두번 작동되면서, 첫번째 통신을 보내기 전에(혹은 보내자마자) 소켓이 닫혀버리는 셈.
strict mode component를 주석처리해주면 정상 동작한다.
#2
'프로젝트 기록 > LLM 게임 프로젝트' 카테고리의 다른 글
개발 리뷰 -14- 게임 시스템 개발 + 최종 데모 영상 (0) | 2025.02.26 |
---|---|
개발 리뷰 -12- 채팅 시스템 구현 (0) | 2025.02.05 |
개발 리뷰 -11- 게임 채팅 페이지 개발 (0) | 2025.01.23 |
개발 리뷰 -10- 메인 페이지 개발 (0) | 2025.01.23 |
개발 리뷰 -9- 실시간 채팅 구현을 위한 Websocket, webRTC 선행 (0) | 2025.01.16 |