캐시된 이벤트들

Photon 이벤트들은 게임 로직의 핵심 역할을 하고 있고 플레이어들은 룸에서 서로 소통을 합니다. 클라이언트들은 룸에서 한 명 이상의 플레이어에게 데이터를 전송하기 위해 OpRaiseEvent를 호출 합니다. 참여한 모든 플레이어들은 이러한 이벤트를 즉시 받을 수 있습니다. 그러나 늦게 참여한 플레이어들은 캐싱 옵션을 사용하지 않으면 이러한 이벤트를 수신 할 수 없게 됩니다.

이벤트를 캐시 할 때 Photon 서버는 룸 상태를 저장하여 나중에 참여한 플레이어들도 사용할 수 있도록 보관 합니다. Photon 서버는 "현재발생하고있는" 이벤트를 전송하기 전에 참여한 플레이어에게 저장된 룸 상태를 우선 전송합니다.

유즈 케이스 1: 데이터로 경기의 시작 시간을 포함하는 "시작시간" 이벤트를 캐시 할 수 있습니다. 이 방식으로 게임에 참여하는 모두가 언제 게임이 시작되었는지 알 수 있습니다. (아마도 언제 끝날지 알 수 있을것입니다.)

순차적인 전송이 보장됩니다

참여하고 있는 플레이어들은 서버에 도착한 순서와 동일한 순서로 캐시된 이벤트를 얻을 수 있습니다. 클라이언트는 우선 룸과 플레이어 프로퍼티를 읽은 후(이로 인해서 모든 플레이어를 알 수 있습니다) 캐시된 이벤트들을 수신 합니다. 참여한 이후 발생된 모든 이벤트들은 이후에 수신 됩니다. 이벤트들이 송신 순서와 동일한 순서로 캐시된 이벤트를 수신 받는 다고 판단 할 수 있습니다. 예외는 UDP 가 사용되고 비신뢰로 전송되었을 때만 입니다.

어떻게 이벤트들이 캐시되는지에 대한 이해

여기에서는 어떻게 이벤트가 캐시되는지에 대해서 파악해야 하는 부분만 설명 하며 상세하게 다루지는 않습니다:
각각의 캐시된 이벤트는 전송자의 데이터와 액터 번호의 코드에 의해 정의됩니다.

이벤트 캐시는 두 개의 "논리적인 파티션"으로 그룹핑 될 수 있습니다: - "글로벌 캐시": 룸에 연견된 캐시(ActorNr == 0). EventCaching.AddToRoomCacheGlobal 와 같이 전송된 캐시되고 명시적으로 제거되지 않은 전체 이벤트를 포함하고 있습니다. 이러한 캐시된 이벤트들은 원시 전송자에 의해 더 이상 추적되지는 않습니다. 모든 참여하고 있는 액터에게 전송되어지는 이벤트 들이기 때문입니다. - "액터 캐시": 특정한 액터 번호(ActorNr != 0)에 관련된 캐시 입니다. 액터에 의해 전송되고 글로벌 캐시에 추가되지 않았거나 캐시에서 제거 되지 않은 모든 캐시된 이벤트들이 포함 됩니다. 이러한 이벤트들은 원시 전송자를 제외한 참여하고 있는 모든 액터에게 전송됩니다.

이벤트 캐시의 통제

LoadBalancing API와 PUN 에서 사용자들은 모든 OpRaiseEvent 호출에 RaiseEventOptions 객체를 전달 할 필요가 있습니다. 이 파라미터는 CachingOption 프로퍼티를 포함하고 있습니다. EventCaching 값이 이벤트 캐시에 어떻게 영향을 주는지 살펴보도록 하겠습니다:

  • DoNotCache: 디폴트 값입니다. 전송되는 이벤트가 룸의 캐시에 추가되지 않도록 합니다.
  • AddToRoomCache: 전송 액터의 룸 캐시에 추가됩니다. 전송 액터 번호로 표기 되어 있습니다.
  • AddToRoomCacheGlobal: 전송된 이벤트가 "글로벌 캐시"에 추가됩니다. 이 값을 사용할 때는 코드에서 명시적으로 제거 요청을 해야 만이 제거가 되므로 사용에 주의 하셔야 합니다. 명시적으로 제거해 주지 않으면 룸과 동일한 생명주기를 가지게 됩니다.
  • RemoveFromRoomCache: 이전에 캐시된 이벤트들이 지정한 "필터 패턴"에 매칭되면 캐시에서 제거 됩니다. "필터 패턴"은 3개 파라미터의 조합 입니다:이벤트 코드, 전송자 번호와 이벤트 데이터 입니다. 하나 또는 두개 또는 세가지 모두를 이용 할 수 있습니다.
    • 이벤트 코드가 0 이면 모든 이벤트를 나타내는 와일드 카드가 됩니다.
    • 전송자 번호는 0 이 될 수 있으며 "글로벌 캐시" 에서 캐시를 제거하라는 의미입니다.
    • 이벤트 데이터로 필터를 하게 되면 데이터 일부분만 전송해도 됩니다. 예를 들어 이벤트 데이터로 Hashtable을 이용하고 있으면 하나 이상의 키/값 쌍을 지정하여 이벤트를 삭제 할 수 있습니다.
  • RemoveFromRoomCacheForActorsLeft: 제거된 액터로 부터 전송 되었던 캐시된 이벤트들이 제거 됩니다. 룸 생성시의 디폴트 값인 RoomOptions.CleanupCacheOnLeave 을 true 로 설정하여 생성하는 것과 차이가 없습니다.
다음의 조건이 하나라도 맞게 된다면 이벤트들은 캐시에 추가되지 않을 것 입니다:
  • RaiseEventOptions.Receivers == ReceiverGroups.MasterClient.
  • RaiseEventOptions.TargetActors != null.
  • RaiseEventOptions.InterestGroups != 0.

유즈 케이스 2: 이벤트 내용으로 Hashtable 을 사용하고 있으면 모든 이벤트들에 대해서 특정 객체에 속한다고 "oid" 키("ObjectID"을 줄임말)와 몇개의 값으로 표시 할 수 있습니다. 특정 객체에 관련된 캐시를 없애고 싶을 때 EventCaching.RemoveFromRoomCache 에 이벤트 데이터 필터로써 Hashtable(){"oid", <objectId>} 를 전송 할 수 있습니다.

캐시 없애기

플레이어가 게임을 종료 할 때 일반적으로 플레이어의 액션들은 신규 플레이어에게는 더 이상 관련이 없습니다. 참여시 혼잡을 피하기 위하여 Photon 서버는 룸을 영원히 떠난 플레이어에 의해 캐시된 이벤트를 자동으로 없애는 것이 기본으로 설정되어 있습니다.

룸의 이벤트 캐시를 수동으로 없애고 싶다면 RoomOptions.CleanupCacheOnLeave 를 false 로 룸을 생성 하면 됩니다.

특별한 생각

  • 캐시된 이벤트에 의해 "현재발생되고 있는" 모든 것이 지연되게 되면 발생된 모든 것을 캐시 하지 않도록 고려 해봐야 합니다.

  • Photon 에서 캐시 된 이벤트 개수를 제한하고 있지는 않으나, 클라이언트 구현에 대한 최악의 시나리오를 고려 해주셔야 합니다.

 기술문서 TOP으로 돌아가기