[Akka.NET] 액터 메시지 받기

소개

오늘은 Akka.NET에서 액터 메시지 받는 방법에 대해서 알려 드리려고 합니다.

앞서, Tell, Sender.Tell 등과 함께 액터끼리 메시지를 전달하는 방법에 대해서 알아 보았습니다.

메시지를 주었으면, 메시지를 받은 액터는 받고 나서 어떤 행동을 해야할지? 결정하는 이벤트 핸들러가 필요한데요.

바로 Receive 를 이용하여 메시지를 받고 특정 이벤트 핸들러를 실행할 수 있습니다.

예제 코드를 통해서 어떻게 메시지를 받고 또 받고나서 어떤 행동을 처리하는지 보여 드리도록 하겠습니다.


예제 코드

  • 아래 예제 코드와 같이, Receive<T> 를 이용하여 액터에서 보낸 메시지를 받아서 이벤트 핸들러까지 실행할 수 있습니다.
  • 현재 아래에서는 액터에서 메시지를 받으면, 해당 메지지 타압에 맞는 Handler 가 실행 되면서 메시지 내용이 출력되는 로직입니다.
using Akka.Actor;
using System;
using System.Threading;

namespace interfaceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //액터 시스템 생성
            ActorSystem actorSystem = ActorSystem.Create("actorSystem");

            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Main : 프로그램 시작");

            //RootActor1 액터 생성
            IActorRef rootActor1 = actorSystem.ActorOf(
                ExampleRootActor1.Props(),
                ActorPaths.RootActor1.Name
                );

            // RootActor1 메시지 전달하기
            rootActor1.Tell(2021); // int 형 메시지
            rootActor1.Tell("메시지 보낸다.");
            rootActor1.Tell("메시지 받은 대로 출력해라.");

            //액터 시스템 종료 대기
            actorSystem.WhenTerminated.Wait();
        }
    }

    public class ExampleRootActor1 : ReceiveActor
    {
        //팩토리 함수를 이용한 Actor 생성 방법
        public static Props Props()
        {
            return Akka.Actor.Props.Create(() => new ExampleRootActor1());
        }

        public ExampleRootActor1()
        {
            Receive<int>(value => Handle(value));

            //모든 메시지(object 타입)를 처리할 ReceiveAny 함수는
            //반드시 메시지 처리 우선순위 때문에 마지막 함수로 호출해야 한다.
            //
            //void ReceivAny(
            // Action<object> handler);
            //ReceiveAny 함수는 결국 Receive<object>와 같다.
            //
            ReceiveAny(value => Handle(value));
        }

        private void Handle(int value)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} {ActorPaths.RootActor1.Name} <int> : {value}");
        }

        private void Handle(object value)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} {ActorPaths.RootActor1.Name} <object> : {value}");
        }
    }

    public class ActorMetaData
    {
        public ActorMetaData(string name, ActorMetaData parent = null)
        {
            Name = name;
            Parent = parent;
            // if no parent, we assume a top-level actor
            var parentPath = parent != null ? parent.Path : "/user";
            Path = string.Format("{0}/{1}", parentPath, Name);
        }

        public string Name { get; private set; }

        public ActorMetaData Parent { get; set; }

        public string Path { get; private set; }
    }

    public static class ActorPaths
    {
        public static readonly ActorMetaData RootActor1 = new ActorMetaData("ExampleRootActor1");
        public static readonly ActorMetaData ChildActor1 = new ActorMetaData("childActor");
    }
}

실행 결과

1 Main : 프로그램 시작
17 ExampleRootActor1 <int> : 2021
17 ExampleRootActor1 <object> : 메시지 보낸다.
17 ExampleRootActor1 <object> : 메시지 받은 대로 출력해라.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY