애플리케이션 keepalive는 클라이언트 타임아웃보다 짧게 보낸다
클라이언트 라이브러리가 「아무것도 못 받으면 재접속」하는 시간을 확인하고, 그보다 자주 상태를 바꾸지 않는 메시지를 보낸다.
공동 편집 화면에 혼자 있을 때만 일정한 주기로 연결이 끊겼다 붙는다. 다른 사람이 들어와 무언가 하고 있으면 멀쩡하다.
많은 실시간 클라이언트 라이브러리는 「일정 시간 아무 메시지도 못 받으면 연결이 죽었다고 보고 재접속」한다. 예를 들어 y-websocket은 30초 동안 아무것도 받지 못하면 재접속한다. 혼자 있으면 서버가 보낼 것이 없으니 그 시간이 그대로 지나간다.
서버의 웹소켓 ping/pong으로는 풀리지 않는다. 프로토콜 수준 ping/pong은 브라우저가 처리해 자바스크립트에 보이지 않으므로, 애플리케이션의 타임아웃 시계를 되돌리지 못한다.
클라이언트 타임아웃보다 충분히 짧은 간격으로, 애플리케이션 수준의 무해한 메시지(상태를 바꾸지 않는 메시지)를 보낸다. 30초 타임아웃이라면 서버는 10초 동안 보낸 것이 없을 때 하나를 보낸다.
import asyncio
import time
IDLE_SECONDS = 10 # 클라이언트 타임아웃(30초)보다 충분히 짧게
async def keepalive(conn) -> None:
while not conn.closed:
await asyncio.sleep(1)
if time.monotonic() - conn.last_sent >= IDLE_SECONDS:
await conn.send(conn.noop_message()) # 상태를 바꾸지 않는 메시지
conn.last_sent = time.monotonic()
먼저 쓰는 클라이언트 라이브러리의 재접속 타임아웃 값을 문서나 소스에서 확인한다. 그 값이 keepalive 간격을 정하는 기준이다.