Akka 2.6 Actor Discovery In A Non-Actor Class(在 ActorSystem 之外获取 ActorRef)
Akka 2.6 Actor Discovery In A Non-Actor Class (Get ActorRef Outside ActorSystem)
目前我正在使用 Akka,我有以下协议。
在我的协议中,我有一个服务器只负责创建资源(房间和 gabbler)。创建并访问这些资源。接下来,我想通过一个键找到相应的 Gabbler ActorRef 来发送消息,但这次是从 class 公开一个 API / 不是演员的方法。我看过文档,令我难以置信的是,actor 系统中没有一种方法可以 return 其层次结构中的特定 actor 来使用它。我已经阅读了接待员部分,虽然我不是很清楚,但我看到它再次面向演员。 Akka 中没有方法 returns 引用基于 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");
}
}
上图中的协议已经实现,但我仍然无法理解上面的问题。
一般来说,要从 actor 获取数据到 actor 系统外部(例如 main
方法),您需要处理 ask pattern。使用询问模式时,您需要设计消息协议以支持它,通常是让要询问的消息具有 ActorRef<ReplyMsg>
字段(通常命名为 replyTo
)。 akka.actor.typed.javadsl.AskPattern.ask
有效地创建了一个短暂的 actor,将该 actor 的 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()
目前我正在使用 Akka,我有以下协议。
在我的协议中,我有一个服务器只负责创建资源(房间和 gabbler)。创建并访问这些资源。接下来,我想通过一个键找到相应的 Gabbler ActorRef 来发送消息,但这次是从 class 公开一个 API / 不是演员的方法。我看过文档,令我难以置信的是,actor 系统中没有一种方法可以 return 其层次结构中的特定 actor 来使用它。我已经阅读了接待员部分,虽然我不是很清楚,但我看到它再次面向演员。 Akka 中没有方法 returns 引用基于 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");
}
}
上图中的协议已经实现,但我仍然无法理解上面的问题。
一般来说,要从 actor 获取数据到 actor 系统外部(例如 main
方法),您需要处理 ask pattern。使用询问模式时,您需要设计消息协议以支持它,通常是让要询问的消息具有 ActorRef<ReplyMsg>
字段(通常命名为 replyTo
)。 akka.actor.typed.javadsl.AskPattern.ask
有效地创建了一个短暂的 actor,将该 actor 的 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()