일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- autosize
- SSR
- CI/CD
- CORS
- React
- TS
- 결정 알고리즘
- map
- 공변성
- recoil
- 타입 좁히기
- 태그된 유니온
- 인터섹션
- Promise
- dfs
- 투포인터
- 리터럴 타입
- useAppDispatch
- 이분 검색
- Jest
- RTK Query
- ESlint
- 호이스팅
- async/await
- 반공변성
- webpack
- Cypress
- 무한 스크롤
- app router
- tailwind
- Today
- Total
짧은코딩
WebSocket 본문
webSocket
웹소켓은 실시간으로 서버와 데이터를 주고 받을 때 사용한다. 이전까지는 프로트에서 요청을 보내고 서버에서 답을 주는 형식인 단방향 통신이었다. 하지만 웹소켓은 양방향 통신이다.
npm i socket.io-client@2
이렇게 설치하면 된다.
소켓을 컴포넌트와 서버와 연결하면 연결이 끊기지 않고 사용할 수 있다. 하지만 반대로 생각하면 연결된 컴포넌트가 사라지면 소켓 연결도 끊긴다. 따라서 공통된 컴포넌트에 연결해야 한다. 화면이 없고 로직만 있는 경우에는 hooks 파일에다가 만들면된다. 하지만 화면이 들어가도 hooks에 사용할 수 있다.
-hooks/useSocket.ts
hook폴더에 새 파일을 만든다.
npm i -D @types/socket.io-client@1.4.35
그리고 이것도 설치한다. 에러가 발생해서 버전을 낮춰서 설치했다.
import io from 'socket.io-client';
import { useCallback } from 'react';
const backurl = 'http://localhost:3095';
//여러 workspace에 들어가는 경우이다. ts에서는 빈 객체, 빈 배열에선 타입핑을 해야한다. key는 워크스페이스이다.
const sockets: { [key: string]: SocketIOClient.Socket } = {};
const useSocket = (workspace?: string) => {
const disconnect = useCallback(() => {
if (workspace) {
sockets[workspace].disconnect();
//연결 끊었는데 계속 관리 할 필요 없어서 삭제
delete sockets[workspace];
}
}, [workspace]);
if (!workspace) {
return [undefined, disconnect];
}
sockets[workspace] = io.connect(`${backurl}/ws-${workspace}`);
//서버에 hello라는 이벤트 이름으로 world라는 데이터를 보내는 것이다.
sockets[workspace].emit('hello', 'world');
//서버에서 데이터가 오면 message에다가 데이터를 받는 콜백 함수이다.
sockets[workspace].on('message', (data) => {
console.log(data);
});
return [sockets[workspace], disconnect];
};
export default useSocket;
emit으로 보내고 on으로 받는다. 그리고 이벤트 명이 같아야 받는다.
socket는 범위가 중요하다. 예를 들어 a 채팅방에서 보낸 채팅이 b 채팅방으로 가면 안된다. 따라서 범위가 중요하고 우리는 이것을
const socket = io.connect(`${backurl}/ws-${workspace}`);
이 코드에서 구별해 줄 것이다. workspace마다 ws-sleact, ws-test 이런식으로 구분할 것이다.
ws-sleact에서 있다가 ws-test로 넘어가면 소켓을 끊고서 넘어가야 한다. 이렇게 안하면 채팅을 보내면 모든 사람들한테 데이터가 전송되어 보안에 문제가 발생한다.
즉, 채팅방마다 소켓 맺고 끊음이 중요하다.
socket.disconnect();
이렇게 disconnect하면 한 번 연결한 소켓을 끊는다.
https://github.com/ZeroCho/sleact/blob/master/API.md
마찬가지로 여기에 이벤트 명들이 있는데 백엔드 개발자와 협의해서 이름을 정해 사용하면 된다.
-socket
conected: true이여야 연결 상태
nsp: namespace
receiveBuffer, sendBuffer: 이 두 배열은 거의 항상 비어 있어야하는데, 만약 차 있으면 데이터를 서버로 보내야 하는데 연결이 끊겨서 못 보내고 있다는 의미이다. 따라서 socket.io는 연결이 다시 되면 sendBuffer에 쭉 모아놨다가 데이터를 보내준다. 반대로 서버쪽에서도 프론트로 보내줘야 하는 데이터를 receiverBuffer에 모아놨다가 연결되면 보내준다.
_callbacks: on했던 리스트들이 들어있다.
소켓이 연결되면 백엔드에서 소켓 아이디(sid)를 보내주고 프론트와 연결한다. 그리고 프론트에서는 ws-sleact로 연결하겠다고 알려준다.
2 3 2 3 보내는 것은 ping-pong이라고 하며 제대로 연결되었는지 확인 용으로 보내주는 것이다.
'인프런, 유데미 > Slack 클론 코딩' 카테고리의 다른 글
이미지 업로드 하기 (0) | 2022.07.31 |
---|---|
가상 스크롤 바, 날짜 라이브러리(DAY.JS), 해시 태그, emotion.js에서 css에 변수 활용, 정규 표현식 (0) | 2022.07.30 |
여태까지 배운 내용 정리 (0) | 2022.07.28 |
사소한 에러까지 잡는 법 (0) | 2022.07.26 |
팁들(input, toast, Route, NavLink 등) (0) | 2022.07.23 |