编程语言
首页 > 编程语言> > java-该实例的Akka Actor路径

java-该实例的Akka Actor路径

作者:互联网

我正在使用Java Play Framework.
我正在使用Web套接字进行客户端服务器交互.
在服务器端,我们又有参与者来响应客户的请求.
我面临的问题:
我想要,当客户端打开与服务器上的客家演员的Web套接字连接时,实际上为该演员打开了一个池,然后我需要跟踪该实例的演员客户端路径,以便每当采取其他措施时如果放置在其他某个类中,则该类(使用跟踪的实例路径)通知此参与者已发生该操作,然后该参与者通知用户(客户端)该操作已发生.
我实际上正在使用

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

以上保留获取该客户端用户实例的路径.
但是下一次当我尝试使用此路径击中该演员时,我找不到该演员.
我试图从另一个演员中打那个演员的方式是:

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

所以上面的代码简单地说,首先我从缓存中获取苏格兰路径(它已缓存在内存中以备将来使用),然后我尝试将该路径传递给演员选择.一旦我获得了对象用于演员选择,我就使用告诉其他演员我需要传递的消息是m4.
请纠正我我要去哪里.
我看不到演员使用此路径.
我觉得,我追踪路径的方式是错误的.
请纠正我.

解决方法:

请耐心等待,这将需要一些时间,但是应该可以使您对如何做有一个很好的了解.注意:我假设您仍在使用Play 2.4.x并且尚未更新为Play2.5.x.另外,您也使用Java(尽管如果可以切换,我建议使用Akka Scala API).

步骤1:定义正在处理WebSocket连接的actor

在您的控制器中,您可以这样编写:

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生成).您无需对此做任何事情,只需记住,一旦您向该演员发送了一些东西,他便会处理给客户.

您还必须在路由文件中定义适当的路由:

GET / ws controllers.Application.socket()

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

通常,您有两个选择-您可以“查找”上面创建的参与者,也可以提供某种机制来管理它们(类注册表)

>步骤2.1:查找WebSocket参与者

这样做的好处是您不需要额外的注册表/管理器或类似内容.缺点是,实际上很难知道哪个角色为哪个WebSocket连接服务.

您将为此使用actorSelection:

system.actorSelection(“ system / websockets / * / handler”);

之所以起作用,是因为正如我之前提到的,Play生成了连接处理程序参与者,因此它们的地址如下:akka:// application / system / websockets / 42 / handler.同样,通过这种方式,您可以获取所有演员,但不能获得单个演员(因为您不知道其处理者编号).
>步骤2b:管理WebSocket参与者
这样做的好处是,您可以完全管理参与者,并为他们分配各种信息.缺点是您还要多一位演员来照顾(尽管这并不是真正的问题,但Akka在这方面做得很好)

您将创建一个新的演员,例如:

 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,或者如果已经具有对Manager的引用(ActorRef),则可以提供它创建WebSocket actor时作为构造函数参数

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

public class MyWebSocketActor extends UntypedActor {

   ....

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

现在,您已经由…管理器管理了所有WebSocket角色,您可以定义新消息,他可以处理该消息,并告诉他必须将m4转发给客户端.请注意,您可以在Manager中使用诸如Map之类的东西-其中ActorRef是键,而值是某些用户特定的属性或您想要的任何属性.

标签:playframework,playframework-2-0,akka,java
来源: https://codeday.me/bug/20191118/2031467.html