클라이언트-서버 통신
클라이언트가 서버에 연결하면 우선 TCP로 통신이 이루어집니다.
그 동안 백그라운드로 서버와의 UDP 홀펀칭을 성공하게 되면 UDP 통신도 가능하지만 그 전까진 reliable, Unreliable 메시징 모두 TCP로 대체됩니다. 하지만 UDP 홀펀칭 성공 이후부터 Reliable 메시징 은 UDP로 대체됩니다.
클라이언트는 각각의 TCP port, UDP port를, 서버는 1개의 TCP listening port, 1개 이상의 UDP port를 가지고 통신하는데, 클라이언트는 서버와 TCP 연결을 유지하면서 서버 측의 UDP port 중 한 개를 선정합니다. 즉, 서버 측은 여러 개의 UDP port를 접속한 모든 클라이언트들에게 고루 공유합니다.
예를 들어, 4만 개의 클라이언트가 2만 개의 UDP port를 연 서버와 통신한다면, 서버 측의 각 UDP port 당 2개의 클라이언트가 통신하게 됩니다.
Proxy & Stub 통신 객체에 등록 및 사용
서버와 클라이언트에 통신을 추가해 보겠습니다. 편리성을 위해 서버와 클라이언트 모두 사용하는 Common(공용) 프로젝트를 생성 후 PIDL파일을 준비합니다. 준비된 PIDL파일에 서버에서 클라이언트로 통신을 보내기 위한 프로토콜을 정의 합니다.
위의 PIDL파일을 컴파일하면 Proxy와 Stub객체가 생성됩니다.
Proxy 객체 사용 방법
먼저 사용하실 곳에 Header를 포함시킵니다.
Proxy를 생성하고 서버 객체에 등록시켜 보겠습니다.
AttachProxy라는 함수를 이용하여 생성된 Proxy객체의 포인터를 넘겨주는 방식으로 등록시켰습니다. AttachProxy는 내부에서 배열로 관리하여 여러 종류의 PIDL을 등록 시킬 수 있습니다. 등록 되었다면 Proxy 객체의 함수를 사용하여 통신을 할 수 있습니다.
Proxy와 마찬가지로 stub에도 사용할 곳에 Header를 포함시킵니다.
Stub객체의 경우 받을 프로토콜의 정의 함수기 때문에 상속 받은 객체를 생성하여 사용해야 합니다. AttachStub 함수를 사용하여 등록하면, 해당 호출이 왔을 시 콜백 됩니다. 생성된 Stub 객체 안에는 정의(Define)가 만들어지는데, 이를 사용하면 프로토콜을 변경해도 cpp파일과 h파일을 따로 수정할 필요가 없습니다.
Stub Class에 명시된 Define문 중 DEFRMI_NameSpace_함수이름은 상속 받은 객체의 Header 파일에, DECRMI_NameSpace_함수이름 (Class_Name) 은 cpp에 선언합니다.
'True'를 Return 하는 것은 처리가 되었다라는 의미입니다. 'False'를 Return하게 되면 사용자가 프로토콜에 대한 처리를 하지 않은 것으로 판단하여 OnNoRmiProcessed Event가 콜백 됩니다. DEFRMI_S2C_Chat로 콜백된 함수 인자 중 remote는 RMI를 호출한 상대편 HostID 값 입니다. 이 ID값을 사용하여 Proxy를 호출하면 원하는 상대에게 통신을 보낼 수 있습니다.
이제 생성한 Stub객체를 Client객체에 등록시켜 보겠습니다.
AttachStub 함수도 내부에서 배열로 관리되고 있으며, 포인터를 넘겨주는 방식으로 등록됩니다.
개발 이후 반드시 트래픽을 확인하셔야 합니다. 트래픽은 각 클라이언트, (Super peer기능을 사용한다면 Super Peer에서도) 서버 등에서 각각 통신 양을 체크하고 불필요한 트래픽을 제거해주는 작업이 필요합니다. 트래픽 체크를 위해 아래의 방법들을 참고해 주세요.
NetLimiter와 같은 툴을 사용합니다.
한 컴퓨터에 사용할 프로세스 개수만큼 정확히 실행 한 뒤, 작업 관리자의 간격당 주고받은 바이트 수를 확인하는 방법이 있습니다.
ProudNet의 내부 함수인 CNetServer::GetStats(CNetServerStats &outVal); 를 사용하여 초당 주고받은 트래픽, 보내거나 받은 수, 등을 실시간으로 얻을 수 있습니다. 한 클라이언트의 총 트래픽이 대략 20~30KB 이상 발생 된다면, 해외 서비스에서 문제가 발생할 수 있습니다.
NetLimiter 와 같은 Tool은 사용 후 삭제하길 권장합니다. Kernel Hooking 기능으로 인하여 통신 다바이스를 잡고 있는 코어에 본래 속도 20배 이상의 부담을 줍니다.
이벤트
- 클라이언트와 서버 공통
파라미터 errorInfo의 errorInfo -> ToString(); 을 사용하면 쉽게 문제에 대한 정보를 얻으실 수 있습니다.
- 서버
성능 테스트 등에 이용 가능합니다.
Last updated