메시지 중개자(MessageBroker)
'메시지 중개자'(MessageBroker)를 이용하면 게임 내 이벤트 처리를 메시지를 이용하는 방법으로 처리할 수 있습니다. 이렇게 처리하는 것의 장점은 이벤트 처리를 직접 메소드를 호출하는 방법이 아니라 메시지를 이용해서 처리하기 때문에 컴포턴트간 불필요한 의존관계를 줄일 수 있는 것이 큰 장점입니다.
UniRx에서 지원하는 '메시지 중개자'는 다음의 두 가지가 있습니다.
- MessageBroker
- AsyncMessageBroker
MessageBroker
MessageBroker는 메모리 내에서 메시지를 발행하고 처리할 수 있는 PubSub입니다.
PubSub는 Publish/Subscribe를 줄여서 부르는 말입니다.
MessageBroker를 사용해서 발행하는 메시지는 사용자가 정의하는 클래스를 이용합니다.
public class MyMessage
{
public int Value { get; set; }
}
MessageBroker를 사용하는 경우에는 Receive
연산자를 이용해서 어떤 메시지를 처리할 것인지 지정합니다.
MessageBroker. Default . Receive < MyMessage > ( )
. Subscribe ( x => UnityEngine. Debug . Log ( x ) ) ;
이제 MessageBroker는 MyMessage
타입의 이벤트가 도착하면 Subscribe를 통해서 Unity 에디터의 콘솔 로그창에 이를 출력하게 됩니다.
이제 프로그램 내 메시지의 발행이 필요한 곳에서 메시지를 발행하면 됩니다. 메시지의 발행은 Publish
연산자를 사용합니다.
MessageBroker. Default . Publish ( new MyMessage { Value = 1000 } ) ;
MessageBroker를 이용해서 게임 내 이벤트를 처리하는 방법은 아래와 같이 요약할 수 있습니다.
- 메시지에 사용할 클래스를 정의.
- MessageBroker.Receive 메소드로 생성한 관찰대상자의 Subscribe 메소드에 메시지를 받은 경우에 대해서 처리.
- 이벤트 처리를 위해 메시지의 발행이 필요한 곳에서 MessageBroker.Publish 메소드로 메시지를 발행.
AsyncMessageBroker
AsyncMessageBroker와 MessageBroker의 차이점은 AsyncMessageBroker는 메시지를 구독하는 대상들이 발행한 메시지를 모두 처리한 시점을 알 수 있다는 점입니다. 물론 이 시점에서 처리할 작업 있는 경우 처리하는 것도 당연히 가능합니다.
메시지를 발행하는 메소드의 리턴형에서도 차이점을 알 수 있습니다. MessageBroker의 Publish 메소드의 리턴형은 void이고 AsyncMessageBroker의 PublishAsync 메소드의 리턴형은 IObservable<> 입니다.
public void Publish<T>(T message) // MessageBroker
public IObservable<Unit> PublishAsync<T>(T message) // AsyncMessageBroker
PublishAsync의 리턴형이 IObservable<> 형이기 때문에 Subscribe가 가능하고 Subscribe의 스트림 처리는 메시지를 받는 객체들의 Subscribe 처리가 완료된 후 호출됩니다.
// AsyncMessageBroker is variation of MessageBroker, can await Publish call.
AsyncMessageBroker. Default . Subscribe < MyMessage > ( x =>
{
// show after 3 seconds.
return Observable. Timer ( TimeSpan. FromSeconds ( 3 ) )
. ForEachAsync ( _ =>
{
UnityEngine. Debug . Log ( x ) ;
} ) ;
} ) ;
AsyncMessageBroker이 메시지 발생은 PublishAsync
연산자를 사용합니다.
AsyncMessageBroker. Default . PublishAsync ( new MyMessage { Value = 3000 } )
. Subscribe ( _ =>
{
// 메시지를 구독하는 모든 관찰자들의 처리를 완료한 후 로그를 출력.
UnityEngine. Debug . Log ( "called all subscriber completed" ) ;
} ) ;