강의 원본 : https://www.youtube.com/playlist?list=PLy-g2fnSzUTDsS7kCzmFYn4BJK6nCs0_r
- PC내부에서 일어나는 데이터 교환도 네트워킹이라고 하고 PC간에 통신도 네트워킹이라고한다.
- Latency 차이가 게임 네트워크에서 가장 중요하다
- 광속으로 신호가 전달된다고 해도 두 PC간에 시간차이는 조재할수 밖에 없다
- 실시간 게임 서버에서 양쪽 PC간의 입력시간 차이가 있더라도 지연시간 만큼 기다려주면 서로 같은 결과를 만들어줄수 있다.
- 두 플레이어간의 입력이 시간상에서 서로 다르게 들어와도 지연시간의 존재를 고려하여 처리해준다면 양 쪽 모두 동일한 결과를 만들어 낼수 있다.
- 이러한 방식을 Deterministic 방식이라고 부른다.
- 만약 일련의 문제가 발생하여 두 플레이어간의 상태가 달라진다면 이러한 상황을 desync라고 한다.
- 두 플레이어간의 입력 시간이 동일하도록 delay를 해주면 당장의 Sync 구현을 가능하다.
- 최대 100ms 입력지연시간으로 넘어가면 일반 사용자들이 체감 가능해진다.
- 입력시연시간을 만회하기 위해 두 플레이어간의 다른 타이밍 입력으로 한쪽 PC에 다른쪽 PC에서 온 입력이 들어오면 다른쪽 PC의 입력 신호가 거쳐온 지연시간을 계산해 RollBack하고 다시 재생하는 방식도 있다.이러한 상황에서 생기는 현상이 튕김이다.
- Rollback으로 인해 생기는 플레이어의 불편이 심하고 뒤로감기 기능같은 기능이 구현하기 힘들다.
- 게임 프로그래밍에서 Desync 상황을 극복하는것이 매우 중요하다.
- 플레이어간의 패킷 교환은 보통 가운데 중계서버를 통해 통신한다. Relay방식과 broadCast방식이 있다.
- 중계서버가 존재한다면 Desync는 잘 일어나지 않으나 처리과정이 복잡해져 Delay가 너무 길어진다.
- Delay에 민감하지 않은 게임 장르 구현에서는 중계서버 방식으로 처리한다.
- Delay에 민감할경우 무조건 Rollback을 실행하는 방식이 오히려 구현과 성능에서 이득이다.
- P2P 방식은 클라이언트-클라이언트가 직접 통신하는 방식으로 호스트 방장이 각 node에 통신을하는 방식이다. 그리고 full connection 방식은 각 클라이언트가 관리할 통신은 많지만 중간에 누군가 나가도 통신망이 터지지 않는다.
- Relay 방식은 서버 컴퓨터를 두고 플레이하는 방식이다.
- Private IP를 port에 물려서 네트워크 노드 서비스를 확장할수 있는 장비를 NAT 장비라고 한다.
- TCP는 게임에서 사용하기에는 속도가 느려서 Reliable UDP내지는 hole punching UDP를 사용한다. 현재로서는 많이 소스가 풀어져있다.
- Deterministic방식은 Input set에 의존하기 때문에 해킹에 취약하다.
- 그래서 Checksum과 파일 크기를 비교하여 내부파일 해킹 여부를 판단해 차단하는 방법이 있으며 nprotect같은 별도의 소프트웨어를 이용하여 실행파일을 실시간으로 검사하여 판단하는 방식도 있다.
- 소스코드 암호화하는 방식도 있으나 속도가 조금 느릴수도 있다.
- 웹서버 같은 경우 클라이언트가 필요한 자원을 요청하고 서버가 전송해주면 연결을 끊는 방식을 사용한다.
- 게임서버의 경우 보통 연결을 끊지는 않는다
- 서버에서 월드에 클라이언트의 이동을 크래킹하고 이를 다수의 클라이언트에게 보내주는 응답을 보내어 월드를 유지하는 방식을 Server Authority방식이라고 한다.
- 최소 각 클라이언트마다 10개의 패킷을 받을수 있어야 실시간 게임 서버라고 볼수 있다. 이를 구현하는 방식에는 IOCP와 Select 방식이 있다.
- OS에서 하드웨어의 사양이나 특성에 구애받지 않고 프로그래밍을 할수 있는 영역을 HAL(추상화 Arial)이라고한다. 여기서 하드웨어와 프로그램을 이어주는것, 네트워크 넘어에서 IO를 주고 받는 것을 Socket Progrmming이라고한다.
- 일련의 명령을 요청하고 다른 프로세스를 수행하다가 다시 돌아오는 방식을 비동기식 방식이라고 한다.
- Window에서는 IOCP 방식으로 Linux에서는 Epoll 방식으로 비동기 프로그래밍을 수행한다.
- Select 방식은 처리 여유공간이 있으면 주기적으로 확인해서 끼어들어가는 방식이다. 구현이 간단하다. 일반적으로 100개 이하..?
- IOCP 방식은 Request를 요청하고 결과를 저장해두었다가 결과가 나왔는지 확인하는 방식이다. 효율적이다.
- 월드내에 다양한 이벤트를 처리하기 위해 1개의 쓰레드를 사용하는 것을 Single-thread라고하며 여러 쓰레드를 사용하는것을 Multi-thread라고한다.
- 서로의 프로세스간의 상호작용이 없다면 멀티 프로세스를 사용하는 것도 좋은 방법이다.
- Sigle thread + Multi process 구조 방식정도는 좋은 구조이다.
- 만약 Sigle thread로는 감당이 안되는 상황에서 seamless하게 분할이 안된다면 어쩔수 없이 멀티쓰레드를 사용해야ㅐ한다. 다만 이때 구조를 나누고 구획화하는것이 중요하다.
- 싱글 프로세스에서는 머신의 성능을 올려 감당가능한 프로세스의 수를 올리는 방식을 Scale up 방식이라고한다.
- 멀티프로세스에서 머신의 대수를 늘려서 감당하는 프로세스의 수를 올리는 방식을 Scale out방식이라고한다.
- 서버 비용 측면에서 Scale out 방식이 저렴하다.
- Availability(가용성) : 서버 한놈이 죽으면 게임이 터져버린다. - Single of failure
- 멀티프로세스에서 프로세스간에서 넘어갈때 단절이 생긴다. 이러한 단절이 없는 상태를 seamless라고하며 이 상황에서는 싱글 프로세스가 유리하다. 서비스를 배포하고 업데이트 하는 과정도 복잡해진다.
- Scale out 상태에서는 규모가 커지면 인력으로는 한계가 있어서 자동배포같은 툴이 어려워졌다. 이러한 자동 배포 과정을 전문적으로 하는 직군을 Devops라고 부른다.
- 멀티 쓰레드에서 코어수가 늘어나면 코어간의 관리에 연산 관리가 많아지면서 오히려 비효율적일수 있다.
- 코어수가 늘어날수록 공유자원에 대한 경쟁이 치열해지고 성능은 떨어진다.
- 멀티쓰레드에서 자원을 나눌때 기준을 나누어야 코어의 성능을 최대화 할수 있다.
- 액터를 기준으로 쓰레드를 나누면 액터간의 통신은 Message를 보내는 방식으로 처리한다. (Akka 방식)
- 공유자원 보호를 위해 Lock을 걸면 성능이 하락하고 데드락 발생가능서이 생기는 문제가 발생한다.
- Message 방식에서 만약 비동기 방식으로 구동한다면 타이밍 이슈로 문제가 생길수 있다.
- Actor 마다 가지고 있는 고유의 특성을 포함하는 컴포넌트를 기준으로 thread를 나누는 방식이다. 이를 Entity Component System ECS 방식이라고한다.
- Component는 상태만 가지고 있고 기능은 가지고 있지않은것을 말한다. Entity = 컴포넌트를 가지고 있는것. 기능은 System이 가지고 있다. 다만 데이터는 가지고 있지않다.
- MVC 구조의 게임버전 ECS 구조이다. 이 구조의 장점은 확장성이 좋아지고 Data Locality가 증대된다.
- ECS구조에서 Component는 자체적인 Compnent를 배열상에 추가가 가능하기 때문에 Data Locality가 증대될수 있다.
- ECS 방식은 아직 완성된 구조는 아니다.
'공부 학습' 카테고리의 다른 글
Unity에 IOCP서버 연동하기 (0) | 2022.08.01 |
---|---|
C++에서 virtual(가상함수) 란..? (0) | 2022.08.01 |
머신러닝 정리(종합) (0) | 2022.07.25 |
Catboost 기본부터 알아보기 (0) | 2022.04.02 |
베이지안 선형 회귀(Bayesian linear regression) 기본부터 알아보기 (1) | 2022.04.02 |