Akka 经典 - 发送自定义类消息类型
Posted
技术标签:
【中文标题】Akka 经典 - 发送自定义类消息类型【英文标题】:Akka classic - sending custom class message types 【发布时间】:2021-08-15 18:19:08 【问题描述】:我正在尝试遵循在 Akka Actor 之间发送消息并阅读以下内容的最佳实践:
https://github.com/akka/akka/blob/v2.6.15/akka-docs/src/test/java/jdocs/actor/ActorDocTest.java#L101-L129
https://doc.akka.io/docs/akka/current/actors.html
似乎最好的做法是定义一个包含要发送的消息的静态类。
通过阅读文档,我定义了以下内容:
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.persistence.AbstractPersistentActor;
class RecoveryActor extends AbstractPersistentActor
public static class Msg1
public static class Msg2
private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
/**
* Handler that will be called on recovery.
* @return
*/
@Override
public Receive createReceiveRecover()
return receiveBuilder()
.match(Msg1.class, this::receiveMsg1)
.match(Msg2.class, this::receiveMsg2)
.build();
private void receiveMsg1(Msg1 msg)
log.info("in receive message 1");
private void receiveMsg2(Msg2 msg)
log.info("in receive message 2");
/**
* The normal receive method.
* @return
*/
@Override
public Receive createReceive()
return receiveBuilder()
.match(String.class, s -> s.equals("cmd"), s -> persist("evt", this::handleEvent))
.build();
private void handleEvent(String event)
System.out.println("in handle event");
@Override
public String persistenceId()
return "simple-accountant"; //best practice, the id should be unique.
但我不确定如何使用Msg1
和Msg2
发送消息
我已经定义了一个新类来发送消息:
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
public class ActorMessaging
public static void main(String args[])
final ActorSystem system = ActorSystem.create("example");
final ActorRef actor = system.actorOf(Props.create(RecoveryActor.class));
actor.tell(RecoveryActor.Msg1);
但编译器错误失败:
java: cannot find symbol
symbol: variable Msg1
location: class recoverydemo.RecoveryActor
如何向Msg1
类型的 Actor 发送消息?
这是在参与者之间发送消息并将消息包装在自定义类中的最佳做法吗?
【问题讨论】:
【参考方案1】:actor.tell
正在接受对象。 RecoveryActor.Msg1
不是那个,它甚至不是类引用。尝试像这样发送Msg1
的实例怎么样:
actor.tell(new RecoveryActor.Msg1(), actorRef)
为了与远程actor“交谈”,您首先需要获取对它的引用。这通常由ActorSystem 完成
【讨论】:
谢谢,但是编译失败,编译错误是:'akka.actor.ActorRef'中的''tell(java.lang.Object, akka.actor.ActorRef)'不能应用于'( recoverydemo.RecoveryActor.Msg1)' 。我添加了发件人:'actor.tell(new RecoveryActor.Msg1() , actor);'但未收到消息,并且将以下内容输出到日志:'[example-akka.actor.default-dispatcher-7] - 来自 Actor[akka://example/user/$a 的消息 [recoverydemo.RecoveryActor$Msg1] #901889227] 到 Actor[akka://example/user/$a#901889227] 未处理。 [1] 遇到死信。'【参考方案2】:我犯了一个愚蠢的错误。我覆盖了不正确的方法。我应该改写createReceive
:
public Receive createReceive()
return receiveBuilder()
.match(RecoveryActor.Msg1.class, this::receiveMsg1)
.match(Msg2.class, this::receiveMsg2)
.build();
// return receiveBuilder()
// .match(String.class, s -> s.equals("cmd"), s -> persist("evt", this::handleEvent))
// .build();
【讨论】:
以上是关于Akka 经典 - 发送自定义类消息类型的主要内容,如果未能解决你的问题,请参考以下文章