如何在Akka演员之间传递远程引用?

时间:2014-02-17 14:51:03

标签: java scala akka

我有三个远程Akka演员:A,B和C. A向B发送消息,B保存A的参考(见下文)。另外,我需要B将A的引用发送给C.我怎么能这样做? B的Java代码如下所示:

public class B extends UntypedActor {
    //---------------------------------------------------------------
    /**
     * {@inheritDoc}
     */
    @Override
    public void onReceive(Object object) throws Exception {
        if (refA == null) {
            refA = getSender();
        }

        // how do I send refA to C???
        refC.tell(refA, getSelf()); // <== like this?
    }

    // set during onReceive
    private ActorRef refA = null;

    // initialized in constructor
    private final ActorRef refC;
}

我刚检查过,ActorRefSerializable所以从理论上讲我上面提出的解决方案应该有效,但是有不同/官方/更清洁的方法吗?

2 个答案:

答案 0 :(得分:4)

您的解决方案看起来很好,并且是常见的事情。 Akka参考设计为位置透明和可序列化。因此,您可以将Actor引用发送到远程客户端,他们只需使用它们而无需任何其他设置。

答案 1 :(得分:2)

如果actor C只需要对actor A有引用,你只需要用tell方法将Actor B中的行更改为:

refC.tell(refA, getSender()); 

如果演员C必须同时引用演员A和演员B,那么你可以做两件事:

1)使用您提供的代码。

2)在Actor C中使用方法 getContext()。actorSelection(&#34; actor_name&#34;)来获取Actor A.如何在{{3中描述] actorSelection的工作方式但它看起来如下:

public class ActorC extends UntypedActor {
    private static String ID="whateverID";
    private ActorRef actorA;
    {
      getContext().actorSelection("akka.tcp://app@host:port/user/actorAName").
      tell(new Identify(ID), getSelf());
    }
    //As an alternative, if you need the ActorA initialized in the constructor,
    //you can use the .resolveOne method.
    //public ActorC(){
    //    super();
    //    Timeout timeout=new Timeout(4, TimeUnit.SECONDS);
    //      try {
    //          httpProducer=Await.result(getContext().actorSelection("akka.tcp://app@host:port/user/actorAName").resolveOne(timeout), timeout.duration());
    //      } catch (Exception e) {
    //      Logger.error("Error fetching the routerHTTProducer");
    //      }
    //}
    @Override
    public void onReceive(Object m) throws Exception {
        if (m instanceof ActorIdentity) {
            ActorIdentity identity = (ActorIdentity) m;
            if (identity.correlationId().equals(ID) && identity.getRef() != null) {
                actorA= identity.getRef();
            }           
        }
        //else if (m instanceof ...){}  
    }
}