"ActorRef.tell" 方法的第二个参数是什么?

What is the second argument of the "ActorRef.tell" method?

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

没看懂tell方法第二个参数的用法:

在main方法中写的:

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

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

actor 端的入口点如下所示:

@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

,您还可以看到此 actor 向另一个 actor 发送了消息
printerActor.tell(new Greeting(greeting), getSelf());

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

打印机演员入口点如下所示:

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

因此它只打印提供的消息

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

Here second argument is getSelf() but I tried to change it with ActorRef.noSender() and behaviour was not changed.

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

的第二个参数

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

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();
}

然后更改 greeter actor 以处理 PrinterAck 消息(显然您需要定义 PrinterAck class):

@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();
}