codestates / codestates/Almost-There

[Dev log] 이승연 / 2022-02-22 (2) Socket.io 정리 + 코멘트

Open
#106 0 comments 0 reactions 1 assignee Claimed by @torangL View on GitHub
Client dev-log Server
Dominant language
TypeScript
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

서버

```js
// ! 서버
const { Server } = require('socket.io');
const httpServer = require('http').createServer(app);

// ! Socket 서버 생성(io) + CORS 설정
const io = new Server(httpServer, {
cors: {
origin: 'http://localhost:3000',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
}
});

// socket 서버에 접속한 client 개수?
const count = io.engine.clientsCount;

// ! Socket 서버에서 이벤트 처리
// ! 서버 접속(connection) -> 채널 접속(join), 각 이벤트 처리(init, success, test)
// ? connection: 원래 있는 이벤트, Socket 서버 접속할 때
// on: 받은 이벤트 처리 io.on(이벤트 이름, (이벤트 내용) => { 콜백함수 });
// emit: 이벤트 보내기 io.emit(이벤트 이름, 이벤트 내용);
io.on('connection', (socket) => {
console.log('connection');

// room join
// ? join: Socket 서버의 특정 room에 접속한다.
// ? room: join, leave할 수 있는 임시 채널. 클라이언트 집합에서 발생하는 이벤트 처리할 때 사용하는 듯.
// to: 어느 room으로 이벤트 보낼지 지정
socket.join('test room');
io.to('test room').emit('testRoom', 'in test room');
// console.log(socket.rooms.size);
console.log(socket.rooms); // 접속한 room 확인

// 'init' 이벤트 처리
// init: 'init'라고 이름지은 이벤트, client에서 'init'라는 이벤트를 서버에 보냈을 때 다음과 같이 처리
socket.on('init', (payload) => {
console.log(payload);
});

// 'success' 이벤트 처리
// success: 'success'라고 이름지은 이벤트, client에서 'success'라는 이벤트를 서버에 보냈을 때 다음과 같이 처리
socket.on('success', (payload) => {
console.log('success');
console.log(payload);
// 'success again'이라는 내용의 'success'라는 이벤트를 client에 보내기
io.emit('success', 'success again');
});

// 'test' 이벤트 처리
// test: 'test'라고 이름지은 이벤트, client에서 'test'라는 이벤트를 서버에 보냈을 때 다음과 같이 처리
socket.on('test', (payload) => {
console.log(payload);
});
});

// Socket 서버를 PORT에 연결
httpServer.listen(PORT, () => {
console.log(`HTTP server listen on ${PORT}`);
});
```

클라이언트

```js
// ! 클라이언트(React, TypeScript)

// ! 이벤트 타입 정의
// 서버 -> 클라이언트 이벤트(success, testRoom)
interface ServerToClientEvents {
success: (c: string) => void;
testRoom: (d: string) => void;
}

// 클라이언트 -> 서버 이벤트(init, success)
interface ClientToServerEvents {
init: (a: string) => void;
success: (b: object) => void;
}

// 모름 ??
interface interServerEvents {
ping: () => void;
}

// 그냥 객체 타입 데이터
interface SocketData {
receiver: Array;
notifyId: number;
}

// ! Socket<서버 -> 클라이언트 이벤트, 클라이언트 -> 서버 이벤트> 정의
const socket: Socket = io('http://localhost:4000');

// ! 원하는 대로 Socket 이벤트 보내거나 받은 거 처리하기
// join room
// 'testRoom' 이벤트 처리: 서버에서 'testRoom'이벤트를 전달받았을 때
socket.on('testRoom', (payload) => {
console.log(payload);
});

// Socket.io 접속
// 서버에 'test' 내용의 'init'라는 이벤트를 전달
// useEffect -> 예시에서 가져옴, 그냥 페이지 들어올 때 socket 연결 끊는 거였던가?
socket.emit('init', 'test');
useEffect(() => {
return () => {
socket.close();
};
}, []);

// test: TEST 버튼의 onClick 이벤트
// onClick 이벤트 발생 시에 적용
const test = () => {
console.log('event');

// Client -> Server -> Client 정보 주고받기
const data: SocketData = {
receiver: [2, 3, 4],
notifyId: 1
}

// emit('success'): 서버에 data를 'success'라는 이벤트로 보내기
// on('success'): 서버에서 'success'라는 이벤트를 전달받을 때 다음과 같이 처리
socket.emit('success', data);
socket.on('success', (payload) => {
console.log(payload);
});
}

return (
<>

home

TEST

);
```

메인기능 구현에 관한 개인적인 의견

```js
! Socket.io를 이용한 실시간 알림
Server: 특정 대상에게 그 알림 실시간으로 전송, 데이터베이스에 알림 내용 추가
Client: 특정 대상이 받은 알림 실시간으로 조회하여 사용자에게 전달

1) 로그인(notification room)
- 비로그인 때 온 알림 조회(notification/list)
- Socket 접속, 로그인한 userId 이름으로 채널(room) 생성 후 연결(join)
- login 상태가 true가 되면 접속 -> login 상태가 있는 최상위 컴포넌트가 어디?
- 본인 userId 채널에서 실시간 알림 주고받기
- 소속된 모든 그룹 채널에 연결 -> 그룹 정보 주고받기

2) 로그아웃
- login 상태가 false
- 연결된 모든 채널(room)에서 나가기(leave)

3) 그룹(group room)
- 그룹 생성할 때
- 그 groupId 이름으로 채널(room) 생성 후 소속 인원들 연결(join)
- 생성자 제외 나머지 그룹원들에게 초대 알림 전송
(각자 notification room으로 보내기?)
Client: 그룹 생성 버튼 클릭 -> onClick으로 서버에 알림 전송
* 필요 데이터: 보내는 사람(sender) = userId,
* 받는 사람(receiver) = 다른 그룹원 3명, 알림 종류(notifyId)
{
(OPTIONAL) sender: 클라이언트에서 자신의 id를 보내거나, 서버에서 토큰 해독하여 id 추출
receiver: [2, 3, 4] // 그룹원의 id들을 배열로 전달
notifyId: 1 // 목적에 따라 정해진 숫자(INTEGER)로 전달(쿼리)
} // 데이터 형식 자체는 객체
(notification/send 이용?: 알림 보낸 거 notifications_users 테이블에 저장)
- 그룹 탈퇴할 때
- 그 groupId 채널에서 나가기(leave)

4) 실시간 위치 정보 공유: ?????
- 약속시간 30분 전부터 watchPosition으로 각자 좌표 실시간 제공?
- 약속시간 30분 전부터 작동하도록 group 생성할 때 그 채널에 미리 조건을 걸어놓기?
- 위치 정보 공유 시작 시간을 실시간으로 관리하는 채널을 따로 만들어놓기?
- groupId 채널에서 각자 위치 정보 확인 버튼을 클릭할 때?
- 실시간으로 제공되는 좌표를 가져와서 지도에 표시?

+ 서버: index.js 말고 다른 파일에서도 socket.io 다루는 방법 찾기
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.