채팅내용이 누락되는 현상이 발생해요!
채팅기능을 많이 사용하는 고객사에서 채팅내용이 자꾸 누락이 되는 경우가 발생한다는 오류문의가 들어왔습니다. 우선 플로우는 채팅부분을 개발하기 위해서 Socket.io를 사용 했습니다. socket.io는 연결이 끊어지면 다시 연결을 시도하는 로직이 존재해서 웬만해선 소켓이 사용중에 끊어지는 현상이 발생하지 않습니다. 그렇게 여러가지 테스트를 통해서 데이터가 유실되는 순간을 찾았습니다.
네트워크 연결이 끊어지는 경우
너무나도 당연한 이야기라고 생각 할 수 있지만 네트워크가 끊어진다면 당연히 Client단 소켓통신 역시 끊어지게 되고 이 상황에 메시지를 상대방이 보낸다면 해당 메시지는 누락이 발생하게 됩니다.
네트워크가 끊어지는 경우를 왜 파악하지 못했을까?
왜 네트워크 연결이 끊어진 상황을 인지하지 못했을까요? 보통의 네트워크 연결이 끊어지면 인터넷이 안되고 하단의 인터넷 연결이 끊어졌다고 표시가 나는데도 …. 원인은 바로 절전모드에 있었습니다. 절전모드가 발생하면 해당 PC는 네트워크의 연결또한 끊어두고 다시 사용자가 PC를 사용하게 되면 이를 인지해서 연결을 해줍니다. 이 부분에서 짧은시간 절전모드가 된다면 네트워크를 끊어두지 않지만 테스트 해본 결과 30분에서 1시간이상 시간이 경과하면 네트워크를 끊어버립니다. 이러한 이유로 절전모드가 발생한 시점동안의 메시지가 온다면 그 데이터들은 유실이 발생하는 것이지요
네트워크가 재연결이 되어도 소켓통신이 안되는 경우발생!
데이터가 유실이 발생하는 지점을 찾았지만… 한가지 더 문제가 있었는데요 바로 절전모드 이후에 소켓통신을 진행해도 통신이 안되는 문제가 있었습니다. 이 부분은 Socket.io가 연결을 끊고 다시 연결을 시도 할떄마다 새로운 socket.id를 생성하게 되는데 채팅방이라는 구조안에는 socket.io에서 제공하는 Room이라는 소켓이라는 큰 틀안에 각각의 방을 만드는데 이 방에 있는 아이디가 계속 변경 되면서 해당 통신 구간에 문제가 발생하게 된 것입니다.
어떤식으로 해결을 해야할까?
우선적 Offline.js 라이브러리를 사용해서 네트워크 연결이 끊어진 시점과 다시 연결된 시점을 확인하고 연결이 되는 순간에 소켓을 다시 연결하도록 처리를 했습니다. 여기서 단순히 소켓만을 연결하면 Room간의 socket.id가 맞지 않기 때문에 Room 또한 다시 Join을 시켰습니다. 이렇게 되면 네트워크가 끊어지고 다시 연결되는 순간 다시 연결을 해주어서 실시간 통신에서 생기는 오류가 해결됩니다.
두번째로는 네트워크가 끊어진 시점에 보내진 메시지들을 다시 보여줘야 하기 때문에 네트워크가 연결이 끊어진 시점의 마지막 채팅메시지의 시작점을 기록하고 데이터베이스의 존재하는 마지막 시점의 메시지가 다르다면 디비에서 그 차이 만큼의 데이터를 불러와서 해당 부분을 채워 넣는 로직을 추가 했습니다.
Notices
블로그를 대충이라도 많이많이 쓰자!