Notice
Recent Posts
Recent Comments
Link
250x250
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- MySQL
- BACK-END
- 디자인 패턴
- spring
- 스프링부트
- jpa
- 오라클
- 데이터베이스
- 코드 테스트
- jsp
- 프론트엔드
- oracle
- 정리
- 미니정리
- 프런트엔드
- 백엔드
- 쿼리
- web
- 스프링
- 프로그래머스
- node.js
- SQL
- java
- 알고리즘
- JavaScript
- 서버
- Next.js
- 자바
- 코드테스트
- 자바스크립트
Archives
- Today
- Total
참치코더의 꿈 메모장
나만의 홈 스쿨 개발해보기~~ (2일차) 본문
728x90

25.11.28
프로젝트 2일차
Socket.io를 이용해서 실시간 웹 챗 기능을 개발하면서, 실시간 영상 기능도 추가해 기능을 확장하고 싶었는데, 해당 기술로는
일단 챗 기능 밖에 구현이 안된다는걸 보고 조금 충격이었습니다. 정확히 말하면 되긴하는데...
해당 기능만 사용한다면, 네트워크로 다이렉트로 데이터가 전송이 되기때문에 버퍼링이 심하게 걸릴여부가 있고,
사용자가 늘어난다면 트래픽이 엄청나지기 때문에 해당 데이터를 가볍게 만들어주는 라이브러리인 WebRTC 까지 이용해야
원하는 기능을 만들수 있다는걸 알게됬습니다. (음... 코드를 완전 뒤집어야 하나....)
따라서 일단 Socket.io 기반으로 채팅은 동일하게 움직이기 때문에 해당 기능을 학습 및 완성을 시키고 나서 다른 라이브러리를
접목시키는 방향으로 일단 잡게되었습니다.
1. 첫번째로 프론트 단은 react + Ts 로 해당 관련 view 연결하기
2. 화상 및 chat 관련기능은 서버 생성 및 Socket.io 라이브러리를 사용하여 Node.js 기반으로 해당 웹소켓 기능 제공하기
3. 스프링부트, jpa, maria db, spring security 이용해 로그인, 로그아웃, 회원가입, 권한 기능 개발하기 (학습 진행 시작)
4. (추가추가) Socket.io 라이브러리(웹 chat) + WebRTC 라이브러리(화상 기능 구현)

|
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
/* client 전체 구조 요약 */
// 1일차 때 블로그에 글을 작성하는데 가독성도 좋지 못하고 체계적이지도 않은것 같아서
// Color Scripter 사이트를 활용해 해당 코드를 작성했습니다.
// 디자인은 모든 기능 개발후 최종적으로 진행하기로 했습니다. /*
전체 구조는 이렇습니다.
1. 채팅방에 들어가기 전 화면 생성하기 (방 생성/입장 + 방 목록 표시)
2. 방 안의 화면(채팅 + 닉네임 설정)
*/
// 주요 변경된 코드 정리
// 1. 주요 useState 정리
const [inRoom, setInRoom] = useState(false); // 해당 방에 입장했는지 여부를 판단한다.
const [roomName, setRoomName] = useState(""); // 현재 입장한 방 이름을 저장 및 할당한다.
const [roomsList, setRoomsList] = useState<string[]>([]); // 서버에서 받은 전체 공개 방 목록을 저장한다.
const [messages, setMessages] = useState<string[]>([]); // 서버에서 받은 채팅 메시지 목록을 저장한다.
// 2. ref 정리
const roomInputRef = useRef<HTMLFormElement | null>(null); // 입력한 방 이름을 서버에 전달하기 위해 생성
const messageInputRef = useRef<HTMLInputElement | null>(null); // 입력한 메시지를 서버에 전달하기 위해 생성
const nicknameInputRef = useRef<HTMLInputElement | null>(null); // 입력한 닉네임을 서버에 전달하기 위해 생성
// 3. 로직 돌아가는 흐름 (중요부분 요약)
socket.emit("enter_room", value, () => {
setRoomName(value);
setInRoom(true);
});
// (1) 방 입장
// 사용자가 입력한 방 이름을 서버로 전송
// 서버는 done() 콜백을 실행한다 -> 클라이언트의 콜백합수가 실행되고, 화면이 전환된다.(가려진다.)
// React 화면이 방 목록 화면에서, 채팅 화면으로 변경된다.
socket.emit("new_message", value, roomName, () => {
setMessages(prev => [...prev, `You: ${value}`]);
});
// (2) 메시지 보내기
// 메시지를 서버에 보낸다.
// 서버는 메시지를 보낸사람을 제외한 같은 방의 사람들에 메시지를 브로드캐스트한다.
// 내가 보낸 메시지는 setMessages를 사용해 콜백으로 직접 화면에 표시되도록 작성하였다.
socket.emit("nickname", value);
// (3) 닉네임 바꾸기
// 서버의 socket.nickname 값을 바꾸어주는 역할을 한다. 기본 닉네임은 서버에서 (Anon)으로 설정한다.
// 4. socket 이벤트 수신 (useEffect)
useEffect(() => {
socket.on("welcome", (userNickname) => { // 새 유저가 방에 들어왔을때 해당 이벤트가 실행된다.
setMessages(prev => [...prev, `${userNickname} arrived!`]);
});
socket.on("bye", (userNickname) => { // 누군가 방을 나갔을 때 해당 이벤트가 실행된다.
setMessages(prev => [...prev, `${userNickname} left ㅠㅠ`]);
});
socket.on("new_message", (message) => { // 새로운 메시지가 업데이트 될때마다 해당 이벤트가 실행된다.
setMessages(prev => [...prev, message]);
});
socket.on("room_change", (rooms) => { // 공개방 목록이 업데이트 될때마다 해당 이벤트가 실행된다.
setRoomsList(rooms);
});
}, []);
|
cs |

|
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/* server 전체 구조 요약 */
/*
전체 구조는 이렇습니다.
1. 채팅방에 들어가기 전 화면 생성하기 (방 생성/입장 + 방 목록 표시)
2. 방 안의 화면(채팅 + 닉네임 설정)
*/
// 주요 변경된 코드 정리
// 1. publicRooms() 함수 — 공개 방 구하기
const publicRooms = () => {
const {
sockets: {
adapter: { sids, rooms },
},
} = wsServer;
const publicRooms = [];
rooms.forEach((_, key) => {
if (sids.get(key) === undefined) {
publicRooms.push(key);
}
});
return publicRooms;
};
// sides에 없는 키값이 rooms에 있다면 해당 키값을 가진 방은 -> 공개룸
// sides에 있는 키값이 rooms에 있다면 해당 키값을 가진 방은 -> 비밀룸
// 해당 코드는 공개룸을 구하는 코드이다.
// 2. 닉네임 기본값
socket["nickname"] = "Anon";
// 방금 들어온 사람의 초기 닉네임을 Anon으로 설정
// 3. 방 입장 처리
socket.on("enter_room", (roomName, done) => {
done();
socket.join(roomName);
socket.to(roomName).emit("welcome", socket.nickname); // 같은 방의 다른 사람들에게 welcome 이벤트 전송
wsServer.sockets.emit("room_change", publicRooms()); // 모든 클라이언트에게 공개 방 목록 업데이트
// 4. disconnecting — 방에서 나가기 직전에 실행
socket.on("disconnecting", () => {
socket.rooms.forEach((room) => {
socket.to(room).emit("bye", socket.nickname); // 해당 클라이언트가 나갔다는 걸 표시하기 위해 전송
});
});
// 5. disconnect — 완전히 연결 끊긴 후
socket.on("disconnect", () => {
wsServer.sockets.emit("room_change", publicRooms());
});
// 방 목록 변했을 수 있으므로 → 전체 클라이언트에게 publicRooms() 다시 전송
// 6. 채팅 메시지 전달
socket.on("new_message", (message, room, done) => {
socket.to(room).emit("new_message", `${socket.nickname}: ${message}`);
done();
});
// 7. 닉네임 변경
socket.on("nickname", (nickname) => (socket["nickname"] = nickname));
|
cs |
728x90
'프로젝트' 카테고리의 다른 글
| 웹 프로젝트 / 강아지 산책 서비스 (최종 정리) -완- (0) | 2025.12.30 |
|---|---|
| 웹 프로젝트 / 나만의 홈 스쿨 개발해보기~~ (한달치 한번에 정리) -완- (0) | 2025.12.23 |
| 나만의 홈 스쿨 개발해보기~~ (3일차) (0) | 2025.12.01 |
| 나만의 홈 스쿨 개발해보기~~ (1일차) (0) | 2025.11.26 |
Comments