지난 시간에 foreach로 broadcast를 하는건 유저가 증가할 수록 비효율적이기에 '패킷 모아 보내기' 라는 방법을 사용하기로 하였다.
그럼 이 패킷 모아보내기를 어디서 처리할 수 있을까? 크게 엔진과, 콘텐츠 쪽이 있는데 우리가 작성했던 코드로 보면 엔진영역은 ServerCore - Session - Send() 부분이다.
Enqueue()
를 통해 바로 넣고, RegisterSend() 하는 방식인데 이게 아니라 Enqueue()
로 어느정도 쌓아두고 보내는 구조로 하면 그게 패킷 보내기가 된다.
콘텐츠 쪽은 GameRoom 쪽이며 아래에서 실험을 해본다.
List<ArraySegment<byte>> _pendingLIst
를 선언하고, BroadCast에서 바로 Send()를 해주는게 아니라 List에 저장만 해둔다.
Server의 Main 쓰레드는 그동안 아무 일도 하지 않고 있었는데, 여기에서 일정 시간마다 모아둔 일감을 비우게 명령하도록 한다.
GameObject에 Flush()라는 기능은 없었기에 제작 해준다. 이제 여기서 모아둔 것을 반복문을 통해 전송할 것이다.
GameRoom - Flush()
에서 전송 List 형식을 받아 처리 하기 위해 Send() 함수를 오버로딩 해주어 List 타입은 다른 방법으로 처리한다.
매개변수를 List<ArraySegment<byte>>
으로 변경해주고 foreach를 통해 LIst에 있는 패킷들을 ArraySegment 형태로 보내준다.
로그를 찍어주고
잘 동작하는지 테스트를 해보면 패킷이 전송 되는 걸 확인 할 수 있다.
하지만 패킷이 불규칙적이게 전송되는 모습을 볼 수 있는데 이는 보통 버처 사이즈에 문제가 있어 이러한 문제가 발생한다.
버퍼 사이즈는 프로젝트 초반에 RecvBuffer를 하며 설정 한 부분인데, 이를 가장 큰 사이즈인 65535로 변경해주어 크기를 증가시켜준다. ChunkSize 포함
추가 문제 해결 방법
만약 버퍼사이즈를 증가시켜도 패킷 전송에 문제가 발생한다면 ServerCore의 Listenr에서 설정해주었던 backlog 수를 조절 하거나 콘텐츠 단에서 접속할 때 잠시 쉬어며 접속하게 만들기 위한Thread.Sleep()
의 시간을 변경 해주는 방법을 사용할 수 있다.
하지만 나의 경우는
패킷이 한 번에 5-14 이정도 밖에 전송이되질 않았다. 프로세스 동작이 안정적인걸 보아 문제는 없을 듯 싶으나 컴퓨터 사양의 문제가 아닌가 싶긴하다.