통신 메시지

메시지 송신하기

RMI Foo(int a,float b)가 선언되었을 때, RMI proxy가 ClientServer에 등록되었다면 메시지를 보내기 위해 proxy의 RMI를 호출할 수 있습니다. 메시징 프로토콜은 RmiContextReliableSend 또는 UnreliableSend를 사용할 수 있습니다. 클라이언트-서버 간 통신 및 P2P 통신 모두 사용 가능합니다.

아래는 메시지 송신 예시 입니다.

Proud::HostID oneHostID = ...; // 1개의 송신 대상
int manyHostIDListCount = ...;
 
// 서버에게 RMI를 보낸다.
myProxy.Foo(Proud::HostID_Server, Proud::RmiContext::ReliableSend, 3, 4);
 
// 1개의 송신 대상에게 RMI를 보낸다.
myProxy.Foo(oneHostID, Proud::RmiContext::UeliableSend, 3, 4);

송신 대상은 클라이언트의 Host ID나 서버의 Host ID (Proud::HostID_Server) 혹은 자기 자신을 넣을 수 있으며, P2P 그룹 ID를 넣으면 해당 P2P 그룹으로 멀티캐스트 됩니다. 또한 한 번에 여러 대상에게 멀티캐스트 할 수도 있습니다. 첫번째 파라미터로 HostID 대신 HostID 배열의 포인터와 HostID배열의 크기를 넣으면 됩니다.

// 송신 대상 배열
Proud::HostID sendTo[2];
sendTo[0] = ...;
sendTo[1] = ...;
 
// 여러 송신 대상에게 한번에 송신한다.
myProxy.Foo(sendTo, 2, Proud::RmiContext::ReliableSend, 3, 4);

이때 리스트에서 송신 대상이 중복될 경우, 중복해서 보내지지 않고 1회만 보내지며 리스트에는 1개 호스트 뿐만 아니라 P2P 그룹도 송신 대상으로 지정 가능합니다.

통신 메시지 크기 제한

ProudNet은 통신 메시지의 크기 제한을 유동적으로 설정할 수 있는데, 이는 해킹된 클라이언트에서 서버에게 비의도적으로 큰 메시지를 보낸다는 거짓 신호를 넘길 경우를 차단하기 위함입니다.

따라서 게임 클라이언트와 서버와 통신에서 약 64KB 이상의 큰 메시지를 주고 받는 것은 권장하지 않습니다.

주고 받을 수 있는 메시지 최대 크기의 초기 값은 약 64KB입니다. 하지만 서버 간 통신에서는 이러한 해킹 문제로부터 자유롭고, 서버 간 통신 회선은 초고속이며, 간혹 매우 큰 크기의 메시지를 주고 받을 필요가 있을 것입니다. 그렇기 때문에 서버 간 통신에서는 메시지 최대 크기를 조절할 필요도 있습니다.

이를 위해서 SetMessageMaxLength를 통해 조절할 수 있습니다. 지정한 사이즈보다 큰 메세지를 클라이언트가 보내려고 하면 클라이언트 단의 해당 송신 지점에서 Exception이 발생하게 됩니다.

C++C#

Proud.CNetServer.SetMessageMaxLength

Nettention.Proud.NetServer.SetMessageMaxLength

송신량 자동 조절 기능 (Throttling)

ProudNet은 송신량 자동 조절 기능(throttling) 기능이 있어 통신 속도가 느린 환경에서도 통신 장애를 적게 발생시키며, 통신 속도가 빠른 환경에서는 고품질의 네트워킹을 가능하게 합니다.

- 메시지 송신 우선순위 기능

ProudNet에서는 메시지 송신 우선순위 기능을 제공합니다.

아직 네트워크 회선으로 송출되지 못하고 송신 버퍼에 대기 중인 메시지들이 있을 경우, 우선순위 1의 메시지들이 완전히 송출된 후에야 우선순위 2의 메시지들이 송출됩니다. 마찬가지로, 우선순위 3의 메시지는 우선순위 2의 메시지들이 완전히 송출된 후에야 송출되기 시작합니다.

- 메시지 송신 우선순위 기능 활용

  • 음성 채팅

음성 채팅은 대량의 메시징을 필요로 합니다. 음성 채팅 통신량 때문에 게임 플레이에 방해될 수 있기 때문에 게임 플레이와 관련된 메시지를 높은 우선순위로, 음성 채팅은 보다 낮은 우선순위로 두어 문제를 개선하는 것이 좋습니다.

  • 실시간 컨텐츠 다운로드 게임

빠른 설치 후 게임 시작을 위해 필요한 미디어 데이터를 게임 플레이 진행 중에 다운로드 받는 게임을 개발할 수 있습니다. 게임 플레이에 관련된 메시지를 높은 우선순위로, 다운로드 데이터와 관련된 메시지를 낮은 우선순위로 두어 성능을 개선할 수 있습니다.

  • 대량 캐릭터 위치 동기화

플레이어 캐릭터와 직접 상호 작용하는 캐릭터와의 위치 동기화는 직접 상호 작용하지 않는 다른 캐릭터들에 비해 중요합니다. 따라서 플레이어 캐릭터와 전투를 하거나 카메라 가까이에 있는 캐릭터들의 위치는 높은 우선순위로, 그 밖의 메시지는 낮은 우선순위로 송신하면 보다 좋은 게이밍 환경을 제공할 수 있습니다.

RMI를 호출할 때 입력 파라미터 RmiContext에는 멤버 변수 priority가 있습니다. 이 변수에 메시지 송신 우선순위를 입력하면 됩니다. 메시지 송신 우선순위는 Proud.MessagePriority 의 값 중 하나입니다.

Proud.RmiContext.ReliableSend, Proud.RmiContext.UnreliableSend는 전역 변수입니다. 이들의 priority를 직접 수정하지 마시고, RmiContext 객체를 별도로 만들어 사용하시기 바랍니다.

- 최종 메시지만 송출

최종 메시지만 송출하는 기능은 송신 queue에 쌓여있지만 송출되지 않은 메시지와 같은 메시지를 중복해서 보내되 최종 보내려는 메시지만 보내고 나머지 쌓여있던 메시지들을 취소하는 기능입니다.

온라인 게임에서 캐릭터의 위치를 타 호스트에게 보내려는 경우에 이 기능이 유용하게 쓰입니다.

시간 'Time'이 1 이었을 때 캐릭터 위치(Pos)를 이미 통신선으로 송출한 상황입니다. 그리고 Time 이 2,3일 때 캐릭터 위치는 아직 송출되지 못하고 호스트의 메모리에 적재되어 있다가 최신 Time 4 의 위치를 보내려고 한다면, 아직 대기 중인 Time 2,3 시점의 캐릭터 위치를 보낼 필요는 없으므로 송출하지 않고 Time 4 시점의 위치를 보내는 것이 좋습니다.

사용 방법

RMI를 호출할 때 입력되는 파라미터 RmiContext의 멤버 변수 uniqueID를 0 이외의 값으로 지정하면 됩니다. 이때 RMI 호출에 의해 이 메시지가 송신 queue에 쌓이기 전, 같은 uniqueID를 가진 메시지가 있다면 이전 메시지는 제거되고 새 메시지로 대체됩니다.

UnreliableSend는 많은 곳에서 사용되고 있기 때문에 이를 직접 사용하는 것보다는 RmiContext객체를 별도로 만들어 uniqueID를 지정하는 것이 좋습니다.

사용 예시

// Proud.RmiContext.m_uniqueID 사용 예시
// 기본 unreliable send용 RmiContext 객체의 사본을 가져온다.
Proud::RmiContext rmi = Proud::RmiContext::UnreliableSend;
 
// m_uniqueID에 로컬 호스트가 조종하는 캐릭터의 식별자를 넣는다.
rmi.m_uniqueID = MyPlayerPetID;
 
// RMI를 통해 메시지를 송신한다.
C2CProxy.MyRmiFunction(PeerHostID, rmi, blahblah);

송신 과다 감지하기

- 각 호스트에서 송신 과다 감지

ProudNet은 내부적으로 송신 큐(send queue)를 가지고 있습니다. 송신 큐는 네트워크 회선이 감당 가능한 송신 속도보다 송신하려는 데이터의 양이 상회할 경우, 송신이 완료될 때까지 메모리에 대기하는 '송신할 데이터'를 말합니다.

송신량이 많을수록 송신 큐는 계속 증가하기 때문에 송신량을 측정하여 예방하는 것도 좋은 방법이 됩니다.

송신 큐 측정 메서드

C++C#설명

Proud.CNetServer.GetClientInfo

Nettention.Proud.NetServer.GetClientInfo

이 객체에 연결된 peer 1개의 정보를 얻는다.

Proud.CNetClient.GetPeerInfo

Nettention.Proud.NetClient.GetPeerInfo

이 객체에 연결된 peer 1개의 정보를 얻는다.

Proud.CNetPeerInfo.m_sendQueuedAmountInBytes

Nettention.Proud.NetPeerInfo.sendQueuedAmountInBytes

Peer로 전송될 대기 중인 메시지의 총량(Byte)

  • Peer에서 서버로 가져오는 경우: 클라이언트가 전송한 총량

  • Peer에서 클라이언트로 가져오는 경우: 클라이언트가 전송한 총량 (단, relay된 메시지는 제외)

송신량이 많을 때, 송신량 자동 조절 기능 (Throttling)을 통해 완화할 수 있습니다.

- 각 RMI 종류 별 송신 과다 감지

RMI 호출마다 발생하는 이벤트 콜백 Proud.IRmiProxy.NotifySendByProxy 은 파라미터 Proud.MessageSummary 를 가지고 있어 이를 통해 호출되는 각 RMI 통신량을 측정할 수 있습니다.

Last updated