P2P 게임 네트워크 구현시 슈퍼 피어 선정하기



게임 네트워크를 제작할 때, 대다수의 게임이 서버와 통신을 하지만 몇몇 게임의 경우 로그인이나 게임의 데이터 송수신은 서버와 하지만 네트워크 게임 플레이 자체는 클라이언트 간의 통신, 즉 peer-to-peer(이하 P2P) 방식으로 처리하는 경우가 있다. 일반적으로 소규모 멀티 플레이 게임이나 데이터 전송량이 많은 FPS 같은 게임의 멀티 플레이에서 P2P 방식을 사용할 것을 권장한다.


이러한 소규모 온라인 게임(Multi Online, MO)에서 사용하는 P2P 통신 방법의 하나로, P2P 그룹 내에 있는 멤버 중 하나가 게임 플레이를 위한 메시지의 송수신을 담당하는 Super peer(슈퍼 피어 혹은 호스트) 중심의 P2P 네트워킹이 있다.


간단한 예를 들자면 FPS 게임에서 P2P 네트워킹을 사용하는데 게임의 종료 조건 중의 하나가 타임 오버일 때, 그 P2P 그룹에 속하는 모든 클라이언트가 각자의 시간을 가지고 계산한다면 상황에 따라서 게임이 종료되는 시간이 각 클라이언트마다 제각각인 상황이 발생할 수도 있다. 이러한 상황을 방지하기 위해 P2P 그룹의 멤버들 중에서 하나의 슈퍼 피어를 선정하고 그 슈퍼 피어인 멤버의 클라이언트가 게임의 시간을 관리하게 하는 것이다. 그렇게 함으로써 모든 클라이언트의 종료 시점은 동일해질 수 있다.


이런 슈퍼 피어를 선정할 때에도 고려해야할 조건들이 있는데, 그것은 바로 P2P 그룹의 멤버 중에서 가장 네트워크 접속 상태가 좋고 전송 속도가 빠른 멤버를 슈퍼 피어로 삼아야 한다는 것이다. 만약에 통신 품질이 좋지 않은 클라이언트를 슈퍼 피어로 선정하게 되면 게이밍 품질이 하락할 수 있다. 예를 들자면 FPS 게임에서 캐릭터의 이동을 슈퍼 피어의 기준으로 동기화하였는데, 슈퍼 피어의 상태가 좋지 않다면 캐릭터의 이동이 뚝뚝 끊어져 보일 것이다.


슈퍼 피어를 선택하는 방법은 다음과 같다 :


1. 인터넷 공유기 뒤에 있지 않고 직접 회선에 물려있는 경우 슈퍼 피어로서의 자격이 상승한다.

2. 클라이언트의 송신 속도가 높을 수록 슈퍼 피어로서의 자격이 상승한다.

3. 클라이언트의 성능이 좋아서 초당 실행 프레임레이트(framerate)가 높은 경우 슈퍼 피어로서의 자격이 상승한다. 가령, 물리 시뮬레이션을 수퍼피어가 전담하는 게임 개발의 경우 이것이 중요해진다. 자세한 것은 Proud.CNetClient.SetApplicationHint 도움말을 참고하라.


직접 개발하게 된 네트워크 API의 경우엔 위의 조건을 계산해내는 기능을 직접 구현해야 하겠지만, 프라우드넷에서는 그와 관련된 함수가 이미 존재한다. Proud.CNetServer.GetMostSuitableSuperPeerInGroup() 함수와 Proud.CNetServer.GetSuitalbeSuperPeerRankListInGroup() 함수가 바로 그것이다.


이 함수들의 설명은 다음과 같다 :


virtual HostID Proud::CNetServer::GetMostSuitableSuperPeerInGroup(

HostID groupID,

const CSuperPeerSelectionPolicy & policy = CSuperPeerSelectionPolicy::GetOrdinary(),

const HostID * excludees = NULL,

intptr_t excludeesLength = 0

)


이 메서드는 groupID가 가리키는 P2P 그룹에 있는 멤버들 중 가장 최적의 슈퍼 피어를 찾아서 알려주는데, P2P 그룹을 생성하거나 변경한 직후에는 슈퍼 피어 후보자를 제대로 얻지 못할 수도 있다. 처음 이 메서드를 호출한 이후 2-5초 후에 다시 호출해주면 더 정확한 슈퍼 피어를 찾을 수 있다.


매개변수

groupID :: 슈퍼 피어를 찾고자하는 P2P 그룹의 ID

policy :: 슈퍼 피어를 선정하는 정책. 자세한 설명은 CSuperPeerSelectionPolicy 를 참고.

excludees :: groupID가 가리키는 P2P 그룹의 멤버 중 excludees에 들어있는 멤버들은 제외하고 선별한다. 예를 들어 이미 사용하던 슈퍼 피어가 자격을 박탈당한 경우 다시 재선발되는 것을 막고자할 때 유용하다.


반환값

슈퍼 피어로서 가장 적격인 클라이언트의 HostID. P2P 그룹이 찾지 못했거나 excludees에 의해 모든 멤버가 필터링되면 HostID_None을 리턴한다.


virtual int Proud::CNetServer::GetSuitableSuperPeerRankListInGroup(

HostID groupID,

SuperPeerRating * ratings,

int ratingsBufferCount,
const CSuperPeerSelectionPolicy & policy = CSuperPeerSelectionPolicy::GetOrdinary(),

CFastArray<HostID> & excludees = CFastArray<HostID>

)


이 메서드 역시 Proud.CNetServer.GetMostSuitableSuperPeerInGroup() 와 마찬가지로 최적의 슈퍼 피어 후보자를 찾아주지만 이전 메서드와 다른 점은 최고 순위의 후보자 뿐만 아니라 차순위의 후보자 역시 찾아서 준다.


매개변수

groupID :: 슈퍼 피어를 찾고자하는 P2P 그룹의 ID

ratings :: 여기에 적합한 슈퍼 피어 후보자 목록이 채워져서 반환된다. 가장 적합한 후보자 순으로 정렬되어 채워진다.

ratingsBufferCount :: rating의 배열 항목 갯수이다. 이 함수가 리턴하는 배열의 크기는 이 크기 이상은 채우지 않는다.

policy :: 이전 메서드의 설명과 같다.

excludees :: 이전 메서드의 설명과 같다.


반환값

ratings에 채워진 항목의 갯수를 반환한다. P2P 그룹을 찾지 못했거나 excludees에 의해 모든 멤버가 필터링되면 0을 반환한다.



위의 함수들을 적절하게 이용하면 적합한 클라이언트를 슈퍼 피어로 선정할 수 있을 것이고, 게이밍의 질을 향상시킬 수 있을 것이다.


참고

http://guide.nettention.com/cpp_ko#super_peer

http://help.nettention.com/cpp/1.7.31494-master/class_proud_1_1_c_net_client.ndn/

반응형

+ Recent posts