지난주에 책을 읽으며 깨달은 사실
TCP의 신뢰성, 흐름제어 및 혼잡제어는 아주 강력하다. 반드시 패킷을 손실 없이, 순서대로 수신하도록 해준다.
그러한 강력한 점 때문에 게임에선 아쉬울 수 있는 상황이 있다. 실시간의 네트워크 상황에 의해 다음 패킷이 먼저 도착했더라도 먼저 처리할 수 없다. 이전 패킷이 도착해야만 순서대로 다음 계층으로 패킷을 전달해주기 때문이다. 그래서 통신할 때 데이터의 신속성이 무엇보다도 중요하다면 위의 장점을 포기하고서라도 UDP로 구축할 수 있다.
예를 들어 위치 정보는 과거 정보보다 더 현재 시간에 가까운 나중에 들어온 정보가 이미 있다면 그대로 처리해줘도 무방하다.
또한 만약 송신측에서 발송한 패킷이 유실되었을 때, 몇 개쯤 유실되어도 괜찮아서 다시 보내고 싶지 않을 때에도 UDP가 적절하다.
현재 프로젝트는 TCP로만 구축돼 있다. 그런데 배드민턴을 쳐야 하는 게임 특성상 위치 정보의 신뢰성이 중요하므로, TCP의 지연이 불편하게 작용할 수 있을 것 같다.
→ UDP 위에서 동작하도록 구현을 변경해보자.
궁금한 사항. UDP 위에서 신뢰성 매커니즘을 구현한다면, 패킷이 유실되거나 순서가 잘못 도착하는 것에 대한 처리는 가능할 것 같다. 그런데 네트워크의 흐름을 제어해야 하는 흐름 제어, 혼잡 제어에 대해서는 어떻게 대응할 것인가? UDP이니 막 보내기? 배달 통지 매커니즘이 있으면 매번 RTT를 측정하면서 PP 값을 결정할 수 있겠다. 이렇게 동적으로 PP를 결정하면 곧 흐름 제어가 될 수 있을 것 같다.
지금 무엇을 진행하는가?
어쨌든 TCP든 UDP든 NetworkManager 하위에서 벌어지는 일이니, 패킷을 전달 받았다고 가정하고 상위의 기능을 개발해도 문제 없겠다. 지난주 목표였던 Replication Create/Update 동작을 우선 마저 완성하자!
Unity에서 PacketType, ReplicationAction을 받아 처리하도록 넘겨주는 코드를 만들었다.
테스트 해보고자 서버를 돌리니, 서버가 터진다!!!! 어디서 터지는거지!!
디버깅 결과 ReplicationUpdate로 전달되는 shared_ptr<gameObject>
객체가 nullptr
전달 된다. 분명 networkId
는 1로 시작하는데, get의 결과로 얻은 networkId
는 0이었다. 여기부터 문제가 있다.
gameObject에 networkId를 저장하지 않는 문제점을 찾았다. linkingContext가 자체적으로 gameObject별 networkId를 갖고 있으므로, gameObject는 networkId 필드를 갖지 않기로 했다.