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