프라우드넷의 네트워크 모듈
1. NetServer 클래스: 게임 서버의 메인 모듈
- 클라이언트의 연결을 받으며, 클라이언트와 메시지를 주고받는 역할을 함
- 각 클라이언트의 네트워크 상황 등을 열람할 수 있음
2. NetClient 클래스: 게임 클라이언트에서 네트워크 모듈
- 서버로 연결을 맺은 후 메시지 주고받기를 수행할 수 있음
- 다른 클라이언트와 P2P 통신도 가능
NetServer 인스턴스를 생성하고 NetServer가 클라이언트 접속을 받으려면 다음 작업이 필요
- CNetServer.Create()로 CNetServer 인스턴스를 생성
- CNetServer.Start()로 서버가 클라이언트 접속을 받을 수 있게 함
Start()에 들어가는 필수 매개변수는 프로토콜 버전과 리스닝 포트 번호로, 프로토콜 버전은 마음대로 값을 정하면 됨
클라이언트는 다음과 같이 서버에 접속
- CNetClient.Create()로 클라이언트 인스턴스를 생성함
- CNetClient.Connect()로 서버로 접속함
NetClient의 FrameMove() 함수를 호출하면, 마지막에 같은 FrameMove()를 호출했던 때 이후부터 지금까지 누적된 이벤트나 수신된 메시지에 대한 이벤트 콜백이 일어남
요약)
- NetServer를 생성하여 Start() 함수를 호출
- NetClient를 생성하여 Connect() 함수를 호출
- NetServer.OnClientJoin(), OnClientLeave()에서 클라이언트의 들어옴/나감을 처리
- NetClient.OnJoinServerComplete(), OnLeaveServer()에서 서버와 접속의 성공/실패/중도 연결 해제를 처리함
- NetClient.FrameMove()를 계속해서 호출
프라우드넷에서 메시지를 주고 받는 방법
- 전통적인 방법으로 바이너리 데이터 주고받기
- 다른 컴퓨터에 있는 함수를 원격으로 호출하기
전통적인 방법으로 바이너리 데이터 주고받기
: NetClient나 NetServer의 SendUserMessage() 함수를 호출하면 상대방에게 여러번 메시지가 전송됨, 이때 제공해야 하는 매개변수는
- 누구한테? (HostID 또는 HostID array)
- 어떻게? (reliable, unreliable, ...)
- 무엇을? (byte array)
와이파이 셀룰러 연결 핸드오버 기능
- 연결 유지 기능
RMI
: 원격 메서드 호출(Remote Method Invocation)의 약어로, "상대방 컴퓨터 안에 있는 프로그램의 특정 함수를 멀리서 실행하라."라는 의미
- RMI의 정체는 수동으로 만들었어야 하는 코드를 자동으로 만들어 주는 것으로 송신하는 쪽에서는 실제 함수 대신 송신을 담당하는 코드가 실행됨
- 송신을 담당하는 코드는 "함수 호출을 대신해 준다"라는 의미로 proxy라고 함
원격 메서드 호출의 장점
- 송신을 처리하는 코드와 수신을 처리하는 코드를 손으로 일일이 구현할 필요가 없음
- 송수신 메시지의 형태가 변경되었을 때 송신이나 수신을 처리하는 코드를 수정하다가 실수할 위험이 없음
서버와 클라이언트에 송신 코드(Proxy)와 수신 코드(Stub)를 붙이는 방법
- Proxy, Stub이 인스턴스를 생성함
- 이 인스턴스들을 AttachProxy, AttachStub 함수를 써서 부착함
클라이언트에서 서버로 RMI를 호출
- RMI를 호출할 때는 다음 매개변수를 넣음
서버에서 RMI 호출받기
- 호출받는 함수에서 전달하는 매개변수
서버에서 클라이언트로 원격으로 함수를 호출하려면
- 앞서 선언했던 <서버 => 클라이언트> RMI를 서버와 클라이언트에 붙여야 함
- RMI의 Proxy는 서버에 붙이고 RMI의 Stub는 클라이언트에 붙임
지금까지 절차 요약)
- PIDL 파일에 RMI 함수들을 정의
- 이를 컴파일,, 가능하면 빌드 설정에 넣음
- 생성된 Proxy, Stub을 NetClient와 NetServer에 부착함
- 생성된 Proxy의 함수를 호출하면 메시지가 전송됨
- 생성된 Stub에 함수를 부착하면 그 함수들이 호출됨
P2P
- 서버에서 클라이언트 1과 클라이언트 2가 P2P 연결을 하라고 지시
- 클라이언트 1, 클라이언트 2는 자기가 P2P 연결이 되었음을 즉시 알 수 있음
- 직후에 바로 클라이언트 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 |