Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#270 안 읽은 메세지 확인 #305

Merged
merged 28 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d77856f
Add: updateChatHandler
chlehdwon May 29, 2023
5c40faa
Add: emitUpdateEvent
chlehdwon May 30, 2023
a9c3b01
Add: sendChatHandler
chlehdwon May 30, 2023
76844ff
Add: readAt in participantSchema
chlehdwon May 30, 2023
9186492
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Aug 9, 2023
5369fe0
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Aug 28, 2023
63896a3
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 3, 2023
37b514b
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 4, 2023
f81a2f9
Refactor: apply prettier
chlehdwon Sep 4, 2023
52b5747
Add: partInfoHandler
chlehdwon Sep 4, 2023
b41425b
Refactor: change updateChatHandler to readChatHandler
chlehdwon Sep 5, 2023
92cab6a
Remove: partInfoHandler
chlehdwon Sep 5, 2023
3737777
Remove: parameter userId in emitUpdateEvent
chlehdwon Sep 5, 2023
455497a
Fix: disconnectSocket channel
chlehdwon Sep 5, 2023
9859916
Fix: change endpoint of readChatHandler
chlehdwon Sep 5, 2023
0d1a745
Remove: import formatSettlement
chlehdwon Sep 5, 2023
d658d93
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 11, 2023
8270cdd
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 17, 2023
8092fa1
Fix: fix format
chlehdwon Sep 17, 2023
784cad3
Remove: lastMsgDate in readChatHandler
chlehdwon Sep 17, 2023
86babb6
Refactor: change readAt field to optional
chlehdwon Sep 17, 2023
341b11f
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 18, 2023
b5a9331
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 19, 2023
fdc18d7
Refactor: chat.js
chlehdwon Sep 19, 2023
6f9d1a9
Remove: readAt default value
chlehdwon Sep 19, 2023
8f64026
Fix: change Date.now() and remove isPart
chlehdwon Sep 19, 2023
9fbd089
Fix: remove redundatn populate option
chlehdwon Sep 24, 2023
9bdbbc4
Merge branch 'dev' of https://github.com/sparcs-kaist/taxi-back into …
chlehdwon Sep 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/modules/auths/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const login = (req, sid, id, oid, name) => {
const logout = (req) => {
// 로그아웃 전 socket.io 소켓들 연결부터 끊기
const io = req.app.get("io");
if (io) io.in(req.session.id).disconnectSockets(true);
if (io) io.in(`session-${req.session.id}`).disconnectSockets(true);
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved

req.session.destroy((err) => {
if (err) logger.error(err);
Expand Down
2 changes: 1 addition & 1 deletion src/modules/populates/rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const roomPopulateOption = [
{ path: "to", select: "_id koName enName" },
{
path: "part",
select: "-_id user settlementStatus",
select: "-_id user settlementStatus readAt",
populate: { path: "user", select: "_id id name nickname profileImageUrl" },
},
];
Expand Down
34 changes: 32 additions & 2 deletions src/modules/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,35 @@ const emitChatEvent = async (io, chat) => {
}
};

const emitUpdateEvent = async (io, roomId) => {
try {
// 방의 모든 사용자에게 socket 메세지 업데이트 이벤트를 발생시킵니다.
if (!io || !roomId) {
throw new IllegalArgumentsException();
}

const { name, part } = await roomModel.findById(roomId, "name part");

if (!name || !part) {
throw new IllegalArgumentsException();
}

const userIds = part.map((participant) => participant.user);
await Promise.all(
userIds.map(async (userId) =>
io.in(`user-${userId}`).emit("chat_update", {
roomId,
})
)
);
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved

return true;
} catch (err) {
logger.error(err);
return false;
}
};

// https://socket.io/how-to/use-with-express-session 참고
const startSocketServer = (server) => {
const io = new Server(server, {
Expand All @@ -198,7 +227,7 @@ const startSocketServer = (server) => {
setHeader(key, values) {
req.cookieHolder = values[0];
},
writeHead() {},
writeHead() { },
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved
};
sessionMiddleware(req, fakeRes, () => {
if (req.session) {
Expand Down Expand Up @@ -235,7 +264,7 @@ const startSocketServer = (server) => {
socket.join(`user-${userOid}`);
});

socket.on("disconnect", () => {});
socket.on("disconnect", () => { });
} catch (err) {
logger.error(err);
}
Expand All @@ -247,5 +276,6 @@ const startSocketServer = (server) => {
module.exports = {
transformChatsForRoom,
emitChatEvent,
emitUpdateEvent,
startSocketServer,
};
2 changes: 2 additions & 0 deletions src/modules/stores/mongo.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const participantSchema = Schema({
enum: ["not-departed", "paid", "send-required", "sent"],
default: "not-departed",
},
readAt: { type: Date, required: true, default: () => Date.now() },
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved
});

const deviceTokenSchema = Schema({
Expand Down Expand Up @@ -117,6 +118,7 @@ const locationSchema = Schema({
latitude: { type: Number }, // 이후 required: true 로 수정 필요
longitude: { type: Number }, // 이후 required: true 로 수정 필요
});

const chatSchema = Schema({
roomId: { type: Schema.Types.ObjectId, ref: "Room", required: true },
type: {
Expand Down
12 changes: 12 additions & 0 deletions src/routes/chats.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ router.post(
chatsHandlers.sendChatHandler
);

/**
* 채팅 읽은 시각 업데이트 요청을 처리합니다.
* 같은 방에 있는 user들에게 업데이트를 요청합니다.
*/
router.post(
"/read",
body("roomId").isMongoId(),
body("lastMsgDate").isISO8601(),
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved
validator,
chatsHandlers.readChatHandler
);

// 채팅 이미지를 업로드할 수 있는 Presigned-url을 발급합니다.
router.post(
"/uploadChatImg/getPUrl",
Expand Down
62 changes: 61 additions & 1 deletion src/services/chats.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
const { chatModel, userModel, roomModel } = require("../modules/stores/mongo");
const { chatPopulateOption } = require("../modules/populates/chats");
const aws = require("../modules/stores/aws");
const { transformChatsForRoom, emitChatEvent } = require("../modules/socket");
const {
transformChatsForRoom,
emitChatEvent,
emitUpdateEvent,
} = require("../modules/socket");
const {
roomPopulateOption,
} = require("../modules/populates/rooms");

const chatCount = 60;

Expand Down Expand Up @@ -165,6 +172,58 @@ const sendChatHandler = async (req, res) => {
}
};

const readChatHandler = async (req, res) => {
try {
const io = req.app.get("io");
const { userId } = req;
const { roomId, lastMsgDate } = req.body;
const user = await userModel.findOne({ id: userId });

if (!userId || !user) {
return res.status(500).send("Chat/read : internal server error");
}
if (!io) {
return res.status(403).send("Chat/read : socket did not connected");
}
const isPart = await isUserInRoom(userId, roomId);
if (!isPart) {
return res
.status(403)
.send("Chat/read : user did not participated in the room");
}
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved

const roomObject = await roomModel
.findOneAndUpdate(
{
_id: roomId,
part: {
$elemMatch: {
user: user._id,
},
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved
},
},
{
$set: { "part.$[updater].readAt": lastMsgDate },
},
{
new: true,
arrayFilters: [{ "updater.user": { $eq: user._id } }],
}
)
.lean()
.populate(roomPopulateOption);
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved
chlehdwon marked this conversation as resolved.
Show resolved Hide resolved

if (!roomObject) {
return res.status(404).send("Chat/read : cannot find room info");
}

if (await emitUpdateEvent(io, roomId)) res.json({ result: true });
else res.status(500).send("Chat/read : failed to emit socket events");
} catch (e) {
res.status(500).send("Chat/read : internal server error");
}
};

const uploadChatImgGetPUrlHandler = async (req, res) => {
try {
const { type, roomId } = req.body;
Expand Down Expand Up @@ -277,4 +336,5 @@ module.exports = {
sendChatHandler,
uploadChatImgGetPUrlHandler,
uploadChatImgDoneHandler,
readChatHandler,
};