如何解决Akka 2.6 在非 Actor 类中发现 Actor在 ActorSystem 之外获取 ActorRef
我正在与 Akka 合作,目前我有以下协议。
在我的协议中,我有一个服务器,它只负责创建资源(房间和 gabblers)。这些资源被创建,然后被访问。接下来,我想通过一个键来找到相应的 Gabbler ActorRef 来发送消息,但这一次是从一个公开了 API / 方法的类中发送的,而该类不是一个演员。我看过文档,令我难以置信的是,演员系统中没有一种方法可以从其层次结构中返回特定演员以使用它。我已经阅读了接待员部分,虽然我不太清楚,但我看到它再次面向演员。 Akka中没有根据Actor的路径返回引用的方法吗?
package co.test;
import akka.actor.typed.ActorSystem;
import akka.actor.typed.javadsl.AskPattern;
import akka.actor.typed.receptionist.Receptionist;
import co.test.actors.ChatServer;
public class ChatServerApplication {
public static void main(String[] args) {
ActorSystem<ChatServer.ServerCommand> system =
ActorSystem.create(ChatServer.create(),"chat-server");
system.tell(new ChatServer.NewEventRoom("room1"));
system.tell(new ChatServer.AttendeeJoin("room1","user1"));
system.tell(new ChatServer.AttendeeJoin("room1","user2"));
system.tell(new ChatServer.AttendeeJoin("room1","user3"));
system.tell(new ChatServer.AttendeeJoin("room1","user4"));
system.tell(new ChatServer.AttendeeJoin("room1","user5"));
system.tell(new ChatServer.AttendeeJoin("room1","user6"));
system.tell(new ChatServer.AttendeeJoin("room1","user7"));
//ActorRef<Gabbler.Command> gabbler = get specific Gabbler ActorRef
//gabbler.tell(new Gabbler.SendMessage("test");
}
}
上图中的协议已经实现,但我无法理解上面的要求。
解决方法
一般来说,为了从演员到演员系统外部(例如 main
方法)获取数据,您需要处理 ask pattern。使用询问模式时,您需要设计您的消息协议来支持它,通常是通过让旨在被询问的消息具有 ActorRef<ReplyMsg>
字段(通常命名为 replyTo
)。 akka.actor.typed.javadsl.AskPattern.ask
有效地创建了一个短期角色,将那个角色的 ActorRef
注入到消息中,如果它在超时时间内收到一条消息,它会用该消息完成一个 CompletionStage
。
在此应用程序中,由于您要路由从 main
到 system
演员的所有内容,因此您可以定义 ChatServer.GetAttendee
消息:
// assuming that there's an interface Command {} already in ChatServer
public class ChatServer extends AbstractBehavior<ChatServer.Command> {
public static class GetAttendee extends Command {
public final String room;
public final String user;
public final ActorRef<ChatServer.AttendeeIs> replyTo;
public GetAttendee(String room,String user,ActorRef<ChatServer.AttendeeIs> replyTo) {
this.room = room;
this.user = user;
this.replyTo = replyTo;
}
}
public static class AttendeeIs {
public final ActorRef<Gabbler.Command> ref
public AttendeeIs(ActorRef<Gabbler.Command> ref) {
this.ref = ref;
}
}
}
(ChatServer
可能会在相应的 ChatRoom
上传递消息)
在您的 main
中,您可以发送类似内容的询问
String desiredRoom = "whatever";
String desiredUser = "whoever";
CompletionStage<ChatServer.AttendeeIs> getGabbler =
AskPattern.ask(
system,replyTo -> new ChatServer.GetAttendee(desiredRoom,desiredUser,replyTo),Duration.ofSeconds(15),system.scheduler()
)
CompletionStage<ActorRef<Gabbler.Command>> gabblerFuture =
getGabbler.thenCompose(
(ChatServer.AttendeeIs response) ->
return CompletableFuture.completedFuture(response.ref)
)
ActorRef<Gabbler.Command> gabbler = gabblerFuture.toCompletableFuture().get()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。