일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Java
- Python
- 파이썬
- 노드개발
- 알고리즘
- static final
- email인증
- 백준 2667
- 실버5
- 너비우선탐색
- nodejs
- 노드프로젝트
- 노드개발자
- Gmail인증
- 앱개발
- DFS
- 코딩
- springboot
- 코테
- 쪽지기능
- 브실이의입시전략
- 프로그래머스
- 이메일인증
- 자바
- BFS
- 백준
- 코딩테스트
- 깊이우선탐색
- SWEA
- 1260
- Today
- Total
데옹의 블로그
Node.js 로 간단 쪽지 기능 구현 (2) 본문
Node.js 로 간단 쪽지 기능 구현 (1)
에서 말한 것처럼 API는 총 5개고 이번에는 나머지 2개를 해보겠습니다.
이번 포스트 에서는 아래 두개를 다룰거에요.
- 쪽지 방 (socket에선 room?) 을 생성
- 쪽지 방 확인하기 (카톡 방 처럼 리스트로 보이게 하려 했음)
- 쪽지 보내기
- 쪽지 확인하기
- 쪽지 방 나가기
4. 쪽지 확인하기
여기서부터는 생각도 꽤 하고 수정도 해가면서 만들었습니다.
우선 쪽지 방을 만들게 되면 그 곳엔 2명의 사람이 있을 것이고, 어떤게 내가 보냈는 지를 확인할 수 있어야 한다고 생각했습니다.
그러기 위해서 userIdx와 matchIdx를 따로 받을 수도 있었겠지만 그러지 않고 roomId에 식별자가 들어가있게 설정을 해두었으니 그 것과 JWT로 들어올 userIdx를 비교하여 무엇이 받는 쪽지고 무엇이 보낸 쪽지인지 확인할 수 있게 했습니다.
- Controller.js
// 쪽지 내용 확인
exports.getMsg = async function (req, res) {
const userIdxFromJWT = req.verifiedToken.userIdx;
const roomId = req.body.roomId; // '1_2' 의 형식으로 들어옴
if(!roomId) {
return res.send(response(baseResponse.MSG_ROOMID_EMPTY)); // error code
}
const arr = roomId.split("_"); // * 참고 1
const userIdx = arr[0]; // '1_2' 에서 1
const matchIdx = arr[1]; // '1_2' 에서 2
// 보낸/받는 사람 구별
if (userIdxFromJWT == userIdx) { // JWT로 받은 인덱스가 arr[0]과 같다면
const sender = userIdx; // 우리는 위 주석에서 1에 해당하는 사람으로 인식됩니다.
const receiver = matchIdx;
const result = await msgProvider.getMsg(roomId, sender, receiver);
return res.send(response(baseResponse.SUCCESS, result));
}
else if (userIdxFromJWT == matchIdx) { // 반대의 경우
const sender = matchIdx;
const receiver = userIdx;
const result = await msgProvider.getMsg(roomId, sender, receiver);
return res.send(response(baseResponse.SUCCESS, result));
}
};
**** 변수 명은 먼저 아무거나 알아보기 편하게 설정한 것이니 의미 부여 너무 하지 않기 ****
* 참고 1
split이라는 함수를 사용해서 body로 받아온 roomId를 분리한 것입니다.
위에서는 split("_") 으로 했는데 이 것은 _를 기준으로 나누는거에요. 그럼 '1_2' 가 1 과 2 로 분리가 됩니다.
위에 주석에 간단히 써놨는데 더 자세히 써보자면
JWT로 넘어온 userIdx 가 1이라고 했을 때 DB의 senderIdx가 1이면 '보낸 쪽지', 1이 아니면 '받은 쪽지'로 나와야 합니다.
그걸 하나의 쿼리로 다 뽑기 위해서 if문을 사용한건데
jwt로 받은 userIdx와 MsgRoom에 있는 userIdx가 동일하면 userIdx가 sender가 되고 그 반대는 matchIdx가 sender가 됩니다. (userIdx = 채팅방 만든 사람, matchIdx = 채팅방에 참여한 사람)
고대로 파라미터를 Provider.js로 보내줍니다.
- Provider.js
exports.getMsg = async function (roomId, sender, receiver) {
try {
const params = [sender, receiver, roomId];
const connection = await pool.getConnection(async (conn) => conn);
const getMsgResult = await msgDao.getMsg(connection, params);
connection.release();
return getMsgResult;
} catch (err) {
logger.error(`getMsg Provider error\n: ${err.message}`);
return errResponse(baseResponse.DB_ERROR);
}
};
위에서 이미 sender와 receiver를 구분해서 값을 받아왔기 때문에 딱히 뭔가를 해줄 필요는 없습니다.
그냥 이대로 Dao로 넘기면 될 것 같아요.
- Dao.js
SELECT (CASE
WHEN senderIdx = ? THEN 'send'
WHEN senderIdx = ? THEN 'receive'
END) AS status, text, sendAt
FROM Message WHERE roomId = ? ORDER BY sendAt ASC;
간단한 select문인데 case when을 추가하여 각 상황에 맞게 나올 수 있도록 했습니다.
1과 2가 쪽지를 주고 받을 때 Controller에서 1 이라는 userIdx를 sender로 인식했다면 Provider에서의 파라미터 값은
[ 1, 2, 1_2] 가 되겠죠. (sender, receiver, roomId)
이 순서대로 쿼리문에 들어갈테니
senderIdx = 1 이면 'send'
senderIdx = 2 이면 'receive'로 표시가 될 것입니다.
이 것들을 보낸 시각 즉 sendAt을 오름차순으로 정렬을 했습니다.
이렇게 쪽지 보내기는 마무기가 됩니다.
4. 쪽지 방 삭제하기
마지막으로 쪽지 삭제하기 입니다.
우선 쪽지 삭제는 이렇게 진행이 돼요..
roomId = '1_2' 라고 예를 들게요~!
- 1이 쪽지 방을 삭제하더라도 2는 이전에 쪽지를 볼 수 있어야 한다.
- 둘 다 나가면 DB에서 삭제
대충 이런 목적을 갖고 만들었는데, 함 볼게여
- Controller.js
exports.deleteMsg = async function (req, res) {
const userIdx = req.verifiedToken.userIdx;
const roomId = req.body.roomId;
if(!roomId) {
return res.send(response(baseResponse.MSG_ROOMID_EMPTY)); // error code
}
const arr = roomId.split("_");
const userIdxAtRoom = arr[0];
const matchIdxAtRoom = arr[1]; // roomId를 분리하면서 Index 파악
const getRoomIdxResult = await msgProvider.getRoomIdx(roomId); // DB에 있는 index 확인
const MsgRoomUserIdx = getRoomIdxResult[0].userIdx;
const MsgRoomMatchIdx = getRoomIdxResult[0].matchIdx; // 할당
if(MsgRoomUserIdx == 7 || MsgRoomMatchIdx == 7) { // 만약 둘 중 하나라고 7이라면
const result = await msgService.deleteMsg(roomId); // 방 바로 삭제
} else if(userIdx == userIdxAtRoom) {
const result = await msgService.updateExitUserIdx(roomId, MsgRoomMatchIdx, 1);
} else if(userIdx == matchIdxAtRoom) {
const result = await msgService.updateExitUserIdx(roomId, MsgRoomUserIdx, 2);
} // 나머지 else if문은 내가 해당되는 index를 바꿔주기 위함
return res.send(baseResponse.SUCCESS);
}
보기 전에 7이라는 userIdx는 제가 그냥 dummy data로 넣은 것입니다. 그냥 제가 만들기 편할 것 같아서 넣었어요.
roomId를 분리하는 것까진 위에서 했으니 따로 하진 않겠습니다.
DB에 있는 index확인은 왜 하냐면.. 거기에 지금 dummy data가 있는지 확인하고 값들을 할당해주기 위함입니다. 아까 말한 상황들을 제대로 수행하려면 확인하고 둘 중 하나라고 dummy data가 있는지 확인해야해요!
그 밑의 할당이라고 쓴 주석은 그냥 진짜 할당만 해준거에요. 바로 위에서 얻은 값들을요.
간단한 get 즉 select문이기 때문에 따로 Provider와 Dao를 적지는 않겠습니다.
그 밑의 if문을 보겠습니다.
우선 만약 둘 중 하나라도 이미 7 즉 dummy data라면 그냥 방을 아예 DB에서 삭제해버리는 겁니다.
근데 그 밑의 것들은 좀 달라요..
둘 중 하나라고 더미데이터가 아닌 상황인데, 그럼 제가 해당되는 컬럼의 index를 더미데이터로 바꿔줘야겠죠.
그 부분을 위해서 2명이 쪽지하는거니까 2개의 상황을 만든거고, Service로 넘어가는 파라미터 중 1,2 는 index가 아니고 Service에서 type별로 로직을 나눠뒀기 때문에 여기서 한 번에 보내주는 거에요!
바로 Service 보겠습니다.
- Service.js
exports.deleteMsg = async function (roomId) {
try {
const connection = await pool.getConnection(async (conn) => conn);
const deleteMsgResult = await msgDao.deleteMsg(connection, roomId);
connection.release();
return response(baseResponse.SUCCESS);
}
catch (err) {
logger.error(`App - deleteMsg Service error\n: ${err.message}`);
return errResponse(baseResponse.DB_ERROR);
}
}
첫번째로 둘 중 하나라도 dummy data가 있으면 방을 아예 삭제해버린다고 했죠.
그냥 간단하게 DB에서 삭제해버리는 로직입니다.
Dao도 굉장히 간단해요.
DELETE FROM MessageRoom
WHERE roomId = ?;
그냥 이 정도....
근데 이제 두개 다 dummy data가 아니다..?
exports.updateExitUserIdx = async function (roomId, remain, type) {
try {
var params;
if(type == 1) {
params = [7, remain, roomId];
} else if(type == 2) {
params = [remain, 7, roomId];
}
const connection = await pool.getConnection(async (conn) => conn);
const updateExitUserIdx = await msgDao.updateExitUserIdx(connection, params);
connection.release();
return response(baseResponse.SUCCESS);
}
catch (err) {
logger.error(`App - updateExitUserIdx Service error\n: ${err.message}`);
return errResponse(baseResponse.DB_ERROR);
}
}
다른건 사실 볼 필요가 없고 if문에 들어가 있는 것만 보면 됩니다.
아까 Controller에서 type별로 1,2 나눠서 파라미터를 전송해줬습니다. 그 안의 코드는 내가 어느 컬럼에 속해있는지 판단해서 타입별로 나눠 보내게 된 것이었는데요.
1번의 경우 내 userIdx가 roomId = '1_2' 중 1이었다면 그 위치의 컬럼을 dummy data로 바꿔버릴거에요.
2번은 그 반대구요.
remain에는 roomId에서 내 userIdx가 아닌 index가 들어가있습니다.
UPDATE MessageRoom
SET userIdx = ?, matchIdx = ?
WHERE roomId = ?;
그래서 따로 정리할 것 없이 이렇게 해버리면 1번의 경우엔 userIdx = 7, matchIdx = 2 가 되겠죠.
그럼 성공입니다 ㅎㅎ userIdx 에 속한 사람은 나갔다고 표시가 될거에요!
여기까지가 끝입니다..
완벽한 코드도 아니고 그냥 제가 만들어보고 싶어서 만들었어요.
그래도 좀 종이에 로직을 써가며 어떤 오류가 생기는지 보면서 테스트 했고, 나름 괜찮은 결과를 얻은 것 같습니다.
같은 팀 내의 프론트엔드 분께 일단 API sheet를 전달해드렸는데 오늘 결과물이 나올 것 같네요 ㅠㅠ
결과물이 나온다면 또 쓰러 와야지...
아직 뭔가를 다루는 것이 어설픈 것 같은데 언제쯤 능숙해져서 시니어 개발자처럼 멋있어질지 모르겠네요.
Nodejs도 정말 좋지만, 제가 취업하고 싶은 회사는 Spring을 사용하기에..
함 도전해보려 합니다
그럼 20000
'NodeJS' 카테고리의 다른 글
Node.js 로 간단 쪽지 기능 구현 (1) (0) | 2022.08.12 |
---|