접속 상태는 요구사항 목록의 맨 끝에 붙는 기능인데 쓰기는 가장 많습니다. 메시지는 말할 때만 생기지만 접속 상태는 사람이 앱을 열고 닫을 때마다, 그리고 살아 있다고 알리는 신호마다 생깁니다.
그래서 이 기능은 정확도를 낮춰 비용을 낮추는 것이 정석입니다. 상대가 3초 전에 나갔는지 30초 전에 나갔는지는 아무도 신경 쓰지 않습니다.
살아 있다고 알리고, 조용하면 사라진다
접속 상태를 어딘가에 기록하면 그것을 지울 책임이 생깁니다. 앞 단계에서 본 대로 비정상 종료는 스스로 정리할 기회가 없습니다. 그래서 지우는 대신 만료를 씁니다.
여기서 중요한 것은 만료를 갱신 주기의 2배로 두는 것입니다. 같게 두면 갱신이 몇 초 늦게 도착하는 순간마다 접속자가 오프라인으로 깜빡입니다. 여유를 두면 한 번 놓쳐도 상태가 뒤집히지 않습니다.
| 값 | 정하는 기준 |
|---|---|
| 갱신 주기 | 짧으면 쓰기가 늘고 길면 사라진 것을 늦게 안다 |
| 만료 시간 | 갱신 주기의 2배 이상. 한 번 놓치는 것을 견딘다 |
화면에 보이는 사람만 구독한다
접속 상태의 진짜 비용은 저장이 아니라 전파입니다. 상태 하나가 바뀔 때 그 사람을 보고 있는 모든 사람에게 알려야 합니다.
앱을 열 때 내가 속한 모든 채널의 참여자를 구독하면, 큰 채널에 든 사용자 한 명이 수만 건을 구독합니다. 그래서 지금 화면에 보이는 사람만 구독하고 화면을 벗어나면 해지합니다.
대화방 목록을 보고 있다: 목록에 보이는 상대만
대화방 안에 있다: 그 채널의 참여자 중 화면에 보이는 사람만
큰 채널: 접속 상태를 아예 보여주지 않는다
이 판단은 읽음 표시에서와 같습니다. 채널이 커지면 기능을 줄입니다.
한 사람이 여러 기기를 쓴다
기기마다 따로 신호를 보내므로 상태는 기기 단위로 저장하고, 사람의 상태는 하나라도 살아 있으면 접속 중으로 계산합니다.
기기 하나가 꺼졌다고 오프라인으로 바꾸면 컴퓨터를 닫는 순간 휴대폰을 쓰고 있는데도 오프라인이 됩니다.
타이핑 표시는 저장하지 않는다
타이핑 표시는 접속 상태보다 더 잦고 더 짧게 삽니다. 이것을 저장소에 쓰면 시스템에서 가장 많은 쓰기가 되는데, 3초 뒤에는 아무 의미가 없는 데이터입니다.
| 성격 | 처리 |
|---|---|
| 몇 초만 유효하다 | 저장하지 않고 전달만 한다 |
| 잃어도 문제가 없다 | 재시도하지 않는다 |
| 매 글자마다 생긴다 | 클라이언트가 몇 초에 한 번으로 줄여 보낸다 |
잃어도 되는 데이터는 잃어도 되게 다룹니다. 모든 데이터를 같은 무게로 다루면 정작 중요한 메시지 저장이 느려집니다.
마지막 접속 시각은 조심해서 다룬다
"3분 전 접속" 같은 표시는 상대의 생활 패턴을 노출합니다. 끄는 설정을 주고, 끈 사람은 남의 것도 볼 수 없게 합니다. 읽음 표시와 같은 규칙입니다.