사이드 프로젝트에서 채팅을 담당하게 되서 이참에 Websocket을 정리해보려고 한다.
(환경은 React + Typescript + NodeJS이다)
웹소켓
- 클라이언트와 서버 간의 양방향 통신 프로토콜이다
- 실시간 통신이 가능하다
Server
백엔드분과 통신하기 전에, 로컬서버를 만들어 채팅을 주고 받을 수 있는지 테스팅해보기로 했다.
서버 폴더를 생성하고 server.ts를 생성한다.
mkdir websocket_test
cd websocket_test
npm init -y
그리고 다음 패키지들을 설치한다
npm i ws
npm i ts-node-dev
npm i --save-dev @types/ws
npm i --save-dev @types/node
server.ts를 만든후 다음과 같이 작성한다
import WebSocket from 'ws';
const PORT = 1234;
const wss = new WebSocket.Server({ port: PORT }); // 웹소켓 서버열기
wss.on('connection', (ws: WebSocket) => {
console.log('새로운 클라이언트가 연결되었습니다.');
// 클라이언트로부터 메시지 수신 시 처리
ws.on('message', (message: string) => {
console.log('메시지를 받았습니다: %s', message);
});
// 서버에서 클라이언트한데 메시지 보내기
ws.send('hi from server');
// 클라이언트 연결 종료 시 처리
ws.on('close', () => {
console.log('클라이언트 연결이 종료되었습니다.');
});
// 에러발생 시
ws.on('error', (error: any) => {
console.log(error);
});
});
console.log(`WebSocket 서버가 ${PORT} 포트에서 실행 중입니다.`);
npm start하기 전에 package.json을 다음과 같이 수정한다
"main": "server.ts",
"scripts": {
"start": "ts-node-dev --respawn server.ts"
},
이제 npm start하면 웹소켓 서버가 로컬 1234포트에서 실행됨을 알 수 있다.
이제 서버와 통신할 Client를 만들어보자
Client
CRA로 클라이언트를 만든다
컴포넌트가 렌더링 될때, useEffect에서 WebSocket 객체를 만든뒤 이를 state에 저장하여 사용한다.
state을 사용해 webSocket 연결, 연결끊김, 메시지 수신 등 이벤트를 핸들링한다.
주의할 점은 브라우저를 닫으면 메모리 누수와 자원 소비를 방지하기 위해 웹소켓 연결을 끊어줘야한다.
const [webSocket, setWebSocket] = useState<WebSocket | null>(null);
useEffect(() => {
// 컴포넌트가 마운트될 때 WebSocket 연결 생성
const socket = new WebSocket('ws://localhost:1234/ws');
// WebSocket 이벤트 핸들러 등록
socket.onopen = () => {
console.log('WebSocket 연결이 열렸습니다.');
};
socket.onmessage = (event) => {
console.log('서버로부터 메시지를 받았습니다:', event.data);
};
socket.onclose = () => {
console.log('WebSocket 연결이 닫혔습니다.');
};
// 상태 업데이트
setWebSocket(socket);
// 컴포넌트 언마운트 시에 WebSocket 연결 닫기
return () => {
socket.close();
};
}, []); // 빈 배열을 전달하여 마운트 및 언마운트 시에 한 번만 실행되도록 함
서버1234가 켜진 상태에서 클라이언트를 npm run start실행하면
아래와 같이 서버쪽에서 새로운 클라이언트가 연결되었다고 알려주고
클라이언트쪽에서 서버로부터 메시지를 받는다
채팅 송신 수신
이제 클라이언트에서 서버에게 채팅 보내는 것을 해보자
간단하게 버튼을 클릭하면 hello from client 메시지를 전송하게 해봤다.
const sendMsg = () => {
webSocket?.send('hello from client');
};
return (
<button onClick={sendMsg}>
send msg
</button>
);
클라이언트에서 버튼을 누르면 서버에서 메시지를 받을 수 있다.
여기까지 간단한 WS를 이용한 클라이언트와 서버의 통신을 테스트해봤다.
문제가 있으면 알려주세요!
'웹' 카테고리의 다른 글
form.submit()와 axios.post() 데이터 전송의 포맷차이 (0) | 2024.10.24 |
---|---|
브라우저 언어감지, 다국어 페이지 URL로 표현하기 (0) | 2024.09.20 |
ESC눌러서 모달창 닫기, 배열을 querystring파라미터로 전달하기 (0) | 2023.09.12 |
쿠키 세션 토큰 JWT (0) | 2023.06.30 |
CORS (0) | 2023.06.04 |