
채팅 프로그램 입장하기 위한 닉네임 로그인 ⭕️
단체 채팅방(room)
1:1 채팅방(DM 구현 응용)
닉네임, 채팅방 로그인 UI

room 구현
// 클라이언트를 특정 방으로 추가
socket.join("roomA");
// 클라리언트를 특정 방에서 제거
socket.leave("roomA");
// 특정 방에 속한 모든 클라이언트에게 특정 이벤트와 데이터를 발송
io.to("roomA").emit("msg", "hello");
단체 채팅방 입장 & 채팅 입력
socket.on("entry", (res) => {
if (Object.values(userIdArr).includes(res.userId)) {
// 닉네임이 중복될 경우에
socket.emit("error", {
msg: "중복된 아이디가 존재하여 입장이 불가합니다.",
});
} else {
// 닉네임이 중복되지 않을 경우에
// 해당하는 단체방에 입장
socket.join(res.roomId);
console.log(res.roomId);
// 특정 방에 속한 모든 클라이언트에게 전달
io.to(res.roomId).emit("notice", {
msg: `${res.userId}님이 입장하셨습니다.`,
});
socket.emit("entrySuccess", { userId: res.userId });
userIdArr[socket.id] = res.userId;
}
console.log(userIdArr);
updateUserList();
});
io.to(res.roomId).emit("chat", { userId: res.userId, msg: res.msg });새로 고침 & 사이트를 나갈 때 서버 에러 발생

💡 에러 해결
disconnection 하는 부분에서 매개변수를 받지 않는데, 위에 처럼 동일한 코드를 사용해서 에러 발생❗
io.to(res.roomId).emit("notice", ~~~);
해결 방법 : userIdArr 처럼 roomId를 저장해서 서버 내에서 사용할 수 있도록 객체 생성.
const userRoomIdArr = {};
socket.on("entry", (res) => {
if (Object.values(userIdArr).includes(res.userId)) {
socket.emit("error", {
msg: "중복된 아이디가 존재하여 입장이 불가합니다.",
});
} else {
socket.join(res.roomId);
// userRoomIdArr에 roomId 저장
userRoomIdArr[socket.id] = res.roomId;
io.to(res.roomId).emit("notice", {
msg: `${res.userId}님이 입장하셨습니다.`,
});
socket.emit("entrySuccess", { userId: res.userId });
userIdArr[socket.id] = res.userId;
}
updateUserList();
});
socket.on("disconnect", () => {
if (userIdArr[socket.id]) {
io.to(userRoomIdArr[socket.id]).emit("notice", {
msg: `${userIdArr[socket.id]}님이 퇴장하셨습니다.`,
});
// 클라이언트를 특정 방에서 나가게 함
socket.leave(userRoomIdArr[socket.id]);
// userRoomIdArr 에서도 삭제
delete userRoomIdArr[socket.id];
delete userIdArr[socket.id];
}
console.log(userIdArr);
updateUserList();
});
단체 채팅방 들어와있는 사람 목록
기존에 모든 userList를 클라이언트측에 넘겨줬다면 이제는 특정 방에 대한 userList를 넘겨줌
동일한 userList를 계속 변경해서 보냈더니, 가장 마지막에 입장하는 user에 대해서만 userList가 변경됨 (오류!)
const updateUserList = (roomId) => {
// userRoomIdArr에서 roomId와 일치하는 socket.id 찾기
const socketIdInRoom = Object.keys(userRoomIdArr).filter(
(socketId) => userRoomIdArr[socketId] === roomId
);
// userIdArr에서 socketIdInRoom 배열과 일치하는 socket.id : userId 저장
const usersInRoom = socketIdInRoom.reduce((acc, socketId) => {
acc[socketId] = userIdArr[socketId];
return acc;
}, {});
io.emit("userList", usersInRoom);
};
const updateAllRoom = (roomId) => {
// userRoomIdArr에서 roomId와 일치하는 socket.id 찾기
const socketIdInRoom = Object.keys(userRoomIdArr).filter(
(socketId) => userRoomIdArr[socketId] === roomId
);
// userIdArr에서 socketIdInRoom 배열과 일치하는 socket.id : userId 저장
const usersInRoom = socketIdInRoom.reduce((acc, socketId) => {
acc[socketId] = userIdArr[socketId];
return acc;
}, {});
if (roomId === "FRONTEND") io.emit("updateFrontList", usersInRoom);
else if (roomId === "BACKEND") io.emit("updateBackList", usersInRoom);
else io.emit("updateFullList", usersInRoom);
};
단체 채팅방 나가기
const handleRefreshClick = () => {
window.location.reload(true);
};
<button onClick={handleRefreshClick}>✖️</button>
단체 채팅방 UI

개인 채팅방 입장
프로젝트 시작해서
나중에 다시 해보는걸로...