Frequently Asked Questions

어떤 Photon 제품이 나에게 맞을까요?

이에 대한 답변은 주로 귀하의 프로젝트와 팀에 따라 달라집니다.
일반적으로, 저희는 가장 진보된 클라이언트 솔루션인 Fusion 또는 Quantum을 사용하는 것을 권장합니다.

빠른 개요를 위해 두 제품 시트 모두 제품 선택기 "Quadrant"를 포함합니다:

의문 사항이 있으시면 언제든지 연락주시길 바랍니다.

Photon Cloud

Photon Cloud는 다운되나요?

Photon Cloud 상태는 여기에서 확인하거나 트위터에서 @exitgames를 팔로우하여 상태 업데이트에 대해 알림을 받으십시오.

기본 Photon 지역은 어디인가요?

고객들은 최소 하나의 지역을 사용할 수 있으면 Photon Cloud에 연결할 수 있어야합니다.
이에 대해 보장을 위해, 기본값이 구성되어있거나 개발자가 명시적으로 값을 설정하지 않거나 "최적 지역" 옵션을 선택하지 않을 때 사용됩니다.
기본값은 클라이언트 SDK에 따라 다양할 수 있습니다.
원시 SDK에서는 OpGetRegions 에 의해 서버에서 리턴되는 지역 목록의 첫 번째 인덱스에 있는 값입니다.
Unity와 DotNet SDK에서 기본 지역은 "EU" 입니다.

일부 지역을 비활성화할 수 있나요?

예.
이 기능은 "비활성화된" 지역 없이 "지역 허용 목록"을 정의하여 작동합니다.
"대시보드 지역 필터링"에 대해 자세히 알아보세요.

모든 클라우드 서버/IP 목록을 얻을 수 있나요?

Photon Cloud가 너무 자주 변경되기 때문에 이러한 목록은 존재하지 않습니다. 서버가 추가되거나 제거되고 때때로 새로운 지역이 나타납니다. 즉, Photon Cloud(전체)를 허용 목록에 추가하는 것은 불가능합니다.

Enterprise Cloud의 경우 다른 주제이기 때문에 메일로 문의해 주시길 바랍니다.

Photon Industries Circle 내의 앱은 허용 목록에 대한 호스트 이름에 의존할 수 있습니다: *.photonindustries.io. 연결할 "서버"로 ns.photonindustries.io를 사용해야 합니다.

방 연결이 끊긴 후 빨리 다시 참여하려면 어떻게 해야 하나요?

방에 참가하는 동안 예상치 못한 연결 끊김으로 인해 복구하려면 클라이언트가 다시 연결을 시도하여 방에 다시 참가할 수 있습니다.
우리는 이것을 "빠른 재입장"이라고 부릅니다.
빠른 재입장은 다음과 같은 경우에만 성공합니다.

  • 방이 여전히 같은 서버에 존재하거나 로드될 수 있음:
    플레이어가 방을 나가더라도 다른 플레이어가 계속 참여해 있다면 그 플레이어는 Photon 서버에서 살아남을 수 있습니다.
    플레이어가 마지막으로 나가고 방이 비어 있으면 EmptyRoomTTL은 플레이어가 참여하거나 다시 참여하기를 기다리면서 방이 살아 있는 시간입니다.
    EmptyRoomTTL 이후에도 룸이 비어 있고 아무도 참여하지 않으면 해당 룸은 Photon 서버에서 제거됩니다.
    지속성 조건이 충족되고 웹훅이 설정된 경우, 룸 상태를 구성된 웹 서비스에 저장하여 나중에 로드할 수 있습니다.
  • 액터가 비활성으로 표시됨: 동일한 UserId를 가진 액터가 액터 목록 내에 있지만 현재 룸에 참여하지 않은 경우입니다.
    이렇게 하려면 PlayerTTL이 0이 아니어야 합니다.
  • 비활성 액터의 PlayerTTL이 만료되지 않았습니다. 액터가 돌아올 수 있는 옵션과 함께 방을 나갈 때 비활성화 타임스탬프를 저장합니다.
    방이 활성화되어 있는 한, 비활성화 시간 후에 PlayerTTL 밀리초가 경과하면 해당 액터는 액터 목록에서 제거됩니다.
    그렇지 않은 경우, 액터가 재참여를 시도할 때 재참여 시도 시간과 비활성화 시간 사이의 밀리초 차이가 PlayerTTL을 초과하면 액터는 액터 목록에서 제거되고 재참여는 실패합니다.
    따라서 비활성적인 행위자는 비활성화 시간 후 PlayerTTL 밀리초 동안만 룸에 다시 참여할 수 있습니다.

스레딩

단일 Photon server에서 쓰레드는 몇 개나 수행되나요?

쓰레드의 사용은 분리됩니다:

  1. 네이티브 - 9 개 쓰레드
  2. 매니지드 - .NET 기본 설정을 사용하는 .Net ThreadPool 에 의존함

이 설정은 상당히 집중적으로 테스트되었으며 다양한 부하 프로파일에 매우 적합합니다.

매니지드 쓰레드의 사용은 (.NET Windows Performance counters에서 보고된 것처럼) 다양합니다:

a) 전형적인 Photon cloud RealTime 부하에서 ~12
b) 클라이언트 클라우드가 플러그인 간 통신(잠금)을 통해 플러그인을 실행함으로써 (우리의 코드와 달리) 일부 더 높은 경합이 발생하는 곳에서 35 (및 그 이상)

노트: 필요에 따라, .Net ThreadPool 설정은 조정될 수 있습니다.
지금까지 기본값은 각 버전마다 다를 수 있지만 좋은 결과를 얻었습니다.

경쟁 조건 및 기타 멀티스레딩 문제를 방지하려면 어떻게 해야 하나요?

Photon에서는 가능한 한 모든 것을 단순화했습니다.

  1. 모든 스레드에서 PhotonPeer 메서드를 사용할 수 있습니다.
  2. PhotonPeer의 모든 알림은 하나의 파이버에서 실행됩니다(아래 파이버에 대한 내용을 읽어보세요).
  3. 한 방의 모든 작업은 하나의 파이버에서 실행됩니다.
  4. 피어는 멀티스레딩 문제로부터 데이터를 보호하기 위해 룸의 파이버로 메시지를 보냅니다.

파이버는 FIFO 방식으로 순차적으로 하나씩 실행되는 작업 목록입니다.
이는 하나의 스레드에서 실행된다는 것을 의미하지 않습니다.
실제로 이러한 작업은 여러 스레드에서 하나씩 실행됩니다.
따라서 첫 번째 작업은 스레드 A에서 실행되고, 완료되면 두 번째 작업은 스레드 B에서 실행됩니다.
하지만 매 순간에 방 데이터에 접근하는 스레드는 단 하나뿐입니다.
여러 개의 파이버가 동일한 데이터에 접근하는 경우 잠금을 사용합니다.
예를 들어, 방의 캐시에 넣어두는 것과 같습니다.

다음과 같이 섬유를 사용할 수 있습니다.

C#

// rooms contructor
someFiber = new PoolFiber(); // create new fiber
someFiber.Start();
someFiber.ScheduleForInterval(someRepetitiveRoutine, 0, 100); // start immediately and repeat every 100 ms, ie 10 times per second. this params may vary as you need
// at some other point, where you need to add more logic to the fiber
someFiber.Enqueue(newTask);
someFiber.Enqueue(()=>{ anotherTask(parameters);});
// from the tasks you can send messages to the room e.g. to notify the room of a result of a task
room.EnqueueMessage(new YourCustomMessage(somethingToSend));

동일한 코드나 동일한 데이터를 공유하는 여러 개의 사용자 정의 파이버를 사용하는 경우 서로 다른 파이버의 작업이 동시에 실행되므로 액세스를 동기화해야 합니다.

Logging

클라이언트가 연결하거나 연결을 끊을 때마다 로그는 어떻게 생성하나요?

어플리케이션의 "log4net.config"에 아래 내용을 추가합니다:

XML


<logger name="Photon.SocketServer.ApplicationBase">
	<level value="DEBUG"/>
</logger>

"{MyApplication}.log"의 출력내용:

Successful connect:

2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ConnID=17, IP 127.0.0.1 on port 4530
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - response sent to ConnId 17 with SendResult Ok

Disconnect:

2013-05-02 11:19:07,608 [24] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnDisconnect - ConnID=17

Photon이 클라이언트에 작업 응답을 보낼 때 어떻게 로그를 생성하나요?

어플리케이션의 "log4net.config"에 아래 내용을 추가합니다:

XML


<logger name="Photon.SocketServer.PeerBase">
	<level value="DEBUG"/>
</logger>

"{MyApplication}.log"을 출력내용:

2013-05-02 11:19:02,569 [21] DEBUG Photon.SocketServer.PeerBase [(null)] - SentOpResponse: ConnID=17, opCode=255, return=0, ChannelId=0 result=Ok size=14 bytes

How to write a log entry when Photon receives an operation request from a client?

This kind of logging is best done in your application's Peer class (which inherits from HivePeer).

XML


<logger name="Photon.Hive.HivePeer">
	<level value="DEBUG"/>
</logger>

Output from "{MyApplication}.log":

2013-05-02 11:19:02,553 [21] DEBUG Photon.Hive.HivePeer [(null)] - OnOperationRequest. Code=255

OnOperationRequest 메소드에서 로그 항목의 내용을 변경할 수 있습니다.

C#

protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
	if (log.IsDebugEnabled)
    {
		log.DebugFormat("OnOperationRequest. Code={0}", operationRequest.OperationCode);
	}	
	// snip
}

클라이언트들이 왜 연결이 끊어질까요? 타임아웃은 어떻게 디버깅을 하나요?

클라이언트의 연결이 끊기는 이유를 확인하려면 피어에서 OnDisconnect가 호출될 때 디버그 로그 항목을 작성하도록 어플리케이션을 구성합니다.

XML


<logger name="Photon.Hive.HivePeer">
	<level value="DEBUG"/>
</logger>

Peer 클래스(HivePeer에서 상속됨)에서 , OnDisconnect() 메소드는 다음의 코드와 같아야합니다:

C#

protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
	if (log.IsDebugEnabled)
    {
		log.DebugFormat("OnDisconnect: conId={0}, reason={1}, reasonDetail={2}", this.ConnectionId, reasonCode, reasonDetail);
	}
	// 	
}

"{MyApplication}.log"의 출력 내용:

2013-05-02 11:19:07,639 [12] DEBUG Photon.Hive.HivePeer [(null)] - OnDisconnect: conId=17, reason=ClientDisconnect, reasonDetail=

If you are using UDP: in case of "TimeoutDisconnect", the "reasonDetail" will contain the RoundTripTime history, like this:

index - sequence - rtt - variance - sentTime - recvTime - cmd_rtt

0 - 326 - 0 - 0 - 830717056 - 830728351 - 11295
1 - 325 - 89 - 19 - 830715918 - 830716042 - 124
2 - 324 - 85 - 14 - 830714826 - 830714904 - 78
3 - 323 - 86 - 17 - 830712751 - 830712813 - 62
4 - 322 - 89 - 14 - 830711659 - 830711737 - 78
5 - 321 - 90 - 16 - 830710551 - 830710645 - 94
6 - 320 - 90 - 19 - 830709428 - 830709537 - 109
7 - 319 - 88 - 19 - 830708320 - 830708414 - 94
8 - 318 - 88 - 23 - 830707197 - 830707306 - 109
9 - 317 - 86 - 24 - 830706105 - 830706183 - 78
10 - 316 - 87 - 29 - 830704701 - 830704763 - 62
... etc ... 

각 라인은 다음들의 값으로 구성되어 있습니다:

  • 인덱스 (0...49, 0이 가장 최신이고 49는 가장 오래된 것입니다. 최신의 50개 항목만 보여집니다.)
  • 시퀀스 - 증가하는 일련번호
  • rtt (RoundTripTime - ms로 현재 RTT - ACK 또는 타임아웃이 발생 처리된 이후 사용가능)
  • variance (ms 로 현재 Variance)
  • sentTime (명령이 전송된 시간)
  • recvTime (ACK가 수신된 시간)
  • cmd_rtt (ms 단위로 명령이 전송되고 ACK가 수신된 시간 사이의 간격)

위의 예에서 클라이언트는 62ms에서 124ms 사이에 cmd_rtt를 가지고 있었습니다. 마지막 명령에 대해 11초 동안 ACK를 수신하지 않은 후 연결이 끊어졌습니다.

Back to top