我开始学习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();
}