이제 누락된 메시지를 어떻게 전달할 수 있을지 봐보자.
이를 위해선
우선, 메시지가 누락됐는지 여부를 서버에서 체크해야 한다.
이때 사용할 수 있는 방법이 sequence다.
채팅방마다 sequence를 부여하고, message에 이 sequence를 넣어서 저장하고 웹소켓으로 전달하면 된다.
그러면, 클라이언트에서 메시지를 전달할 때 자신이 갖고 있는 가장 마지막 sequence까지 같이 넣어서 보내주면 된다.
서버에서는 그 채팅방의 lastSequence 값을 알고 있으니 클라이언트가 보낸 sequence 값과 비교한다.
A와 B가 실시간으로 채팅을 한다고 해보자.
A가 sequence 105, 106, 107, 108 메시지를 보냈다.
그런데, 네트워크 오류로 B는 이 메시지를 받지 못해서 마지막 sequence가 104다.(이게 a의 메시지이든 b의 메시지이든 상관없다)
그러면 채팅방의 마지막 sequence는 108인데, 클라이언트가 보낸 값은 104이니
서버에선 105, 106, 107, 108의 메시지가 전송되지 않았다는 것을 인지하게 된다.
이 아이디어는 네트워크에서 데이터를 송수신하는 방식에서 모티프를 얻어서 구현하게 됐다.
이제 코드를 한번 봐보자.
클라이언트에서는 위와 같은 형태로 메시지를 전송한다.
그러면, chatRoom에 기록된 이 lastSequence와 비교해서 누락된 메시지가 있는지 확인한다.
chat에도 sequence 값이 저장돼서 중복되는 문제는 있지만, 채팅으 보낼 때마다 chat을 스캔하는 것보다는 chat_room에 저장해놓은 값을 바로 쓰는 게 나을 거 같았다.
인덱스를 쓰더라도 chat이 쌓이면 db 부하가 커질 수밖에 없다고 생각했다. 어차피 지금 chat을 보낼 때 chat_room을 매번 update해주고 있으니(다른 기능 때문에)이때 같이 sequence도 업데이트해주면 된다.
지금은 우선 기능 구현에 집중해서
코드가 정돈이 안 됐다ㅎㅎ..
로직은 채팅방에서 시퀀스 넘버를 읽어오고 거기서 +1을 한 뒤에 이걸 message(chat)에 넣어준다.
그리고, 앞서 말했듯 누락된 메시지가 있는지 확인하고 있으면 그걸 return해줄 응답에 넣어준다.
between 쿼리를 쓰면 인덱스를 타지 못해서
in을 쓰는 방식으로 쿼리를 짰다.
이제 여기서 메시지를 전달하고+응답까지 내려준다.
응답에는 전송된 채팅과 누락된 메시지들이 같이 내려간다.
지금은 정말 기본적인 상황만 처리를 했다.
동시성 문제와
메시지누락 중
1)b가 보낸 메시지의 sequnece가 102인데 a가 보낸 메시지가 97은 해결됐지만
2)b가 보낸 메시지의 sequnece가 102인데 a가 보낸 메시지가 101, 102
이건 아직 처리를 못했다. 이것도 조만간 처리해야 한다.