다양한 서버의 종류

P2P Server (Peer-to-Peer)
- 구조 : 모든 클라이언트가 서로 직접 연결하여 데이터를 주고 받음
- 장점
- 서버 비용 없음
- 연결 지연(Latency)이 적을 수 있음
- 단점
Listen Server
- 구조 : 한 명의 플레이어가 서버 역할도 수행
- 장점
- 단점
- 호스트가 나가면 게임 종료됨
- 성능 한계가 있음
Dedicated Server
- 구조 : 중앙 서버가 모든 클라이언트의 메시지를 수신하고 처리
- 장점
- 보안성 높음
- 안정적인 게임 환경
- 동기화 정확도 우수
- 단점
- 비용(서버 유지비) 발생
- 데이터가 한 지점에 몰려서 지연 발생 가능
Dedicated Server의 실행 흐름도
실행 흐름
- 서버 프로레스 실행
-> 실행할 때 Open {Level명}?Listen 명령어가 인자로 전달되면 해당 Level을 열어둠
-> 이때 Socket이 생성되며 다른 PC가 접속 가능하게 함 (Listen 명령어가 없으면 싱글플레이)
-> Level에 있는 WorldSettings 속성을 통해 GameMode와 GameState 액터를 생성
- 클라이언트가 서버의 IP 주소와 포트 번호로 접속 시도
-> 서버는 접속 시도하는 클라이언트에게 Level 정보를 넘김
-> 클라이언트도 해당 Level을 열고, Level을 여는데 성공했다고 서버에게 알림
- 클라이언트 전용
PlayerState, PlayerController, PlayerCharacter가 서버에 생성
-> 해당 액터들이 클라이언트에 복제됨
-> 서버에 있던 GameState도 복제됨
- 또 다른 클라이언트가 접속 시에 2~3번 과정 반복
-> 클라이언트 간에는 서로의 PlayerState, PlayerCharacter가 복제됨
-> 해당 복제를 통해 서로의 상태 및 캐릭터를 보이게 됨

서버 환경 설정
- Allow Late Joining 체크 -> 게임 시작 후에도 클라이언트 추가 가능
- Always on top 체크 -> 새 클라이언트 화면이 항상 위에 뜸
- Multiplay Options
- Launch Separate Server 체크 -> 서버를 따로 띄워줌, 안 하면 에디터 화면이 클라이언트이자 서버
- Run Under One Process 해제 -> 체크하면 같은 프로세스 내라서 공유하는 에셋이 생겨서 의도하지 않는 동작 발생
- Net Mode : Play as Client
- Number of Players : 2 -> 2개 이상의 클라이언트로 검사
언리얼의 멀티플레이 관련 개념 및 용어
NetMode
- 개념
- 해당 게임 프로세스가 네트워크 상에서 어떤 역할을 하고 있는지를 의미
- 싱글(NM_StandAlone), 서버(NM_Listen, NM_DedicatedServer), 클라이언트(NM_Client)
- 필요성
- 작성한 로직이 서버에서 돌고 있는지, 클라이언트에서 돌고 있는지를 알아야 함
- 멀티플레이에서는 같은 코드가 여러 PC에서 동작할 수 있고, 디버깅을 제대로 하기 위해서는 어떤 PC에서 동작하는지 알아야 함
- 관련 함수
ENetMode UNetDriver::GetNetMode() : NetDriver를 통해 넷모드를 받아올 수 있음
- NetMode에 따른 액터 위치
- 서버에만 존재하는 액터 : 게임 모드
- 서버와 개개인의 클라이언트에 존재하는 액터 : 플레이어 컨트롤러
- 서버와 모든 클라이언트에 존재하는 액터 : 배경 액터와 폰
- 클라이언트에만 존재하는 액터 : UI
NetConnection
- 개념
- 동작 과정
- 다른 PC와의 연결이 발생하면 그에 대응하는
UNetConnection 객체가 생성됨
- 서버에 클라이언트 접속 시
- 서버에는
ClientConnection 객체가 추가됨
- 클라이언트에는
ServerConnection 객체가 생성됨
- 특징
UNetDriver는 생성된 UNetConnection 객체를 소유하고 관리하고 있음
- 서버 PC에 생성된
UNetDriver는 접속한 클라이언트의 수만큼 ClientConnections을 관리
- 클라이언트 PC에 생성된
UNetDriver는 ServerConnection, 단 하나만을 관리
- 하나의
ClientConnection은 하나의 PlayerController를 소유
PlayerController의 Owner은 ClientConnection임
PlayerController가 빙의하는 Pawn의 Owner는 해당 PlayerController로 설정
- 위와 같이 Owner 속성을 연결해서 액터의 NetConnection을 반환받거나 할 수 있음
// UNetDriver.h
UCLASS()
class UNetDriver : public UObject, public FExec
{
UPROPERTY()
TObjectPtr<UNetConnection> ServerConnection;
UPROPERTY()
Tarray<TObjectPtr<UNetConnection>> ClientConnections;
}
NetDriver
- 개념
- 언리얼 네트워크 통신에서 로우레벨 동작들을 관리하는 클래스
- 특징
- 싱글플레이에서는
UNetDriver 객체가 생성되지 않음
- 멀티플레이에서만
UWorld::Listen() 함수를 통해 UNetDriver 객체가 생성됨
- 멀티플레이에 참여하는 각 PC마다
UNetDriver 객체가 생성됨
NetRole
- NetMode의 경우에서는 월드와 관련된 정보로, 해당 월드가 서버 PC의 월드인지, 클라이언트 PC의 월드인지 구분하기 위함이다.
- 그 액터가 서버 PC에서 스폰되어서 함수가 서버 PC에서 실행되고 있는지, 클라이언트 PC에서 스폰되어서 함수가 클라이언트 PC에서 실행되고 있는지도 파악해야 한다.
- 이를 파악하기 위해서
Actor 별로 NetRole 속성을 가지고 있어서, 서버나 클라이언트에서 이 액터를 어떤 권한으로 다루는지 알 수 있다.
Authority & Proxy
- Authority : 서버에 스폰된 액터의 NetRole 속성은 서버에서는 언제나 Authority로, 서버에서 수행을 해도 된다는 권한을 가진 것을 의미한다.
- Proxy : Authority인 액터가 클라이언트에 복제되었을 때, 클라이언트에서 복제된 액터의 NetRole 속성 값은 Proxy(허상)로, 실질적인 권한이 없음을 의미한다.

Local Role & Remote Role
- 로컬 롤 : 현재 동작하는 컴퓨터에서의 NetRole
- 리모트 롤 : 커넥션으로 연결된 컴퓨터에서의 NetRole
NetRole의 종류
- None
- 액터가 존재하지 않음
- 서버에서 스폰되고 레플리케이션되지 않는 액터. 또는 클라이언트에서 스폰된 액터
- Authority
- 게임에 중대한 영향을 끼칠 수 있는 로직 작성이 가능함
- Autonomous Proxy
- 서버로부터 수신 받아서 동기화되면서, 서버로 송신도 가능함
- ex) PlayerController
- Simulated Proxy
- 서버로부터 수신 받아서 동기화만 함
- ex) 다른 플레이어의
PlayerCharacter
중요 함수들
- 게임에 중대한 영향을 끼치는 데미지 같은 로직은 서버 컴퓨터에서만 실행되어야 한다.
AActor::HasAuthority() : 실행되는 곳이 서버 컴퓨터이고, 서버에서 생성된 액터인지 확인하는 함수
- 또한 입력 관련 로직이나 UI는 Autonomous Proxy에서 수행되어야 함
AController::IsLocalController() : Autonomous Proxy 롤을 가지는지 검사
-> 두 함수 모두, 네트워크에 연결되어 있지 않은 StandAlone인 상태에서도 true를 반환
액터별 특징
- 게임 모드는
HasAuthority() 함수를 호출할 필요가 없음 -> 어차피 서버에만 존재
- 폰은 Authority, Autonomous Proxy, Simulated Proxy가 혼재되어 있음
- UI 관련 로직은 클라이언트에서만 수행됨
출처: 팀스파르타 내일배움캠프