PUN Classic(PUN1이라고도 불립니다)은 PUN의 첫 버전입니다.         현재는 리팩토링 및 기능 확장에 의해 PUN2로 새롭게 바뀌었습니다.          새 프로젝트에는 PUN2를 이용해 주시고, 기존의 프로젝트도 가능하면 PUN1에서 PUN2로 옮기는 것을 권장합니다.  자세한 내용은: "마이그레이션 노트". PUN Classic은 곧 점검이 시작됩니다.        중요한 버그의 수정과 Unity의 신버전의 지원 등을 예정하고 있습니다. 신기능의 추가는 PUN2에서만 이루어지므로 주의해 주십시오.

연결해제 분석

온라인 멀티 플레이어 게임을 구축 할 때 클라이언트와 서버간의 연결이 때로 끊어 질 수 있다는 것을 염두에 두어야 합니다.

연결이 끊기는 원인은 소프트웨어 또는 하드웨어의 원인 일 수 있습니다. 연결이 끊기면 메시지는 지연, 없어지거나 꼬여서 연결을 셧다운 해야 할 수도 있습니다. 이런 사항이 자주 발생하면 무엇인가를 해주어야 합니다.

일반적인 이슈

타임아웃 연결해제

타임아웃 연결해제는 연결 자체의 문제를 제외한 것 중에서 가장 많이 발생하는 이슈입니다.

타임아웃의 의미는 신뢰 메시지를 전송 또는 ACK 에 실패하여 연결이 종료되는 것 입니다.

Photon 연결의 양쪽(클라이언트와 서버)은 신뢰 명령어가 상대편에서 잘 수신되었는지를 모니터링 합니다. ACK 가 "즉시" 없다면 (현재 라운드트립 시간을 기준으로) 신뢰 커맨드는 재전송 됩니다. 몇 번을 반복해도 반응이 없으면 상대쪽에서 적절하게 응답할 수 없다는 것을 뜻하게 되며 연결 타임아웃이 발생 합니다.

Back To Top

타임아웃 처리

자주 타임아웃이 발생하게 되는 경우 원인은 다양 하지만, 이러한 이슈의 원인을 찾고 수정하는 몇 개의 일반적인 시나리오들이 있습니다.

타임아웃 연결해제가 매우 자주 발생한다면, 전송하는 데이터의 양을 검토 해봐야 합니다. 데이터 양이 갑자기 많아졌거나 초당 메시지 속도가 매우 높으면 연결 품질에 영향을 줄 수 있습니다. 다른 하드웨어와 다른 네트워크에서 이 이슈를 재현 할 수 있는지 체크 해보세요.

재전송 개수와 재전송 시간을 조정 할 수 있습니다. "Solution: Tweak Resends"을 보세요. ResentReliableCommands 를 살펴 보시기 바랍니다. "체크: 신뢰 커맨드 재전송"을 읽어 보세요.

Back To Top

대역폭 이슈와 버퍼 풀

버퍼 풀(Buffer Full) 이슈는 거의 "메모리 부족(Out of Memory)" 문제 입니다. Photon 서버들과 클라이언트들은 패키지로 담아 인터넷을 통하여 전송하기전에 일반적으로 명령어 일부를 버퍼링 합니다. 이렇게 하면 여러개의 커맨드들을 (더 적은) 패키지로 통합 할 수 있습니다. 어느 쪽에서 수 많은 커맨드들이 나오게 된다면(예, 수 많은 큰 이벤트를 전송함으로써) 버퍼가 부족할 수 있습니다.

버퍼를 채우는 것은 추가적인 지연(Lag)의 원인이 되기도 합니다: 더이상 다른 쪽으로 이벤트들이 도착하지 않는 것을 알게 될 것 입니다. 오퍼레이션 응답이 평소만큼 빠르지 않습니다.

Back To Top

전형적인 솔루션

솔루션: Tweak Resends

최근 닷넷 Photon 라이브러리에는 재전송 시간을 수정할 수 있는 두 개의 프로퍼티가 있습니다: QuickResendAttemptsSentCountAllowance입니다.

QuickResendAttempts 는 수신 측에서 ACK 를 받지 않은 신뢰 명령의 반복 속도를 높여 줍니다. 결과는 일부 메시지가 드롭 되었다면 더 짧은 지연으로 인하여 트래픽은 더 많아 지게 됩니다.

SentCountAllowance 는 클라이언트가 개별적으로 신뢰 메시지를 얼마나 자주 반복 할지를 정의 합니다. 클라이언트가 반복을 더 빠르게 한다면 SentCountAllowance 를 더 자주 반복 해야 합니다.

특정한 경우에 있어서는 QuickResendAttempts 를 3으로 하고 SentCountAllowance를 7 로 설정하면 좋은 결과를 볼 수 있습니다.

PUN v1.58 에서는 PhotonNetwork 클래스를 변경하여 값을 설정 할 수 있습니다. networkingPeer.QuickResendAttempts 를 설정하세요. PUN v1.60 에서는 PhotonNetwork 클래스에 프로퍼티를 직접 추가 할 예정 입니다.

Back To Top

체크: 신뢰 커맨드 재전송

ResentReliableCommands의 모니터링을 시작 해야 합니다. 이 카운터는 신뢰 커맨드가 재전송 될 때 마다 증가 합니다(서버로 부터 ACK 가 제 시간에 도착하지 않았기 때문에)

PUN 에서는 PhotonNetwork.ResentReliableCommands 이고 LoadBalancing API 에서는 LoadBalancingClient.ResentReliableCommands 를 사용 합니다.

만약 이 값이 최대값을 넘어 섰다면 연결이 불안 해지고 UDP 패킷들은 양방향에서 잘 전달 되지 않게 됩니다.

Back To Top

솔루션: CRC Checks 사용하기

때로는 클라이언트와 서버 간 전송시에 패키지가 변질 될 수 있습니다. 라우터 또는 네트워크가 Busy 할 때 많이 발생 합니다. 일부 하드웨어 또는 소프트웨어가 명백한 버그로 인한 변질로 인하여 언제든지 발생 할 수 있습니다.

Photon 에는 추가적인 패키지의 CRC 체크 기능이 있습니다. 이것으로 인하여 부하가 걸릴 수 있으므로 디폴트로는 활성화 해 놓지는 않았습니다.

클라이언트에서 CRC 체크를 사용하도록 하지만 서버는 이렇게 하면 CRC 를 보내 줄 것 입니다.

PUN에서 연결 하기 전에 PhotonNetwork.CrcCheckEnabled = true 로 설정 해주세요. C# 라이브러리에서 LoadBalancingClient.loadBalancingPeer.CrcEnabled = true 로 설정 합니다.

Photon 클라이언트들은 CRC 체크를 가능하도록 설정해 놓아 얼마나 많은 패키지가 오류로 떨어졌는지 추적 할 수 있습니다. PUN 에서는 PhotonNetwork.PacketLossByCrcCheck 를 모니터링 할 수 있습니다. 닷넷 SDK 에서는 LoadBalancingClient.loadBalancingPeer.PacketLossByCrc를 체크 하세요.

Back To Top

솔루션 : 전송 줄이기

대역폭 문제를 해결 하기 위하여 더 적게 전송 할 수 있습니다. 이렇게 하는 것에는 수많은 접근법이 있습니다.

  • 문자열을 보내는 대신에 모든 클라이언트가 알고 있는 짧은 문자열 또는 정수 또는 바이트 키 를 전송하여 텍스트를 대체 할 수 있습니다. 예를들어 PUN 은 RCP 콜에서 메소드 이름을 축약 할 것 입니다. 모든 메시지에 대해서 이렇게 처리 할 수 있습니다.
  • 델타 압축(delta compression). 마지막으로 전송 된 이후 변경된 것에 대한 값만 전송 합니다.
  • 관련있는 값 만을 전송하며 이것들로 부터 최대한 많은 것을 얻습니다. 무엇을 전송하며 얼마나 자주 보내는지 생각해 보세요.
    • RTS 에서는 다량의 유닛에게 "orders" 전송을 할 수 있습니다. 이것은 초당 10번 각 유닛에게 위치, 회전과 속도를 전송하는 것 보다는 훨씬 더 양이 작습니다! 읽으면 유용한 것: 1500 archers.
    • 발사 했을 때 쏜 위치와 방향을 전송 합니다. 총알은 직선으로 날아 갑니다. 따라서 100 ms 마다 모든 총알 위치를 보낼 필요는 없습니다. 총알이 어떤 것에 맞았거나 굉장히 멀리 날아간 후에 총알을 없앨 수 있습니다.
    • PUN 에서 모든 총알의 인스턴스를 생성하거나 파괴할 필요가 없습니다. 예,
    • 애니메이션을 전송하지 마세요. 일반적으로 모든 애니메이션을 입력과 플레이어가 행하는 액션으로 판단 할 수 있습니다. 지연되어 전송 된 애니메이션으로 인하여 늦게 플레이 되는 것은 어색하게 보입니다.
    • 지도와 같이 큰 정적 데이터는 다른 서비스를 이용하여 전송 합니다. Photon 은 컨텐츠 전송 시스템이 아닙니다. 일반적으로 HTTP-기반 컨텐츠 시스템을 이용하는 것이 더욱 쉽고 유지하는 것이 더 저렴 합니다. 최대 전송 유닛(MTU,Maximum Transfer Unit) 보다 큰 데이터는 단편화되며 여러개의 신뢰 패키지로 전송 됩니다.(다시 하나의 큰 메시지로 조립되어야 합니다)
    • 커스텀 속성을 과다하게 사용하지 마세요! 긴 시간동안 진행되는 게임에서 너무 많은(!) 커스텀 프로퍼티를 설정 하였다면 참여하고 있는 플레이어들이 현행화 해야 할 것이 너무 많을 것 입니다. 룸에 참여하는 동안 클라이언트가 많이 드롭될 때 이 사항을 체크 해 보세요.
    • 할 수 있다면 비신뢰로 전송 하세요. 가능한 빨리 다른 갱신사항을 전송해야 하는 경우 대부분은 비신뢰 메시지를 전송 할 수 있습니다. 예 : FPS 의 플레이어 위치는 일반적으로 비신뢰로 전송 될 수 있습니다. 비신뢰 메시지는 반복 전송을 절대로 유발하지 않습니다.

Back To Top

솔루션: 주기적으로 서비스를 호출 합니다

클라이언트 측에서 연결이 살아있도록 유지 하기 위해서 Service를 주기적으로 호출 해 야 합니다. 초당 10에서 50번 호출이 좋습니다.

PUN 에서만 이것을 자동으로 해줍니다!

접속 해제 문제 또는 지연에 대해서 인지 했을 때, Service 호출 또는 SendOutgoingCommands()DispatchIncomingCommands() 를 자주 호출 했는지 확인 해보세요. 프레임속도 저하는 Photon 연결에 영향을 받습니다.

유니티에서는 신과 에셋을 로드하는 동안과 Standalone-플레이어 창을 드래그 할 때에는 Update() 가 호출되지 않는 다는 것을 기억 하세요!

만약 클라이언트가 트래픽 통계를 사용할 수 있다면 얼마나 자주 전송, 수신 및 처리 하는지 추적해야 합니다. 아래를 보세요.

Back To Top

체크 해 봐야 할 것

다른 것을 통해 연결해 보기

어떤 경우에 있어서는 특정 하드웨어로 인하여 연결이 실패 될 수 있습니다. 다른 WiFi , 라우터로 시도 해보세요. 다른 기기로 했을 때 더 잘 수행 되는지 체크 해봅니다.

Back To Top

다른 서버 또는 지역으로 시도하기

Photon 클라우드는 다른 지역으로 접속을 쉽게 할 수 있습니다.

자체 호스팅을 하시나요? 가상 기계보다는 물리적인 것이 좋습니다. 서버와 가까운(하지만 동일 기계도 아니며 동일 네트워크상에 있지 않아야 합니다) 클라이언트와 최소 지연(라운드트립 타임)을 테스트 합니다. 고객에게 가까운 곳에 서버를 추가하는 것을 고려 해보세요.

Back To Top

다른 프로젝트를 시도하기

Photon 의 모든 클라이언트 SDK 는 몇 개의 데모가 있습니다. 플랫폼에 맞게 이중 하나를 선택하여 사용 합니다. 데모도 역시 실패 하는 경우이면 연결에 문제가 있는 것 입니다.

Back To Top

더 낮은 MTU 시도하기

클라이언트 측의 설정으로 강제적으로 서버와 클라이언트를 평소보다 더 작은 최대 패키지 크기를 이용하도록 할 수 있습니다. MTU 를 낮추는 것은 메시지에 대해 더 많은 패키지를 보내야 한다는 것을 의미 하지만 다른 방법으로 해결 되지 않을 때는 시도해 볼 만 합니다.

이 결과는 아직 검증되지 않았으므로 이것을 통해 향상이 된 경우라면 아래 메일주소로 메일을 주시면 감사하겠습니다: developer@photonengine.kr.

PUN 에서는 PhotonNetwork.networkingPeer.MaximumTransferUnit = 520 으로 설정합니다. C# 에서는 LoadBalancingClient.loadBalancingPeer.MaximumTransferUnit = 520 으로 설정 합니다.

Back To Top

더 많은 반복 시도하기

기본적으로 Photon 클라이언트들은 각각의 신뢰 명령을 최대 6번까지 전송 합니다. 5번째 시도까지 아무 ACK가 없으면 연결은 셧다운 됩니다.

PUN 에서 PhotonNetwork.MaxResendsBeforeDisconnect C# 에서는 LoadBalancingClient.loadBalancingPeer.SentCountAllowance를 설정하여 더 많은 반복이 될 수 있도록 실험해 볼 수 있습니다. 반복수를 더 많이 설정하더라도 더 나은 연결을 보장 되는 것은 아니며 확실히 지연이 길어 지게 됩니다.

Back To Top

로그 체크 하기

모든 클라이언트들은 내부 상태 변화와 이슈에 대한 로그 메시지를 제공하기 위한 몇 개의 콜백이 있습니다. 이러한 메시지들은 기록 해야 하고 문제가 발생된 경우에 확인 해 봐야 합니다.

보이는 로그가 쓸모가 없다면 로깅을 어느정도 증가 시킬 수 있습니다. API 레퍼런스를 보고 어떻게 하는지 확인 해보세요.

Back To Top

트래픽 통계 체크

일부 클라이언트 플랫폼에서는 Photon 에서 직접적으로 Traffic Statistics 를 사용하도록 할 수 있습니다. 이러한 추적 자료는 성능의 중요한 지표이며 쉽게 기록 할 수 있습니다.

C# 에서는 트래픽 통계들은 LoadBalancingPeer 클래스의 TrafficStatsGameLevel 프로퍼티에서 사용 할 수 있습니다. 가장 관심있는 값들에 대한 개요를 제공 합니다.

예를들어, 연속된 DispatchIncomginCommands 호출 시간 중 가장 긴 시간을 체크 하기 위해서 TrafficStatsGameLevel.LongestDeltaBetweenDispatching을 사용 합니다. 만약 이 시간이 수 밀리세컨드보다 크면 로컬 지연이 있을 가능성이 있습니다.

LongestDeltaBetweenSending 을 검토하여 클라이언트가 자주 전송하고 있는지 확인 하시기 바랍니다.

TrafficStatsIncomingTrafficStatsOutgoing 프로퍼티들은 수신/발신 바이트, 커맨드와 패키지에 대한 통계를 제공합니다.

Back To Top

Wireshark

네트워크 프로토콜 분석기 및 로거로써 게임의 네트워크 레이어에서 어떤 일이 발생하고 있는지 알아볼 때 매우 유용 합니다. 이 툴로 네트워킹 측면의 사실들을 볼 수 있습니다. Wireshark는 복잡해 보이지만 게임의 트래픽을 기록 할 때 몇개만 설정하면 됩니다.

설치하고 시작 합니다. 첫 번째 툴바 아이콘이 (네트워크)인터페이스 목록에서 오픈될 것입니다.

PhotonServerSettings in Inspector
Wireshark 툴바

트래픽을 가지고 있는 인터페이스 옆의 박스를 체크할 수 있습니다. 확신이 서지 않으면 하나 이상의 인터페이스를 기록하세요. 다음에 "Options"을 클릭 합니다.

PhotonServerSettings in Inspector
Wireshark - Capture Interfaces

모든 네트워크 트래픽에 대한 것을 다루지 않으므로 체크된 인터페이스별로 필터를 설정 해야 합니다. 다음 다이얼로그 ("Capture Options")에서 체크된 인터페이스를 찾아 더블 클릭 하세요. 이렇게 하면 "Interface Settings" 다이얼로그가 열리게 됩니다. 여기에서 필터를 설정 할 수 있습니다.

PhotonServerSettings in Inspector
Wireshark - Interface Settings

기록할 Photon 과 관련된 필터는 다음 처럼 보입니다:

(udp || tcp) && (port 5055 || port 5056 || port 5057 || port 5058 || port 843 || port 943 || port 4530 || port 4531 || port 4532 || port 4533 || port 9090 || port 9091 || port 9092 || port 9093 || port 19090 || port 19091 || port 19093 || port 27000 || port 27001 || port 27002)

"Start" 를 누를 때, 연결시에 기록이 시작됩니다. 이슈가 발생 한 후에, 기록을 멈추고(세 번째 툴바 버튼) 저장 합니다.

오류가 발생한 상황, 오류가 주기적으로 발생했는지, 얼마나 자주 발생했고 언제 발생했는지(로그에 타임 스탬프가 포함되어 있습니다)를 포함 시켜 주는 것이 가장 좋습니다. 클라이언트 콘솔 로그도 첨부해 주세요. 저희에게 .pcap 파일과 다른 파일을 메일로 주시면 검토 하겠습니다.

기술문서 TOP으로 돌아가기