실시간 채팅 구현 조금 생각을 해 보았다.
1) 온라인 -> socketio로 연결해서 실시간 통신
1.5) 백그라운드 -> FCM으로 push 알람만 보냄.
2) 오프라인 -> 아무것도 하지 않음.
다만 온라인으로 상태 변경 시, 서버에서 읽지 않은 메시지 목록을 전부 받아오면 될 듯.
+ 읽은 기능 구현은 users - room join table에 해당 유저가 접속한 시간을 적고, 그 시간이 갱신되면 그것보다 작은 것들의 읽은 시간을 갱신하면 될 듯.
저번에 올린 예제를 만든 파일의 경우, 인터넷 연결이 끊기면 메시지를 받을 수 없다는 문제점이 존재했다. 그래서 서버에 보낸 메시지를 저장하는 schema를 추가하려고 합니다. 형태는 ((보낸 시간, 방 번호), 보낸 사람, 메시지 내용) 정도로 생각하자. 해당 schema에 대해 지금은 임의대로 Messages라는 이름을 쓴다고 치자
각 기기에서 '메시지 전송'이라는 이벤트가 발생하면 서버의 Messages에 ((방 번호, 보낸 시간), 보낸 사람, 메시지 내용, 메시지 내용)을 추가하고 해당 채팅방에 속해있는 사람들에게 socket.io의 send(emit이었던가?)를 통해 메시지를 발송한다.
한편 인터넷 연결 끊김 등으로 서버에 연결되지 않은 사람들은 socketio의 send를 통해 메시지를 받을 수 없는데, 이런 사람들에 대해서 서버에 저정해 둔 Messages를 이용해 데이터를 줘야 할 것 같다.
1. 각 기기에서 제일 최근에 읽은 메시지의 시간을 기록하고 있는다. (utime이라 표기)
- 각 기기에서 보낸 시간을 서버로 전송하게 하면 될 것 같다. 그러면 socket.io에서 보낸 시간이 보내지고, Messages에서도 같은 값을 넣을 수 있게 될 것 같다.
2. 각 기기에서 서버에 로그인하거나 인터넷에 다시 접속되면 Messages table에 접근해 해당 유저가 속해있는 채팅방의 제일 최근에 보내진 메시지의 시간(stime이라 표기)과 utime을 비교해 stime이 더 크다면
3. 서버에서 해당 유저가 속해있는 채팅방에서, utime보다 큰 stime을 가지는 메시지들을 모두 서버에서 읽어온다.
SELECT * FROM Messages M
WHERE M.roomNum = userroomNum AND M.sendTime > utime AND M.senduserID != userID
이정도로 하면, 프론트에서 '유저가 속한 채팅방 번호', '제일 최근에 읽은 메시지의 시간', '유저 ID' 3개를 서버로 보내면 위의 1, 2, 3번을 수행할 수 있게 될 거 같다
그리고... 프론트에서 '인터넷 연결' 또는 '로그인'의 이벤트가 발생하면 해당 사람이 속해있는 모든 채팅방에서 위의 쿼리를 수행하면 될 것이다.
마지막으로 각 채팅방이 삭제될 때 message table에서 해당 채팅방의 채팅 기록을 삭제하면 서버에도 크게 부하가 걸릴 것 같지 않다.
이게 현업에서 이렇게 쓰는지는 모르겠는데, 일단은 이렇게 하면 실시간 채팅 비스무리한 걸 구현할 수 있지 않을까? 앱이 꺼졌을 때 어떻게 불러오는지는 프론트에서 알아서 하겠지...
이제 지금 올린 내용 그대로 작성하고 통합로그인 토큰 받아오는 걸 조금 작성하면 될 것 같다...
'Development > Socket.io' 카테고리의 다른 글
[Socket.io] Socket.io를 이용한 실시간 채팅 (0) | 2022.11.01 |
---|---|
[Socket.io] socket.io 간단한 예제 (0) | 2022.10.04 |