gpt4 book ai didi

java - 该实例的 Akka Actor 路径

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:39:10 27 4
gpt4 key购买 nike

我正在使用 Java Play 框架。我正在使用网络套接字进行客户端服务器交互。在服务器端,我们有响应客户端请求的又名参与者。我面临的问题:我想,当客户端打开与服务器上的 Hakka actor 的 web 套接字连接时,它实际上为该 actor 打开一个池,然后我需要跟踪该实例的 actor 客户端路径,以便每当其他操作发生时放置在其他某个类中,该类通知此参与者(使用被跟踪的实例路径)操作已发生,然后此参与者通知用户(客户端)此操作已发生。我实际上正在使用

String ClientPushActorPath = akka.serialization.Serialization.serializedActorPath(self());

以上是为了获取客户端用户实例的路径。但是下次当我尝试使用这条路径攻击这个 Actor 时,我找不到这个 Actor 。我试图从另一个 Actor 那里攻击 Actor 的方式是:

PushCacheManager cache = PushCacheManager.getInstance();
cache.load(qiid);
String ActorPath = cache.get("ClientPushActorPath");
ActorSelection ClientPushActor = system.actorSelection(ActorPath);
ClientPushActor.tell(m4, getSelf());

所以上面的代码简单地说,首先我去从缓存中获取 scots 路径(它被缓存在内存中以备将来使用)然后我尝试将该路径传递给 Actor 选择。一旦我获得了 Actor 的对象选择我用它来告诉其他 Actor 我需要传递的消息是 m4。请纠正我哪里出错了。我无法看到使用此路径的 Actor 。我觉得,我跟踪路径的方式是错误的。请纠正我。比

最佳答案

请耐心等待,这需要一些时间来完成,但它应该让您知道该怎么做。注意:我假设您仍在使用 Play 2.4.x 并且尚未更新到 Play 2.5.x。并且您使用 Java(尽管如果您能够切换,我会推荐 Akka Scala API)。


第 1 步:定义处理 WebSocket 连接的 actor

在你的 Controller 中你会这样写:

public static WebSocket<String> socket() {
return WebSocket.withActor(MyWebSocketActor::props);
}

这意味着每个 WebSocket 连接都将由 MyWebSocketActor 类型的 actor 实例处理。然后,您将必须像这样实现 Actor :

import akka.actor.*;

public class MyWebSocketActor extends UntypedActor {

public static Props props(ActorRef out) {
return Props.create(MyWebSocketActor.class, out);
}

private final ActorRef out;

public MyWebSocketActor(ActorRef out) {
this.out = out;
}

public void onReceive(Object message) throws Exception {
if (message instanceof String) {
out.tell("I received your message: " + message, self());
}
}
}

您看到的 ActorRef out 参数实际上是底层 actor(从 Play 生成)。你不需要对它做任何事情,只要记住一旦你向这个 out actor 发送了一些东西,他就会将它处理给客户端。

您还必须在 routes 文件中定义正确的路由:

GET/ws controllers.Application.socket()

第 2 步:定义如何管理所有 WebSocket 参与者

一般来说,您有两种选择——要么“查找”上面创建的参与者,要么提供某种机制来管理它们(某种注册表)

  • 第 2.1 步:查找 WebSocket 参与者

    这里的优点是您不需要额外的注册表/管理器或类似的东西。缺点是很难知道哪个 actor 服务于哪个 WebSocket 连接。

    为此您可以使用 actorSelection:

    system.actorSelection("system/websockets/*/handler");

    这是可行的,因为正如我之前提到的,Play 生成了连接处理程序 actors - 所以它们的地址是这样的:akka://application/system/websockets/42/handler。同样,通过这种方式您可以获得所有 Actor ,但无法获得单个 Actor (因为您不知道他们的处理程序编号)。

  • 第 2b 步:管理 WebSocket 参与者这里的优点是您可以完全管理 Actor 并为他们分配各种信息。缺点是你多了一个 Actor 要照顾(虽然不是什么大问题,Akka 很擅长这个)

你会像这样创建一个新的 Actor :

 public class ManagerActor extends UntypedActor {

List<ActorRef> slaves;

public MyWebSocketActor() {
this.slaves = new ArrayList<>();
}

public void onReceive(Object message) throws Exception {
if (message instanceof RegisterMe) {
// a new WebSocket was created so we can register him
slaves.add(sender());

// also register a DeathWatch so that we know when the WebSocket actor dies
context.watch(sender());
} else if (message instanceof Terminated) {
// remove from the list
...
}
}
}

第 3 步:将所有内容放在一起

现在,还记得上面的 WebSocket actor 吗?他应该以某种方式向经理注册。同样,您可以通过两种方式执行此操作:您可以使用 context.system.actorSelection("user/manager")“查找”Manager,或者如果您已经有引用( ActorRef) 到管理器,您可以在创建 WebSocket actor 时将其作为构造函数参数提供

您可以使用每个 Actor 都可以使用的 preStart 方法进行注册:

public class MyWebSocketActor extends UntypedActor {

....

@Override
public void preStart() throws Exception {
context().system().actorSelection("user/manager").tell(RegisterMe, self());
super.preStart();
}
}

现在您已经拥有由 ... 管理器管理的所有 WebSocket actor,您可以定义他可以处理的新消息并告诉他必须将 m4 转发给客户端。请注意,您可以在管理器中使用类似 Map 的东西 - 其中 ActorRef 是键,值是一些用户特定的属性或您想要的任何内容。

关于java - 该实例的 Akka Actor 路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36312970/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com