简体   繁体   English

Akka 2.6 Actor Discovery In A Non-Actor Class (Get ActorRef Outside ActorSystem)

[英]Akka 2.6 Actor Discovery In A Non-Actor Class (Get ActorRef Outside ActorSystem)

I am working with Akka at the moment I have the following protocol.目前我正在使用 Akka,我有以下协议。

在此处输入图像描述

In my protocol I have a server that is only responsible for creating resources (room and gabblers).在我的协议中,我有一个服务器只负责创建资源(房间和 gabbler)。 These resources are created and then accessed.创建并访问这些资源。 Next, I would like by means of a key to find the corresponding Gabbler ActorRef to send a message but this time from a class that exposes an API / method that is not an actor.接下来,我想通过一个键找到相应的 Gabbler ActorRef 来发送消息,但这次来自 class,它公开了一个不是演员的 API / 方法。 I have seen the documentation and it is incredible to me that there is not a method in the actor system that can return a specific actor from its hierarchy to use it.我看过文档,令我难以置信的是,actor 系统中没有一种方法可以从其层次结构中返回特定的 actor 以使用它。 I have already read the Receptionist section and although it is not very clear to me, I see that it is again oriented to the actors.我已经阅读了接待员部分,虽然我不是很清楚,但我看到它再次面向演员。 There is no method in Akka that returns the reference based on the path of the Actor? 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");
    }
    
}

The protocol in the image above is already implemented but I am stuck in understanding what was asked above.上图中的协议已经实现,但我仍然无法理解上面的问题。

In general, for getting data from actors to outside of the actor system (eg the main method), you're dealing with the ask pattern .通常,为了从参与者获取数据到参与者系统之外(例如main方法),您需要处理ask 模式 When using the ask pattern, you'll need to design your message protocol to support it, typically by having messages that are intended to be asked having an ActorRef<ReplyMsg> field (often named replyTo ).使用询问模式时,您需要设计消息协议来支持它,通常是让旨在询问的消息具有ActorRef<ReplyMsg>字段(通常名为replyTo )。 akka.actor.typed.javadsl.AskPattern.ask effectively creates a short-lived actor, injects the ActorRef of that actor into the message, and if it gets a message within a timeout period, it completes a CompletionStage with that message. akka.actor.typed.javadsl.AskPattern.ask有效地创建了一个短暂的 actor,将该 actor 的ActorRef注入到消息中,如果它在超时期限内收到消息,它会使用该消息CompletionStage

In this application, since you're routing everything from main through the system actor, you could define a ChatServer.GetAttendee message:在此应用程序中,由于您要路由从mainsystem actor 的所有内容,因此您可以定义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 would likely pass the message on the corresponding ChatRoom ) ChatServer可能会在相应的ChatRoom上传递消息)

In your main , you would send the ask with something like在你的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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM