Frequently Asked Questions
어떤 Photon 제품이 나에게 맞을까요?
이에 대한 답변은 주로 귀하의 프로젝트와 팀에 따라 달라집니다.
일반적으로, 저희는 가장 진보된 클라이언트 솔루션인 Fusion 또는 Quantum을 사용하는 것을 권장합니다.
빠른 개요를 위해 두 제품 시트 모두 제품 선택기 "Quadrant"를 포함합니다:
의문 사항이 있으시면 언제든지 연락주시길 바랍니다.
방 연결이 끊긴 후 빨리 다시 참여하려면 어떻게 해야 하나요?
방에 참가하는 동안 예상치 못한 연결 끊김으로 인해 복구하려면 클라이언트가 다시 연결을 시도하여 방에 다시 참가할 수 있습니다.
우리는 이것을 "빠른 재입장"이라고 부릅니다.
빠른 재입장은 다음과 같은 경우에만 성공합니다.
- 방이 여전히 같은 서버에 존재하거나 로드될 수 있음:
플레이어가 방을 나가더라도 다른 플레이어가 계속 참여해 있다면 그 플레이어는 Photon 서버에서 살아남을 수 있습니다.
플레이어가 마지막으로 나가고 방이 비어 있으면 EmptyRoomTTL은 플레이어가 참여하거나 다시 참여하기를 기다리면서 방이 살아 있는 시간입니다.
EmptyRoomTTL 이후에도 룸이 비어 있고 아무도 참여하지 않으면 해당 룸은 Photon 서버에서 제거됩니다.
지속성 조건이 충족되고 웹훅이 설정된 경우, 룸 상태를 구성된 웹 서비스에 저장하여 나중에 로드할 수 있습니다. - 액터가 비활성으로 표시됨: 동일한 UserId를 가진 액터가 액터 목록 내에 있지만 현재 룸에 참여하지 않은 경우입니다.
이렇게 하려면 PlayerTTL이 0이 아니어야 합니다. - 비활성 액터의 PlayerTTL이 만료되지 않았습니다. 액터가 돌아올 수 있는 옵션과 함께 방을 나갈 때 비활성화 타임스탬프를 저장합니다.
방이 활성화되어 있는 한, 비활성화 시간 후에 PlayerTTL 밀리초가 경과하면 해당 액터는 액터 목록에서 제거됩니다.
그렇지 않은 경우, 액터가 재참여를 시도할 때 재참여 시도 시간과 비활성화 시간 사이의 밀리초 차이가 PlayerTTL을 초과하면 액터는 액터 목록에서 제거되고 재참여는 실패합니다.
따라서 비활성적인 행위자는 비활성화 시간 후 PlayerTTL 밀리초 동안만 룸에 다시 참여할 수 있습니다.
자체 호스팅
리눅스에서 Photon Server를 실행할 수 있나요?
아니오.
Photon Server는 윈도우즈용입니다.
상세내용은 "요구사항" 을 읽어주십시오.
Amazon에서 Photon Server를 어떻게 호스팅하나요?
Amazon에서 Photon Server를 호스트하는 절차입니다:
- 새로운 윈도우즈 서버 EC2 인스턴스를 설정합니다
- Amazon Web Services 계정을 생성합니다.
- AWS 포털에 로그인 합니다.
- "Service -> EC2"로 이동합니다.
- "Create Instance" 섹션의 "Launch Instance"를 클릭합니다.
- Photon Server에서 지원하는 Microsoft Windows Server edition을 "선택" 버튼에서 클릭합니다.
- "Choose an Instance Type" 이후 "6. Configure Security Group"으로 이동합니다
- new security group "Photon Server" 생성하여 이 페이지에 나와있듯이 수신 포트를 허용합니다.
- "Review and Launch"를 클릭하고 검토 및 "실행"합니다.
- 키 페어를 기존 것을 선택하거나 생성합니다.
- 확인 토글을 선택하고 "Launch Instances"를 누릅니다.
- "View Instances"를 클릭하고 인스턴스가 초기화를 마칠때까지 대기합니다.
- 새로운 인스턴스에 RDP 연결
- EC2 인스턴스를 선택합니다.
- "Connect" 클릭합니다.
- "Get Password"를 클릭합니다.
- 개인키를 업로드하거나 내용을 복사하후 "Decrypt Password"를 합니다.
- "Download Remote Desktop File" 을 클릭하여 RDP 바로가기를 얻습니다.
- 바로가기를 더블 클릭하여 원격 머신에 연결합니다.
- 자격증명을 입력하여 로그인합니다.
- Photon Server SDK 설정
- Photon 계정을 생성합니다.
- Photon Server SDK를 다운로드합니다.
- 패키지를 풀고 원격 머신에 파일들을 복사합니다.
- Photon Control을 시작합니다.
- 서비스로 Photon을 설치합니다
- Photon 서비스를 시작합니다.
플러그인 SDK와 서버 SDK의 차이점은 무엇인가요?
두 패키지 모두 동일한 바이너리("deploy" 폴더)와 라이브러리("lib" 폴더)를 제공하지만 다른 소스 코드 프로젝트("src-server")를 제공합니다.
Photon Server SDK는 Photon Server를 자체 호스팅하고 Photon Server 애플리케이션을 개발하는 데 사용할 수 있습니다. 내부 소스 코드는 서버 애플리케이션의 예입니다.
Photon Plugins SDK는 Photon Server를 자체 호스팅하고 사용자 정의 Photon Server 플러그인을 개발하는 데 사용할 수 있습니다. 내부 소스 코드는 플러그인 예제용입니다.
스레딩
단일 Photon server에서 쓰레드는 몇 개나 수행되나요?
쓰레드의 사용은 분리됩니다:
- 네이티브 - 9 개 쓰레드
- 매니지드 - .NET 기본 설정을 사용하는 .Net ThreadPool 에 의존함
이 설정은 상당히 집중적으로 테스트되었으며 다양한 부하 프로파일에 매우 적합합니다.
매니지드 쓰레드의 사용은 (.NET Windows Performance counters에서 보고된 것처럼) 다양합니다:
a) 전형적인 Photon cloud RealTime 부하에서 ~12
b) 클라이언트 클라우드가 플러그인 간 통신(잠금)을 통해 플러그인을 실행함으로써 (우리의 코드와 달리) 일부 더 높은 경합이 발생하는 곳에서 35 (및 그 이상)
노트: 필요에 따라, .Net ThreadPool 설정은 조정될 수 있습니다.
지금까지 기본값은 각 버전마다 다를 수 있지만 좋은 결과를 얻었습니다.
경쟁 조건 및 기타 멀티스레딩 문제를 방지하려면 어떻게 해야 하나요?
Photon에서는 가능한 한 모든 것을 단순화했습니다.
- 모든 스레드에서 PhotonPeer 메서드를 사용할 수 있습니다.
- PhotonPeer의 모든 알림은 하나의 파이버에서 실행됩니다(아래 파이버에 대한 내용을 읽어보세요).
- 한 방의 모든 작업은 하나의 파이버에서 실행됩니다.
- 피어는 멀티스레딩 문제로부터 데이터를 보호하기 위해 룸의 파이버로 메시지를 보냅니다.
파이버는 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