Akka 2.6非演员类中的演员发现(获取ActorRef外部ActorSystem)

ve7v8dk2  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(184)

我正在和 akka 合作,目前我有以下协议。

在我的协议中,我有一个服务器,它只负责创建资源这些资源被创建然后被访问。接下来,我希望通过一个键来找到相应的Gabbler ActorRef以发送一个消息,但这次是从一个公开API /方法的类中发送的,而这个API /方法不是一个参与者。我已经看过文档,我很难相信在actor系统中没有一个方法可以从它的层次结构中返回一个特定的actor来使用它。我已经读过Receponist部分,虽然我不是很清楚,我看到它再次面向演员。Akka中没有方法基于演员的路径返回引用吗?

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");
    }

}

上图中的协议已经实现,但我仍然无法理解上面的问题。

nlejzf6q

nlejzf6q1#

通常,为了从参与者到参与者系统外部获取数据(例如,main方法),您将处理ask模式。当使用ask模式时,您需要设计消息协议来支持它,典型地通过使打算被询问的消息具有ActorRef<ReplyMsg>字段akka.actor.typed.javadsl.AskPattern.ask实际上创建了一个短期执行元,将该执行元的ActorRef注入到消息中,如果它在超时时间段内获得消息,则使用该消息完成一个CompletionStage
在此应用程序中,由于要通过system执行元路由来自main的所有内容,因此可以定义一个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;
    }
  }
}

(the 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()

相关问题