일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Front-End
- 배칭
- react rendering
- NextJS
- 타입스크립트
- lifting state up
- react code splitting
- 프론트엔드
- TypeScript
- 타스
- Next.js
- useMemo
- react router dom v6
- state 최적화
- 자바스크립트
- router dom
- 렌더링 동작원리
- 리액트 코드분할
- 고급타입
- 자동 배칭
- mapped types
- TS
- 리액트
- React
- 렌더링
- 상태 끌어올리기
- Interface
- useCallback
- rendering
- JavaScript
- Today
- Total
서녕이네 개발단지
WebSocket(웹소켓) & Socket.IO(소켓 io) 본문
오랜만에 포스팅을 한다 (베베 너무 귀욥다)
여태 공부한걸 포스팅 했어야 하는데.. 주기적으로 작성하려고 노력해야지🥲
이번엔 socket 포스팅을하려고 하는데, 예전에 한번 따라만들기로 사용해봤지만 제대로 이해하지 못하고 넘어갔음..
줍줍 프로젝트에서 소켓을 사용했지만 내가 한게 아니기 때문에 면접에서 소켓 질문이 나왔을때 대답을 못한 나 자신이 원망스러웠다 ㅜ
내가 맡은 파트가 아니라도 공부를 제대로 하자라는 다짐을 다시 하며..
WebSocket? Socket.IO?
WebSocket
애초에 둘은 다른 개념이다. 웹소켓은 양방향 소통을 위한 프로토콜이다.
프로토콜은 쉽게 말하자면 서로 다른 컴퓨터끼리 소통하기 위한 약속 정도로 이해하면 된다.
Socket.IO
반면에, socket.io는 양방햔 통신을 하기위해 웹소켓 기술을 활용하는 라이브러리이다.
차이점?
WebSocket
- HTML5 웹 표준 기술
- 매우 빠르게 작동하며 통신할 때 아주 적은 데이터를 이용함
- 이벤트를 단순히 듣고, 보내는 것만 가능함
Socket.IO
- 표준 기술이 아니며, 라이브러리이다
- 소켓 연결 실패 시 fallback을 통해 다른 방식으로 알아서 해당 클라이언트와 연결을 시도함
- 방 개념을 이용해 일부 클라이언트에게만 데이터를 전송하는 브로드캐스팅이 가능함
어떤걸 써야할까?
언제 WebSocket을 사용하고, 언제 socket.io를 사용해야할까?
서버에서 연결된 소켓(사용자)들을 세밀하게 관리해야하는 서비스인 경우에는 Broadcasting 기능이 있는
socket.io을 쓰는게 유지보수 측면에서 훨씬 이점이 많다.
반면 가상화폐 거래소같이 데이터 전송이 많은 경우에는 빠르고 비용이 적은 표준 WebSocket을 이용하는게 바람직하다.
❗️추가로 알아두어야 할 내용이 있다. socket.io로 구성된 서버에게 소켓 연결을 하기 위해서는
클라이언트측에서 반드시 socket.io-client 라이브러리를 이용해야한다. 꼭 짝을 맞추자!
Socket.IO란?
👉🏻 Socket.IO는 웹 소켓 연결을 통해 크라이언트와 서버간에 실시간 양방향 통신을 가능하게 하는 JS 라이브러리이다.
Socket.IO는 클라이언트와 서버 간의 실시간 통신을 위한 사용하기 쉬운 인터페이스를 제공하므로
실시간 업데이트 또는 양방향 통신이 필요한 응용 프로그램을 구축하는 데 널리 사용된다.
📌 Socket.IO 기본 개념
1)Socket
: 소켓은 클라이언트와 서버 간의 연결을 나타낸다. 소켓을 사용하여 실시간으로 데이터를 보내고 받을 수 있다.
2)Server
: 서버는 클라이언트와의 소켓 연결을 설정하고 관리한다. 서버는 클라이언트로 이벤트를 방출하거나 클라이언트로부터 이벤트를 수신 할 수 있다.
3)Client
: 클라이언트는 서버와의 소켓 연결을 설정하고 관리한다. 클라이언트는 서버와 동일하게, 서버로 이벤트를 방출하거나 서버에서 이벤트를 수신 할 수 있다.
📌 Socket.IO 트래픽 격리 구분
1)Event
: 이벤트는 소켓 연결을 통해 클라이언트와 서버간에 전송 된 메시지다. 이벤트 이름은 서버와 클라이언트에서 동일하게 선언하여야 한다. (JSON, 문자열, 이진 등 모든 형식의 데이터 포함 가능)
2)Namespace
: 네임 스페이스는 클라이언트와 서버 간의 별도의 통신 채널이다. 단일 서버에서 여러 네임 스페이스를 작성할 수 있으며 클라이언트는 특정 네임 스페이스에 연결하여 해당 네임 스페이스의 다른 클라이언트에게만 이벤트를 수신하거나 방출 할 수 있다.
3)Room
: 룸은 함께 결합 된 소켓 그룹이다. 소켓은 여러 룸에 합류하거나 떠날 수 있다. 룸은 연결된 모든 고객에게 방송하는 대신 특정 클라이언트 그룹에 메시지를 보내는 데 유용하다.
📌 Socket.IO 이벤트 송수신 방식
1. Public
Public은 연결된 모든 클라이언트에게 메시지가 전송되는 경우다. Socket.IO에서 io.emit 연결된 모든 클라이언트에게 메시지를 브로드 캐스트하는 방법으로, 채팅 메시지와 같은 일반 메시지를 연결된 모든 클라이언트에게 보내는 데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('chat message', (message) => {
io.emit('chat message', message);
// 연결된 모든 클라이언트에게 메시지 통신(브로드 캐스트)
});
});
// 클라이언트 측
socket.on('chat message', (message) => {
console.log(`Received message: ${message}`);
});
2. Private
Private은 특정 고객에게 메시지를 보낼 때이다. Socket.IO에서 socket.emit 특정 클라이언트에게 메시지를 보내는 방법으로, 알림 또는 알림과 같은 개인 메시지를 특정 클라이언트로 보내는 데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('send notification', (msg, recipientId) => {
io.to(recipientId).emit('notification', msg);
// 지정된 수신자에게 메시지 보내기
});
});
// 클라이언트 측
socket.on('notification', (msg) => {
console.log(`Received notification: ${msg}`);
});
3. Broadcasting
Broadcasting은 발신자를 제외한 모든 클라이언트에게 메시지가 전송되는 경우이다.
Socket.IO에서 socket.broadcast.emit 발신자를 제외한 모든 연결된 클라이언트에게 메시지를 브로드 캐스트하는 방법으로, 발신자를 제외한 모든 연결된 클라이언트에 사용자 조인 또는 종료와 같은 알림을 보내는 데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('user join', (username) => {
socket.broadcast.emit('new user', username);
// 발신자를 제외한 연결된 모든 클라이언트에게 메시지 통신(브로드 캐스트)
});
});
// 클라이언트 측
socket.on('new user', (username) => {
console.log(`New user joined: ${username}`);
});
📌 Socket.IO 이벤트 송수신 개념
1. Emit
클라이언트에서 서버로 또는 서버에서 클라이언트로 이벤트를 보내는 데 사용.
이벤트 이름과 보낼 데이터라는 두 가지 이상의 인수가 필요하다.
//첫 번째 인수는 이벤트 이름, 두 번째 인수는 전송될 데이터
socket.emit('chat message', 'Hello, world!');
2. To
특정 소켓이나 방에 이벤트를 방출하는 데 사용.
이벤트가 전송 될 소켓 ID 또는 방 이름이라는 하나의 인수가 필요하다.
// to 메소드는 이벤트를 보낼 소켓 ID를 지정하는 데 사용
io.to('12345').emit('chat message', 'Hello, world!');
3. On
클라이언트 또는 서버에서 이벤트에 대한 리스너를 등록하는 데 사용. 이벤트 이름과 이벤트를 처리하기 위한 콜백 함수라는 두 가지 이상의 인수가 필요합니다.
//첫 번째 인수는 이벤트 이름, 두 번째 인수는 이벤트가 수신 될 때 호출되는 콜백 함수(데이터)
socket.on('chat message', (message) => {
console.log(`Received message: ${message}`);
});
4. Of
자체 소켓 및 이벤트 세트로 새 네임 스페이스를 만드는 데 사용.
네임 스페이스의 이름이라는 하나의 인수가 필요하다.
// of 메소드는 새로운 네임 스페이스를 만드는 데 사용
const chatNamespace = io.of('/chat');
Socket.IO 작동 방식
👉🏻 Socket.IO는 클라이언트와 서버간에 WebSocket 연결을 설정하여 작동한다.
서버는 들어오는 연결을 확인하고 클라이언트가 방출하는 이벤트를 처리한다.
클라이언트는 서버에 연결하고 이벤트를 방출하거나 이벤트를 확인할 수 있다.
클라이언트가 이벤트를 방출하면 서버는 이벤트를 수신하여 클라이언트로 응답을 다시 보내거나
동일한 네임 스페이스 또는 방에 있는 다른 클라이언트로 이벤트를 브로드 캐스트 할 수 있다.
Socket.IO에서 setTimeout을 호출해야하는 이유?
Socket.IO의 주요 기능 중 하나는 많은 수의 연결 및 이벤트를 동시에 처리 할 수 있다는 것이다.
그러나 제대로 관리하지 않으면 성능 문제가 발생할 수 있다.
🖐🏻 성능 문제를 피하는 한 가지 방법은 setTimeout과 Socket.IO와 함께 작동하는 것이다.
setTimeout 지정된 시간이 지난 후에 기능을 실행할 수있는 내장 JavaScript 기능으로,
Socket.IO에서 setTimeout 이벤트를 받은 후 클라이언트에게 승인을 보내는 등 특정 기능의 실행을 지연시키면
서버에 너무 많은 이벤트가 동시에 과부하되는 것을 방지 할 수 있다.
// 서버 측
socket.on('message', (data, callback) => {
// 처리 수행
setTimeout(() => {
callback('success');
}, 1000); // 확인을 보내기 전에 1초간 기다리기
});
// 클라이언트 측
socket.emit('message', data, (response) => {
console.log(response); // 1초 후 '성공' 로그 기록
});
The Socket instance (client-side)
🌼 1. ID : 서버 측의 값과 동기화
// 서버 측
io.on("connection", (socket) => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});
// 클라이언트 측
socket.on("connect", () => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});
socket.on("disconnect", () => {
console.log(socket.id); // undefined
});
🌼 2. connected : 소켓이 현재 서버와 연결되어 있는지 여부
socket.on("connect", () => {
console.log(socket.connected); // true
});
socket.on("disconnect", () => {
console.log(socket.connected); // false
});
🌼 3. Lifecycle : 수명주기(작동방식)
🌼 4. Event
- Socket 인스턴스는 다음 세 가지 특별한 이벤트를 전송한다.
- connect
- connect_error
- disconnect
connect
- 이 이벤트는 연결 및 재연결 시 소켓 인스턴스에 의해 발생한다.
- 소켓이 다시 연결될 때마다 새 핸들러가 등록되므로 연결 핸들러 자체에 이벤트 핸들러를 등록해서는 안된다.
// BAD
socket.on("connect", () => {
socket.on("data", () => { /* ... */ });
});
// GOOD
socket.on("connect", () => {
// ...
});
socket.on("data", () => { /* ... */ });
connect_error
- 낮은 수준의 연결이 수립되지 않는다.
- 서버에서 미들웨어 함수에서 연결이 거부된다.
첫 번째 경우에는 소켓이 자동으로 지정된 지연 시간 후에 다시 연결을 시도할 것이다.
두 번째의 경우 수동으로 다시 연결해야 한다. 자격 증명을 업데이트해야 할 수도 있다.
// either by directly modifying the `auth` attribute
socket.on("connect_error", () => {
socket.auth.token = "abcd";
socket.connect();
});
// or if the `auth` attribute is a function
const socket = io({
auth: (cb) => {
cb(localStorage.getItem("token"));
}
});
socket.on("connect_error", () => {
setTimeout(() => {
socket.connect();
}, 1000);
});
disconnect
- 이 이벤트는 연결이 해제될 때 발생한다. 연결이 끊어지면 다시 시작
socket.on("disconnect", (reason) => {
// ...
});
참고
https://socket.io/docs/v3/client-socket-instance/
https://www.peterkimzz.com/websocket-vs-socket-io
https://velog.io/@fejigu/Socket.IO-client
https://velog.io/@kskim625/Socket.IO%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90
'프론트엔드 > React' 카테고리의 다른 글
[React] Jest matcher 함수 종류 (0) | 2024.03.25 |
---|---|
[React] RTL(React Testing Library)쿼리 우선 순위 + Jest 사용법 & TDD란? (0) | 2024.03.21 |
[React] memoization 꼭 필요한가? (0) | 2023.06.20 |
[React] state 최적화를 위한 방법? (hooks 최적화) (0) | 2023.06.19 |
[React] React-Router-Dom V6의 동작원리 (0) | 2023.06.16 |