socket.on("enter_room", async (roomInfo) => {
const objData = JSON.parse(roomInfo);
const {createRoom, roomNum} = await createChattingRoom(objData);
socket["roomNum"] = roomNum;
socket.join(roomNum);
var {chats} = await importChatting(createRoom);
chats = JSON.stringify(chats);
console.log(chats);
io.sockets.to(roomNum).emit("load-message", chats);
});
export const createChattingRoom = async (data) => {
const {userList, roomNum} = data;
let createRoom = await ChatsRoom.findOne({roomNum});
if (createRoom) {
return {
createRoom,
roomNum,
};
}
createRoom = await ChatsRoom.create({roomNum});
userList.foreach(async (name, index) => {
const user = await User.findOne({name});
if (!user) {
console.log("not found user");
return;
}
user.rooms.push(createRoom._id);
createRoom.user.push(user._id);
user.save();
if (index === userList.length - 1) {
await createRoom.save();
}
});
if (createRoom) {
return {
createRoom,
roomNum,
};
}
};
if (index === userList.length - 1)
await createRoom.save();
순회 할 때마다 save를 시키지 말라고 우리의 mongoose가 불만을 표출하길래, 위의 조건을 달아줬다.
const importChatting = async (createRoom) => {
return ChatsRoom.findOne({roomNum: createRoom.roomNum})
.select("-_id")
.populate({
path: "chats",
select: "-_id -chatRoom",
});
};
단순한 mongoose를 이용한 데이터 불러 오기다.
socket.to(roomNum).emit("load-message",chats);
의 로직으로 방에 들어갔을 시 기존의 메세지를 불러와지기를 바랬지만
A,B유저의 방에서 A유저가 입장을 하면 B쪽에서만 메세지가 불러와졌다.
이는 소캣의 동작 방식 때문인데 기본적으로 emit는 자신을 제외한 같은 방 인원에게 이벤트를 보내는 것이기 때문이다.
socket.to(roomNum).emit("load-message",chats);
자신에게도 이벤트를 보내기 위해서는 BroadCast를 사용해서 이벤트를 보내줘야 했다.
단 또 문제가 생겼다. 네임스페이스를 적용시킨 방에게는 이벤트가 가지 않은 것이다.