Quick Flow
매칭 backend가 matchId만 client에 주고 아무 연결이나 받으면 정원 초과·타인 입장·동시 재시도 문제가 생깁니다. backend는 짧은 수명의 입장 권한을 발급하고, game server는 이를 검증한 뒤 player별 seat를 한 번만 joined로 전환합니다.
match completed
-> backend: playerId, matchId, instanceId, expiry를 묶은 join grant 발급
-> client: game server에 grant 제시
-> server: 서명·만료·match·player·instance·seat 상태 확인
-> seat reserved -> joined 전환
-> 초기 snapshot 전송 후 command 허용| 입장 요청 | server 처리 | 이유 |
|---|---|---|
| 처음 받은 유효 grant | seat 예약 후 연결 승인 | 정원과 소유권 확정 |
| 같은 grant 재전송 | 같은 player의 현재 session 반환 또는 거부 | retry가 seat를 두 번 쓰지 않음 |
| 만료·다른 instance grant | 거부 | 오래된 결과나 다른 match 유입 방지 |
| 이미 다른 연결이 활성 | generation 비교 후 교체 또는 거부 | 한 player가 두 simulation을 조작하지 않음 |
입장 권한의 범위
join grant에는 최소한 player ID, match ID, instance ID, 만료 시각, 권한 ID가 필요합니다. client가 이 값을 바꿀 수 없도록 backend가 서명한 token 또는 server가 조회할 수 있는 opaque token으로 만듭니다. raw user ID나 matchId만 query string에 넣는 것은 입장 권한이 아닙니다.
권한은 한 match·한 instance·한 player에만 묶습니다. 관전, backfill, reconnect는 같은 형식의 token을 쓰더라도 role과 허용 seat를 분리합니다. 입장 token을 너무 오래 유지하면 유출된 token이 늦게 사용될 수 있고, 너무 짧으면 mobile 전환·loading에서 정상 입장이 실패합니다. 만료 시간은 client loading time과 reconnect 정책을 기준으로 정하고, 만료 뒤에는 backend에서 새 권한을 발급합니다.
server는 grant를 검증한 뒤 바로 input을 받지 않습니다. player state를 instance에 attach하고, spawn 또는 reconnect 위치를 정하고, 초기 snapshot과 필요한 reliable event를 보낸 뒤 active 상태로 바꿉니다. 이 순서를 지키면 snapshot 이전에 온 move command가 아직 없는 entity를 움직이는 일을 막을 수 있습니다.
seat 상태를 원자적으로 바꾸기
두 connection이 거의 동시에 같은 grant를 제시할 수 있습니다. if seat is free를 읽은 뒤 나중에 쓰는 방식만으로는 둘이 모두 성공할 수 있습니다. instance가 하나의 tick thread로 seat 전이를 소유하거나, 공유 저장소를 쓴다면 compare-and-set 또는 transaction으로 reserved -> joined 전이를 한 번만 허용합니다.
seat를 예약하고 connection이 끝내 오지 않으면 정원이 영구히 줄어듭니다. reservation에는 expiry를 두고, server가 handshake 완료 전 끊긴 connection의 seat를 회수합니다. 반대로 match가 시작된 뒤에는 seat를 바로 다른 player에게 주지 말아야 하는 경우도 있습니다. backfill 가능 여부와 match rule을 입장 정책에 명시합니다.
입장 실패를 숨기지 않기
client에는 expired, alreadyJoined, sessionFull, matchClosed, serverNotReady처럼 재시도 가능 여부가 드러나는 오류를 보냅니다. 모든 실패를 단순 disconnect로 처리하면 backend가 새 token을 줘야 하는지, client가 다시 queue에 들어가야 하는지 알 수 없습니다.
server log에는 grant ID의 원문이 아니라 안전하게 축약한 correlation ID, player ID, match ID, instance ID, seat 전이 결과를 남깁니다. 이 기록은 재접속에서 같은 player가 어떤 연결을 대체했는지 확인하는 기준이 됩니다.
입장 token 검증은 인증만이 아니라 정원·match 소속·중복 연결을 한 번에 닫는 경계입니다. 인증 뒤에 따로 seat를 세면 동시 입장에서 정원이 쉽게 어긋납니다.
참고 링크
2 sources