https://dev.epicgames.com/documentation/ko-kr/unreal-engine/remote-procedure-calls-in-unreal-engine
Remote Procedure Call(원격 프로시저[함수] 호출)의 약자이며 원격 컴퓨터에서 실행중인 프로그램의 함수를 호출할 수 있도록 지정한 프로토콜을 의미한다. 인터넷 서비스에서 다양한 용도로 사용된다. 게임의 경우엔 네트워크 멀티 플레이 환경에서 반응 속도가 빠른 일시적인 명령을 내리거나, 정보를 주고받을 때 사용된다.
대부분의 RPC는 서버를 중심으로 클라이언트에 전파되는 형태로 되어있다. 오너쉽을 가지는 액터는 클라이언트에서 서버로 명령을 전송할 수 있다. 게임 제작에서는 이런 RPC의 특징을 활용하여 안정적이고 부드러운 네트워크 멀티 플레이 환경을 구축한다.
[RPC 사용]
함수를 RPC로 선언하려면 UFUNCTION 선언에 Server, Client, NetMulticast 키워드를 할당하면 된다.
UFUNCTION( Client )
void ClientRPCFunction();
서버에서 호출되지만 클라이언트에서 실행되는 RPC는 위와 같이 선언한다.
UFUNCTION( Server )
void ServerRPCFunction();
클라이언트에서 호출되지만 서버에서 실행되는 RPC는 위와 같이 선언한다.
UFUNCTION( NetMulticast )
void MulticastRPCFunction();
위의 키워드는 특수 유형으로, Multicast RPC는 서버에서 호출된 다음 서버는 물론 현재 연결된 모든 클라이언트에서도 실행되도록 한다. 멀티캐스트 RPC는 클라이언트에서도 호출 가능하지만, 이 경우에는 로컬에서만 실행된다.
추가로 5.0 이상의 엔진 버전에서는 Reliable(신뢰성), Unreliable(비신뢰성)을 설정해줘야 한다. 이전 버전에서는 Unreliable이 기본 설정이었기 때문에 예제는 키워드를 생략했지만, 이후 버전은 키워드를 입력해줘야 한다.
UFUNCTION( Client, Reliable )
void ClientRPCFunction();
[주의사항]
정상 작동 조건이 몇 가지 있다.
1. Actor에서 호출되어야 함
2. Actor는 반드시 replicated여야 함
3. 서버에서 호출되고 클라이언트에서 실행되는 RPC(Client 키워드)는 해당 Actor를 실제 소유하고 있는 클라이언트에서만 함수가 실행됨
4. 클라이언트에서 호출되고 서버에서 실행되는 RPC(Server 키워드)는 클라이언트 RPC가 호출되는 Actor를 소유해야함
5. Multicast RPC는 예외
5-1. 서버에서 호출되는 경우, 서버에서는 로컬에서 실행될 뿐만 아니라 현재 연결된 모든 클라이언트에서도 실행됨
5-2. 클라이언트에서 호출되는 경우 로컬에서만 실행되며, 서버에서는 실행되지 않음(통신 X)
5-3. 업데이트 기간동안 두 번이상 리플리케이트 되지 않음, 다른 RPC에 비해 부하가 많아 자주 실행되지 않고 자주 실행시키지 않는 것이 좋다는 뜻
[인증]
Server RPC의 경우에는 WithValidation이라는 키워드를 사용해주고 여기서 _Validate 함수를 활용해 지금 들어오는 RPC를 실행할지, 실행하지 말지를 결정해줄 수 있다. 값은 bool로 리턴하며 값이 true일 경우 실행해준다. 받아들인 요청이 악의적인 패킷 변조에 대해서는 false를 리턴하며 클라이언트와의 연결을 해제한다.
UFUNCTION( Server, WithValidation )
void SomeRPCFunction( int32 AddHealth );
bool SomeRPCFunction_Validate( int32 AddHealth )
{
if ( AddHealth > MAX_ADD_HEALTH )
{
return false; // This will disconnect the caller
}
return true; // This will allow the RPC to be called
}
void SomeRPCFunction_Implementation( int32 AddHealth )
{
Health += AddHealth;
}