Quick Flow
network connection이 닫혔다고 player session과 월드 상태를 즉시 지우지 않습니다. server는 player를 disconnected로 바꾸고 유예 시간 안의 resume 권한만 받아 새 connection을 현재 session에 붙입니다. 유예가 끝난 뒤에야 AI 대체·패배·퇴장·seat 회수 같은 게임 규칙을 적용합니다.
connection close
-> session: active -> disconnected, grace deadline 기록
-> old connection generation 무효화
-> resume 요청: player·match·expiry·generation 검사
-> 새 connection attach
-> full snapshot + 필요한 reliable event 재전송
-> active| 상황 | session 상태 | server 행동 |
|---|---|---|
| 짧은 network 전환 | disconnected | player state와 seat 유지 |
| 유효한 resume | resuming | 이전 connection을 fencing하고 snapshot 재동기화 |
| 유예 시간 만료 | expired | 장르 규칙에 따라 퇴장·AI·패배 처리 |
| 이전 socket의 늦은 packet | 이전 generation | 무시 |
connection과 session을 분리하기
connection은 TCP socket이나 UDP endpoint처럼 네트워크 transport의 수명이고, player session은 player ID·match·instance·seat·입력 승인 지점을 가진 게임 상태의 수명입니다. 둘을 같은 객체로 두면 Wi-Fi 전환처럼 짧은 단절에서 player entity를 삭제했다가 다시 만들게 되고, 다른 client가 그 자리를 차지한 뒤 원래 player가 돌아오는 경우를 설명하기 어렵습니다.
resume 권한은 로그인 token을 무기한 재사용하는 것과 다릅니다. 특정 match와 player session에 묶고, 짧은 만료·한 번의 generation 교체를 둡니다. 새 connection을 붙일 때 session의 connectionGeneration을 증가시키고, 수신 command에 현재 generation 또는 connection-bound key가 맞는지 확인하면 old socket에서 늦게 도착한 입력을 버릴 수 있습니다.
function resume(session: PlayerSession, grant: ResumeGrant, connection: Connection) {
verifyResumeGrant(grant, session);
session.connectionGeneration += 1;
session.attach(connection, session.connectionGeneration);
sendFullState(session, connection);
}재동기화할 범위
재접속 client는 마지막 화면이 맞는지 추측하지 않습니다. server는 player의 authoritative state, 주변 entity의 spawn·despawn 상태, 현재 tick, 처리한 input sequence, 진행 중인 reliable event를 다시 보냅니다. delta snapshot만 보내면 client가 놓친 baseline을 기준으로 해석해 entity가 사라지거나 오래된 체력으로 남을 수 있습니다.
재접속 중 들어온 local input은 policy를 정합니다. 일반적으로 새 connection의 handshake와 full snapshot이 끝나기 전 command는 버리거나 queue하지 않습니다. queue한다면 어느 tick부터 적용하는지, disconnected 동안 입력을 받지 않았다는 사실과 충돌하지 않는지 명확해야 합니다.
유예 시간은 게임 규칙이다
유예 시간을 길게 두면 모바일·불안정 네트워크의 체감은 좋아지지만, 경쟁전에서는 연결을 끊어 위험을 피하거나 상대를 기다리게 만드는 악용 여지가 생깁니다. 짧게 두면 정상 network 전환이 곧 패배가 됩니다. match type, 랭크 여부, AI 대체 가능성, backfill 정책에 따라 다르게 정할 수 있습니다.
grace deadline은 client clock이 아니라 server tick 또는 server monotonic time으로 관리합니다. server process가 재시작될 수 있는 구조라면 session state와 deadline을 어디에 복구할지, process 장애와 client disconnect를 어떻게 구분할지도 운영 설계에 넣습니다.
새 socket이 붙었다고 이전 socket을 즉시 믿으면 한 player가 두 connection에서 command를 보낼 수 있습니다. session이 generation을 소유하고, 새 connection이 이전 generation을 반드시 fencing해야 합니다.
참고 링크
2 sources