좌표만 보내지 말고 sequence나 server tick을 함께 보냅니다.
소켓 응용 5/5 · LATENCY
늦게 온 과거 좌표는
버려야 합니다.
ordered: false인 WebRTC DataChannel에서는 위치 도착 순서가 바뀔 수 있습니다. 순서 번호, 오래된 좌표 폐기와 보간을 비교합니다.
사이는 부드럽게 잇기
나쁜 결과와 안전한 결과를 비교하세요
unordered WebRTC 위치 패킷을 재생합니다
보는 순서① 비순서 채널 확인→② #3 먼저 수신→③ #2 지연 확인
- 1이동
- 2역전
- 3과거 도착
- 4떨림
도착 순서대로 적용 시나리오입니다. 실험 시작을 눌러 네 장면을 따라가세요.
화면에서 코드로 옮길 때
이 편의 원리 세 가지
마지막 적용 번호보다 작은 패킷으로 현재 화면을 되돌리지 않습니다.
논리는 최신 좌표를 유지하고 화면은 짧게 보간해 부드럽게 이동합니다.
구현 체크리스트
최소 네 조각으로 시작하세요.
데모의 시각 요소를 실제 프로토콜 필드와 런타임 동작으로 옮기면 됩니다.
- 1서버 tick모든 위치 업데이트의 비교 가능한 순서
- 2stale 판정seq가 lastApplied 이하이면 즉시 폐기
- 3작은 보간 버퍼짧은 지연을 감수하고 두 좌표 사이를 연결
- 4중요 이벤트 분리결제·아이템 획득은 신뢰 채널과 ACK 사용
이 데모에 대하여
순서가 뒤바뀌어 도착하는 좌표를 처리합니다
순서를 보장하지 않는 통로에서는 나중에 보낸 좌표가 먼저 도착하는 일이 생깁니다. 이 화면은 3번 좌표가 2번보다 먼저 도착하는 상황을 만들어 두고, 뒤늦게 온 2번을 그대로 반영했을 때와 버렸을 때가 어떻게 다른지 비교합니다. 늦게 온 것을 반영하면 화면 속 대상이 뒤로 순간이동하는데, 그 되돌아감이 사용자에게는 통신 지연보다 훨씬 크게 거슬립니다.
- 순서 보장이 없는 통로라는 표시를 먼저 확인합니다.
- 폐기하지 않는 설계를 고르고 좌표가 도착하는 순서를 봅니다.
- 3번이 먼저 도착해 위치가 앞으로 가는 것을 확인합니다.
- 뒤이어 2번이 도착했을 때 위치가 어떻게 되는지 봅니다.
- 폐기하는 설계로 바꿔 같은 순서를 재생합니다.
- 2번이 도착했을 때 무시되는지, 마지막 적용 번호가 유지되는지 봅니다.
- 보간이 켜졌을 때 이동이 어떻게 달라지는지 비교합니다.
- 두 설계에서 최종 위치가 같은지 확인합니다.
- 폐기된 좌표에 어떤 표시가 남는지 봅니다.
- 마지막 적용 번호가 언제 갱신되고 언제 유지되는지 확인합니다.
- 보간을 껐을 때 이동이 어떻게 보이는지 비교합니다.
늦게 온 좌표를 판단하는 기준
01
좌표에는 시간이 필요합니다.
위치 값만 보내면 받는 쪽은 그것이 언제의 위치인지 알 수 없고, 도착 순서를 그대로 시간 순서로 믿는 수밖에 없습니다. 그래서 좌표마다 순서 번호를 함께 보냅니다. 화면에서 각 좌표에 번호가 붙어 있는 것이 이 판단의 근거이고, 번호가 없으면 폐기라는 대응 자체가 불가능합니다.
02
마지막으로 적용한 번호를 기억합니다.
받는 쪽은 지금까지 반영한 가장 큰 번호를 들고 있습니다. 새로 온 좌표의 번호가 그보다 작거나 같으면 이미 지난 정보이므로 버립니다. 판단이 이 비교 하나로 끝나기 때문에 구현이 간단하고, 늦게 온 것이 얼마나 늦었는지 따로 계산할 필요가 없습니다.
03
되돌아가는 것이 늦는 것보다 나쁩니다.
옛 좌표를 반영하면 화면 속 대상이 뒤로 갔다가 다시 앞으로 옵니다. 위치가 조금 늦게 갱신되는 것은 잘 느껴지지 않지만 뒤로 튀는 움직임은 바로 눈에 띕니다. 정보를 버리는 것이 손해처럼 보여도 이 경우에는 버리는 쪽이 사용자 경험에서 낫다는 판단이 이 설계의 근거입니다.
04
표시와 논리를 나눕니다.
내부적으로 들고 있는 위치는 항상 최신 좌표로 두되, 화면에 그리는 위치는 그쪽으로 짧은 시간 동안 부드럽게 옮깁니다. 값이 띄엄띄엄 도착해도 움직임이 끊겨 보이지 않는 이유가 이것입니다. 대신 화면이 보여주는 위치는 실제 최신 위치보다 아주 조금 뒤처지게 됩니다.
05
부드러움과 정확함을 맞바꿉니다.
보간을 길게 잡으면 움직임이 매끄럽지만 반응이 늦고, 짧게 잡으면 반응은 빠르지만 끊겨 보입니다. 어느 쪽이 나은지는 만드는 것의 성격에 따라 다르며 정답이 하나로 정해지지 않습니다. 화면에서 이 부분을 켜고 끌 수 있게 한 것은 그 차이를 직접 느껴 보라는 뜻입니다.
06
순서를 보장하는 통로도 있습니다.
이 시나리오는 순서를 보장하지 않도록 설정한 통로를 전제로 합니다. 순서를 지키는 통로를 쓰면 뒤바뀜 자체가 생기지 않지만, 대신 중간의 하나가 늦어지면 뒤의 것들이 다 함께 기다립니다. 위치처럼 최신 값만 중요한 데이터에서는 기다리는 것보다 순서를 포기하는 편이 나을 수 있습니다.
07
중요한 이벤트는 다르게 다룹니다.
위치는 버려도 되지만 아이템 획득이나 결제 같은 것은 하나라도 잃으면 안 됩니다. 그래서 같은 연결이라도 성격이 다른 데이터는 다른 통로로 보내고 도착 확인을 받습니다. 이 화면이 다루는 폐기 규칙을 모든 데이터에 그대로 적용하면 안 된다는 점이 중요합니다.
08
버리는 판단에도 근거가 남습니다.
화면은 폐기된 좌표를 그냥 사라지게 하지 않고 버려졌다는 표시와 함께 남깁니다. 무엇을 버렸는지 보이지 않으면 위치가 이상할 때 원인을 짚을 수 없기 때문입니다. 실제 구현에서도 폐기한 개수를 세어 두면 회선 상태가 나빠지는 것을 미리 감지할 수 있고, 그 수치가 갑자기 늘어나는 것 자체가 유용한 신호가 됩니다.
09
최신 값만 의미가 있는 데이터입니다.
위치는 다음 값이 오면 앞의 값이 쓸모없어지는 종류의 데이터입니다. 그래서 하나를 놓쳐도 다음 것이 오면 회복되고, 재전송할 이유도 없습니다. 반대로 채팅 메시지는 하나하나가 모두 남아야 하므로 같은 규칙을 쓸 수 없습니다. 데이터의 이런 성격을 먼저 구분해야 어떤 통로와 어떤 규칙을 쓸지 정할 수 있습니다.
위치 데이터 한 종류만 다룹니다.
브라우저는 실제 통신을 하지 않으며 도착 순서가 뒤바뀌는 상황은 정해진 시나리오로 재생됩니다. 실제 환경에서는 순서 뒤바뀜과 유실이 무작위로 일어나고 그 빈도도 회선 상태에 따라 계속 변합니다. 이 화면에는 없는 것이 많은데, 보간 시간을 얼마로 잡을지, 좌표를 초당 몇 번 보낼지, 대역폭을 아끼려고 좌표를 압축하거나 변화가 없을 때 생략하는 방법, 상대의 다음 위치를 미리 추측해 그리는 방식, 그리고 그렇게 추측한 위치가 틀렸을 때 부드럽게 고치는 처리가 모두 별도 주제입니다. 또한 여러 대상이 동시에 움직이는 경우의 우선순위나, 서버가 각 참가자에게 서로 다른 시점의 화면을 보여줘야 하는 문제도 다루지 않습니다. 실시간 게임에서는 이런 문제들이 함께 얽히므로, 이 화면의 규칙 하나만 옮겨 적용하면 다른 곳에서 어긋나기 쉽습니다. 화면에서 다루는 좌표는 하나뿐이고 경로도 단순하지만, 실제로는 수십 개의 대상이 각각 다른 시점의 정보를 들고 움직입니다. 그 규모에서는 무엇을 버릴지보다 무엇을 먼저 보낼지가 더 중요한 문제가 됩니다.
실험을 마쳤다면