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

gst*_*low 1 java actor akka

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

我不明白tell方法第二个参数的用法:

在主要方法中写:

howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
Run Code Online (Sandbox Code Playgroud)

因此第二个论点是 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
      })
Run Code Online (Sandbox Code Playgroud)

因此我无法访问传递的引用。

此外,您可以看到,如果消息类型为 Greet.class

printerActor.tell(new Greeting(greeting), getSelf());
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Jef*_*ung 5

printerActor.tell(new Greeting(greeting), getSelf());
Run Code Online (Sandbox Code Playgroud)

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

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

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

printerActor.tell(new Greeting(greeting), ActorRef.noSender());
Run Code Online (Sandbox Code Playgroud)

如果您想查看如何使用发送方引用,您可以更改打印机参与者的行为:

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

然后更改欢迎角色以处理PrinterAck消息(显然您需要定义一个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();
}
Run Code Online (Sandbox Code Playgroud)