본문 바로가기
Old/Network

게임 네트워크 엔진

by onenewkong 2023. 7. 31.

프라우드넷의 네트워크 모듈

1. NetServer 클래스: 게임 서버의 메인 모듈

  • 클라이언트의 연결을 받으며, 클라이언트와 메시지를 주고받는 역할을
  • 클라이언트의 네트워크 상황 등을 열람할 있음

2. NetClient 클래스: 게임 클라이언트에서 네트워크 모듈

  • 서버로 연결을 맺은 메시지 주고받기를 수행할 있음
  • 다른 클라이언트와 P2P 통신도 가능

 

NetServer 인스턴스를 생성하고 NetServer 클라이언트 접속을 받으려면 다음 작업이 필요

  1. CNetServer.Create() CNetServer 인스턴스를 생성
  2. CNetServer.Start() 서버가 클라이언트 접속을 받을 있게

Start() 들어가는 필수 매개변수는 프로토콜 버전과 리스닝 포트 번호로, 프로토콜 버전은 마음대로 값을 정하면

 

클라이언트는 다음과 같이 서버에 접속

  1. CNetClient.Create() 클라이언트 인스턴스를 생성함
  2. CNetClient.Connect() 서버로 접속함

 

NetClient FrameMove() 함수를 호출하면, 마지막에 같은 FrameMove() 호출했던 이후부터 지금까지 누적된 이벤트나 수신된 메시지에 대한 이벤트 콜백이 일어남

 

요약)

  1. NetServer 생성하여 Start() 함수를 호출
  2. NetClient 생성하여 Connect() 함수를 호출
  3. NetServer.OnClientJoin(), OnClientLeave()에서 클라이언트의 들어옴/나감을 처리
  4. NetClient.OnJoinServerComplete(), OnLeaveServer()에서 서버와 접속의 성공/실패/중도 연결 해제를 처리함
  5. NetClient.FrameMove() 계속해서 호출

 

프라우드넷에서 메시지를 주고 받는 방법

  1. 전통적인 방법으로 바이너리 데이터 주고받기
  2. 다른 컴퓨터에 있는 함수를 원격으로 호출하기

 

전통적인 방법으로 바이너리 데이터 주고받기

: NetClient NetServer SendUserMessage() 함수를 호출하면 상대방에게 여러번 메시지가 전송됨, 이때 제공해야 하는 매개변수는

  1. 누구한테? (HostID 또는 HostID array)
  2. 어떻게? (reliable, unreliable, ...)
  3. 무엇을? (byte array)

 

와이파이 셀룰러 연결 핸드오버 기능

  • 연결 유지 기능

 

RMI

: 원격 메서드 호출(Remote Method Invocation) 약어로, "상대방 컴퓨터 안에 있는 프로그램의 특정 함수를 멀리서 실행하라."라는 의미

  • RMI 정체는 수동으로 만들었어야 하는 코드를 자동으로 만들어 주는 것으로 송신하는 쪽에서는 실제 함수 대신 송신을 담당하는 코드가 실행됨
  • 송신을 담당하는 코드는 "함수 호출을 대신해 준다"라는 의미로 proxy라고

 

원격 메서드 호출의 장점

  1. 송신을 처리하는 코드와 수신을 처리하는 코드를 손으로 일일이 구현할 필요가 없음
  2. 송수신 메시지의 형태가 변경되었을 송신이나 수신을 처리하는 코드를 수정하다가 실수할 위험이 없음

 

서버와 클라이언트에 송신 코드(Proxy) 수신 코드(Stub) 붙이는 방법

  1. Proxy, Stub 인스턴스를 생성함
  2. 인스턴스들을 AttachProxy, AttachStub 함수를 써서 부착함

 

클라이언트에서 서버로 RMI 호출

  • RMI 호출할 때는 다음 매개변수를 넣음

 

서버에서 RMI 호출받기

  • 호출받는 함수에서 전달하는 매개변수

 

서버에서 클라이언트로 원격으로 함수를 호출하려면

  • 앞서 선언했던 <서버 => 클라이언트> RMI 서버와 클라이언트에 붙여야
  • RMI Proxy 서버에 붙이고 RMI Stub 클라이언트에 붙임

 

지금까지 절차 요약)

  1. PIDL 파일에 RMI 함수들을 정의
  2. 이를 컴파일,, 가능하면 빌드 설정에 넣음
  3. 생성된 Proxy, Stub NetClient NetServer 부착함
  4. 생성된 Proxy 함수를 호출하면 메시지가 전송됨
  5. 생성된 Stub 함수를 부착하면 함수들이 호출됨

 

P2P

  1. 서버에서 클라이언트 1 클라이언트 2 P2P 연결을 하라고 지시
  2. 클라이언트 1, 클라이언트 2 자기가 P2P 연결이 되었음을 즉시 있음
  3. 직후에 바로 클라이언트 1 클라이언트 2 서로 메시지를 주고 받음

 

P2P 그룹 특징

  • P2P 그룹에는 클라이언트를 0 이상 넣을 있음
  • 클라이언트 하나가 여러 P2P 그룹에 들어가도 (겹쳐도 )
  • 서버도 P2P 그룹에 들어가는 것이 허락됨

 

P2P 메시지 보내기

c.SendUserMessage(G, RmiContext.ReliableSend, data);

 

P2P 그룹에 멤버 추가하기 / 삭제하기 / 파괴하기

  • 이미 만들어진 P2P 그룹에 JoinP2PGroup 호출하여 많은 클라이언트를 기존 P2P 그룹에 넣을 있음
  • 그러면 새로 추가된 호스트와 기존에 있던 호스트는 신규로 들어오는 것에 대한 OnP2PMemberJoin() 이벤트를 받음
  • P2P 그룹에서 호스트를 제거하려면 NetServer.LeaveP2PGroup() 호출하고, P2P 그룹 자체를 파괴하려면 DestroyP2PGroup() 호출

 

홀펀칭 상태 변화 감지하기

  • P2P 홀펀칭: 인터넷 공유기 뒤에 있는 클라이언트끼리도 서로 P2P 통신을 있는 기법
  • 홀펀칭이 성공하면 클라이언트에서는 이를 통지받음 (OnChangeP2PRelayState 이벤트)
  • 반대로 기존에 있던 홀펀칭이 중도에 사라지는 경우에도 통지를 받음

 

P2P 통신에서도 RMI 사용할 있음

  • P2P RMI 함수를 선언했다면 Proxy Stub 클래스 인스턴스를 클라이언트에 모두 붙여야

 

요약)

  • CreateP2PGroup()으로 클라이언트들이 직접 통신할 P2P 그룹을 만듦
  • OnP2PMemberJoin()으로 클라이언트들은 자기가 P2P 통신할 있음을
  • RMI SendUserMessage() P2P 메시지를 보냄
  • P2P RMI 쓰려면 Proxy, Stub 모두 NetClient 부착해야

 

스레드 모델

  • 프라우드넷은 서버 프로세스 하나가 스레드를 여럿 가지는 형태의 서버와 여러 서버 프로세스가 각각 스레드 하나를 가지는 형태의 서버에 대한 스레드 모델을 모두 지원함
  • 기본값으로 NetServer 워커스레드는 CPU 개수만큼 구동됨, CPU 개수만큼 스레드를 가진 스레드 풀이 기본으로 제공됨
  • 그러나 다음 모든 상황일 때는 이를 권장하지 않음

'Old > Network' 카테고리의 다른 글

Protobuf  (0) 2024.01.22
게임 네트워킹  (0) 2023.07.27
게임 서버와 클라이언트  (0) 2023.07.24
Socket Programming  (0) 2023.07.24
컴퓨터 네트워크  (0) 2023.07.24