我开始学习Akka,并从official guid下载了示例:

我不理解tell方法第二个参数的用法:

在写的主要方法中:

howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());


因此,第二个参数是ActorRef.noSender()

在演员侧入口点上看起来像这样:

@Override
public Receive createReceive() {
  return receiveBuilder()
      .match(WhoToGreet.class, wtg -> {
        this.greeting = message + ", " + wtg.who;
      })
      .match(Greet.class, x -> {
        //#greeter-send-message
        printerActor.tell(new Greeting(greeting), getSelf());
        //#greeter-send-message
      })


因此,我无法访问传递的参考。

此外,您可以看到该参与者在消息类型为Greet.class的情况下向其他参与者发送了消息

printerActor.tell(new Greeting(greeting), getSelf());


这里的第二个参数是getSelf(),但是我尝试用ActorRef.noSender()更改它,并且行为没有改变。

打印机actor入口点如下所示:

@Override
public Receive createReceive() {
  return receiveBuilder()
      .match(Greeting.class, greeting -> {
          log.info(greeting.message);
      })
      .build();
}


因此,它只是打印提供的消息

最佳答案

printerActor.tell(new Greeting(greeting), getSelf());

  
  这里的第二个参数是getSelf(),但是我尝试用ActorRef.noSender()更改它,并且行为没有改变。


tell()方法的第二个参数是发送方引用,接收方参与者可以向其发送回复。换句话说,如果演员A使用getSelf()作为tell()调用的第二个参数向演员B发送消息,则演员B可以使用getSender()获取对演员A的引用。当接收方参与者不需要引用发送方时,第二个参数是合适的。请注意,您可以使用任何ActorRef.noSender()作为ActorRef的第二个参数。

快速入门指南中的打印机参与者在收到tell()消息时不会调用getSender()。打印机参与者收到Greeting消息时唯一要做的就是记录问候语。在这种情况下,对于问候演员,使用Greeting而不是ActorRef.noSender()更为有意义(但是,在这种情况下,由于打印机演员没有调用getSelf(),这没有什么区别):

printerActor.tell(new Greeting(greeting), ActorRef.noSender());


如果要查看如何使用发件人引用,则可以更改打印机参与者的行为:

@Override
public Receive createReceive() {
  return receiveBuilder()
    .match(Greeting.class, greeting -> {
      log.info(greeting.message);
      getSender().tell(new PrinterAck(), ActorRef.noSender());
  })
  .build();
}


然后更改问候者actor以处理getSender()消息(显然,您需要定义PrinterAck类):

@Override
public Receive createReceive() {
  return receiveBuilder()
    .match(WhoToGreet.class, wtg -> {
      this.greeting = message + ", " + wtg.who;
    })
    .match(Greet.class, x -> {
      printerActor.tell(new Greeting(greeting), getSelf());
    })
    .match(PrinterAck.class, x -> {
      log.info("Received an ack from the printer actor.");
    })
    .build();
}

09-16 06:41