반응형

네트워크 매니저 콜백(Network Manager Callback)


지난 섹션에서는 유넷에서 제공하는 Network Manager HUD의 기능을 직접 구현해보았다. 그리고 그것을 테스트하는 중간에 네트워크 매니저가 보내는 콜백을 통해서 서버와 호스트, 클라이언트의 실행 여부와 접속 여부를 확인할 수 있었다. 네트워크 매니저 콜백은 그 외에도 유니티 네트워크가 지정한 특정한 상황을 알리고 그것에 대한 기본적인 처리를 하는 역할을 한다.


그 상황에 대한 기본적인 처리 외의 필요한 것은 콜백을 상속받아서 처리에 대한 코드를 직접 작성해주면 된다.


우선은 네트워크 매니저 콜백의 종류에 대해서 알아보자. 네트워크 매니저 콜백은 서버에서 호출되는 콜백, 클라이언트에서 호출되는 콜백, 호스트에서 호출되는 콜백, 이렇게 세 가지로 나눌 수 있다. 단, 호스트의 경우에는 서버와 클라이언트의 역할을 겸하기 때문에 호스트에서 호출되는 콜백 이외에도 서버 콜백과 클라이언트 콜백이 함께 호출된다.





서버 콜백(Server Callback)


public override void OnStartServer()


서버가 시작 되었을 때 호출되는 콜백이다.


public override void OnStopServer()


서버가 정지 되었을 때 호출되는 콜백이다.


public override void OnServerConnect(NetworkConnection conn)


서버에 새로운 클라이언트가 연결 되었을 때 호출되는 콜백이다. 매개변수로 새롭게 접속한 클라이언트의 Network Connection이 제공된다.


public override void OnServerReady(NetworkConnection conn)


서버에 접속한 클라이언트가 준비 되었을 때 호출되는 콜백이다. 매개변수로 준비된 클라이언트의 Network Connection이 제공된다.


public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)

public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)


서버에 접속한 클라이언트가 ClientScene.AddPlayer() 함수를 호출해서 새 플레이어를 추가할 때, 호출되는 콜백이다. 이 콜백의 기본 처리는 네트워크 매니저에 등록된 playerPrefab을 이용해서 새 플레이어 객체를 소환한다. 매개변수를 통해서 플레이어를 생성한 클라이언트의 Network Connection과 새로 생성되는 플레이어 컨트롤러의 id, 클라이언트에서 보내는 추가적인 메시지가 전달된다.


public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)


클라이언트가 플레이어를 제거할 때, 서버에서 호출되는 콜백이다. 이 콜백의 기본 처리는 해당 플레이어 객체를 파괴한다. 매개변수를 통해서 플레이어를 제거한 클라이언트의 Network Connection과 제거되는 플레이어 객체가 전달된다.


public override void OnServerDisconnect(NetworkConnection conn)


서버에 접속해있던 클라이언트가 연결이 끊어졌을 때 호출되는 콜백이다. 매개변수를 통해서 연결이 끊어진 클라이언트의 Network Connection이 전달된다.


public override void OnServerError(NetworkConnection conn, int errorCode)


클라이언트 연결에 대한 네트워크 오류가 발생하면 서버에서 호출되는 콜백이다. 매개변수를 통해서 문제가 발생한 클라이언트의 Network Connection과 에러 코드가 전달된다.


public override void OnServerSceneChanged(string sceneName)


씬 로드가 완료되거나, 서버에서 ServerChangeScene()로 씬 로드가 시작될 때 호출되는 콜백이다. 매개변수를 통해서 새롭게 로드되는 씬의 이름이 전달된다.





클라이언트 콜백(Client Callback)


public override void OnStartClient(NetworkClient client)


클라이언트가 시작할 때 호출되는 콜백이다. 매개변수를 통해서 네트워크 시스템에서 사용되는 네트워크 클라이언트 객체가 전달된다. 이 네트워크 클라이언트에는 네트워크 서버에 연결하는데 사용되는 Network Connection이 포함되어 있다. 이 콜백의 기본 처리는 매개변수로 전달받은 네트워크 클라이언트 객체를 NetworkManager.client 멤버 변수에 할당하는 역할을 주로한다. 이 client 멤버 변수를 이용해서 서버에 메시지를 보내거나 서버의 상태를 확인할 수 있다.


public override void OnStopClient()


클라이언트가 정지 되었을 때 호출되는 콜백이다.


public override void OnClientConnect(NetworkConnection conn)


클라이언트가 서버에 연결되었을 때 호출되는 콜백이다. 매개변수를 통해서 서버의 Network Connection이 전달된다. 그리고 이 콜백은 자기 자신의 클라이언트가 서버에 연결 되었을 때만 호출된다. 이 콜백의 기본 처리는 클라이언트를 준비(Ready) 시키고 플레이어를 추가(Adds a player)하는 작업을 한다. 만약 클라이언트가 서버에 연결되자마자 준비하고 플레이어를 추가하는 것을 원하지 않고 별도의 작업을 한 이후에 준비 하고 플레이어를 추가하길 원한다면 base.OnClientConnect()의 호출을 주석처리하거나 코드를 제거하는게 좋다.


public override void OnClientDisconnect(NetworkConnection conn)


서버와의 연결이 해제 되었을 때 호출되는 콜백이다. 매개변수를 통해서 서버의 Network Connection이 전달된다.


public override void OnClientError(NetworkConnection conn, int errorCode)


네트워크 오류가 발생했을 때 호출되는 콜백이다. 매개변수를 통해서 서버의 Networ kConnection과 에러 코드가 전달된다.


public override void OnClientNotReady(NetworkConnection conn)


서버에서 더 이상 클라이언트가 준비 상태가 아님을 알려왔을 때 호출되는 콜백이다. 매개변수를 통해서 서버의 Network Connection이 전달된다.


이 콜백은 주로 씬 전환에 사용된다.





호스트 콜백(Host Callback)


public override void OnStartHost()


호스트가 시작 되었을 때 호출되는 콜백이다.


public override void OnStopHost()


호스트가 정지 되었을 때 호출되는 콜백이다.


호스트 콜백의 경우에는 종류가 시작과 정지 두 가지 뿐이다. 호스트는 서버와 클라이언트를 겸하기 때문에 호스트 콜백과 더불어 서버 콜백과 클라이언트 콜백을 함께 호출한다.


네트워크 매니저에는 위에서 설명한 콜백 이외에도 몇 가지 콜백들이 더 있으나, 나머지 콜백들은 유니티 매치메이커에서 사용되는 콜백이기 때문에 이번 세션에서는 소개하지 않고 추후에 매치메이커 세션에서 설명하도록 하겠다.





콜백의 호출 순서


서버에 새로운 클라이언트가 연결되거나 연결이 끊어졌을 때 등, 여러가지 상황을 처리하는데 콜백은 유용하게 사용된다. 이러한 상황을 처리할 때에 순서가 중요한 경우가 많기 때문에 콜백의 호출 순서를 확인 해두는 것이 좋다.


서버 콜백의 호출 순서


1단계 : 서버 시작


- StartServer() 함수 호출

- OnStartServer

- OnServerSceneChanged


2단계 : 클라이언트 접속


- OnServerConnect

- OnServerReady

- OnServerAddPlayer


3단계 : 클라이언트 연결 해제


- OnServerDisconnect


4단계 : 서버 중지


- OnStopServer





클라이언트 콜백의 호출 순서


1단계 : 클라이언트 시작


- StartClient() 함수 호출

- OnStartClient

- OnClientConnect

- OnClientSceneChanged


2단계 : 서버 중지 or 클라이언트 중지


- OnStopClient

- OnClientDisconnect





호스트 콜백의 호출 순서


1단계 : 호스트 시작


- StartHost() 함수 호출

- OnStartHost

- OnStartServer

- ServerConnect

- OnStartClient

- OnClientConnect

- OnServerSceneChanged

- OnServerReady

- OnServerAddPlayer

- OnClientSceneChanged


2단계 : 클라이언트 접속


- OnServerConnect

- OnServerReady

- OnServerAddPlayer


3단계 : 클라이언트 연결 해제


- OnServerDisconnect


4단계 : 호스트 중지


- OnStopHost

- OnStopServer

- OnStopClient


앞에서 이야기 한 것과 같이 호스트는 서버와 클라이언트의 역할을 겸하기 때문에 서버의 콜백과 클라이언트의 콜백이 함께 호출된다.

반응형
반응형

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