클라이언트와 서버 연결하기
Socket.io 이벤트로 브라우저와 서버 연결하기
⏱ 예상 ~7분
01 · 읽기
게임을 관리하는 서버와 보드를 보여주는 페이지가 있어요. 둘은 아직 서로 대화하지 않아요. 빠진 조각은 client.js 예요. 브라우저에서 돌면서 플레이어가 하는 것 (cell 클릭, 버튼 누르기) 과 서버가 이해하는 것 (Socket.io 이벤트) 사이를 통역하는 JavaScript 예요.
client.js 를 외교 회담의 통역사라고 생각해요. 플레이어는 '클릭과 버튼' 으로 말해요. 서버는 '이벤트와 데이터' 로 말해요. 통역사가 양쪽 말을 듣고, 메시지를 변환하고, 모두가 이해하게 해요.
핵심 정리
- client.js 는 브라우저에서 돌아요. 서버가 아니에요
- 사용자 동작 (클릭) 을 Socket.io 이벤트로 변환해요
- 서버 이벤트를 UI 업데이트로 변환해요 (수 표시, 상태 메시지)
- io() 함수가 자동으로 서버에 연결해요
02 · 프롬프트 템플릿
Claude에게 클라이언트 측 JavaScript를 만들어 달라고 해요. 각 이벤트와 UI 업데이트를 명확히 적어요.
tic-tac-toe 게임용 public/client.js 를 만들어 주세요. 요구 사항: (1) io() 로 서버에 연결해요. Socket.io 가 이 페이지를 제공한 호스트에 자동으로 연결해요. (2) 'Find Game' 을 클릭하면 'find-game' 을 emit 하고 상태를 'Searching for opponent...' 로 업데이트해요. (3) 'waiting' 이벤트를 받으면 상태를 'Waiting for another player...' 로 업데이트해요. (4) 'game-start' 이벤트를 받으면 (symbol 과 roomId 가 옴) 플레이어의 심볼을 기록하고, 누구 차례인지 상태에 표시하고, 보드를 활성화해요. (5) cell 클릭 시 cell index 와 roomId 와 함께 'make-move' 를 emit 해요. 단, 자기 차례이고 해당 cell 이 비어 있을 때만 보내요. (6) 'move-made' 이벤트를 받으면 해당 cell 에 심볼을 채우고 차례 상태를 업데이트하고 누구 차례인지에 따라 클릭을 활성화/비활성화해요. (7) 'game-over' 이벤트를 받으면 결과 (승/패/무) 를 표시하고, 필요하면 승리한 세 cell 을 highlight 하고, Play Again 버튼을 보여 줘요. (8) 'opponent-left' 이벤트를 받으면 'Opponent disconnected' 를 표시하고 Play Again 버튼을 보여 줘요. (9) Play Again 을 클릭하면 보드를 리셋하고 다시 'find-game' 을 emit 해요.
03 · 코드 예제
Claude가 client.js 를 만든 후, 이 핵심 패턴을 찾아봐요. 모든 Socket.io 클라이언트가 이렇게 작동해요.
Socket.io 클라이언트 패턴
const socket = io();
// Sending events TO the server
socket.emit('find-game');
socket.emit('make-move', { index: 4, roomId: myRoom });
// Receiving events FROM the server
socket.on('game-start', (data) => {
// data.symbol is 'X' or 'O'
// data.roomId identifies this game
});
socket.on('move-made', (data) => {
// data.index, data.symbol
// Update the board cell
});
io() 가 서버와의 연결을 만들어요. socket.emit() 이 이벤트를 보내요. socket.on() 이 이벤트를 들어요. 이벤트 이름 ('find-game', 'game-start', 'move-made') 은 클라이언트와 서버 사이의 계약이에요. 정확히 일치해야 해요. 설계 레슨에서 살펴본 그 이벤트 흐름이에요.
04 · 읽기
클라이언트는 절대 수의 유효성을 결정하지 않아요. 모든 클릭을 서버에 보내고 응답을 기다려요. 서버가 수가 유효하다고 하면 ('move-made' emit) 클라이언트가 보드를 업데이트해요. 서버가 무시하면 아무 일도 안 일어나요.
설계 레슨의 같은 원칙이에요. 서버가 권위자고, 클라이언트는 표시일 뿐이에요. 클라이언트 측 체크를 추가해서 (예: 자기 차례가 아닐 때 클릭 비활성화) UI 가 반응적으로 느껴지게 할 수는 있어요. 하지만 서버는 여전히 모든 걸 독립적으로 검증해요.
핵심 정리
- 클라이언트는 수를 서버에 보내고 확인을 기다려요
- 서버가 모든 수를 검증해요. 클라이언트는 절대 유효성을 결정하지 않아요
- 클라이언트 측 체크는 UX 용이지 보안용이 아니에요
- client.js 의 이벤트 이름은 server.js 가 기대하는 것과 정확히 일치해야 해요
05 · 실기 실습
전체 게임 흐름을 테스트해요. 진실의 순간이에요. 두 개의 브라우저 탭으로 같은 URL 을 열어 자기 자신과 플레이해요.
06 · 빈칸 채우기
client.js 의 io() 함수가 서버와의 _____ 연결을 만들어요. 전체 게임 세션 동안 열린 상태로 유지돼요.
07 · 퀴즈
플레이어가 브라우저에서 cell 을 클릭해요. 다음에 무슨 일이 일어나요?
- 클라이언트가 즉시 보드에 심볼을 놓고 나중에 서버에 알려요
- 클라이언트가 HTTP POST 요청을 서버에 보내요
- 브라우저가 페이지를 새로고침해서 업데이트된 보드를 가져와요
- 클라이언트가 'make-move' 를 서버에 emit 하고, 서버가 'move-made' 를 emit 할 때까지 기다린 후에 보드를 업데이트해요
⚠ 전체 인터랙티브 경험에는 JavaScript가 필요해요. JavaScript를 켜고 새로 고침해 주세요.
※ 이 사이트는 독립 운영되는 교육 프로젝트로, Anthropic의 공식 제품이 아니에요. Claude™ 는 Anthropic, PBC 의 상표예요.