【发布时间】:2014-09-23 08:04:23
【问题描述】:
我有一个 Play framework 2 应用程序,它可以接收数据并通过 WebSockets 将其发送到多个客户端。我使用 Akka actor 来处理 WebSockets,就像在 this documentation 中一样。我还有一个 WebSocketRouter 类,它扩展了 UntypedActor 并包含路由逻辑(决定将系统接收到的数据传递给哪些客户端)。我知道我可以使用 Akka 的 Router 功能,但这对我来说目前不是问题。问题是我必须存储所有活动客户的列表。现在我将它存储在WebSocketRouter 类的静态列表中。这是编写概念验证原型的最快方法,但它不是线程安全的,而且似乎不是“Akka 方式”。
下面是一个简化的代码示例:
WebSocketController:
//This controller handles the creation of WebSockets.
public class WebSocketController extends Controller {
public static WebSocket<String> index() {
return WebSocket.withActor(new F.Function<ActorRef, Props>() {
public Props apply(ActorRef out) throws Throwable {
return MessageSender.props(out);
}
});
}
}
消息发送者:
//Hold a reference to the auto-created Actor that handles WebSockets
//and also registers and unregisters itself in the router.
public class MessageSender extends UntypedActor {
public static Props props(ActorRef out) {
return Props.create(MessageSender.class, out);
}
private final ActorRef out;
public MessageSender(ActorRef out) {
this.out = out;
}
@Override
public void preStart() {
WebSocketRouter.addSender(getSelf());
}
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
out.tell(message, getSelf());
}
else {
unhandled(message);
}
}
public void postStop() {
WebSocketRouter.removeSender(getSelf());
}
}
WebSocketRouter:
public class WebSocketRouter extends UntypedActor {
private static ArrayList<ActorRef> senders;
static {
senders = new ArrayList<>();
}
public static void addSender(ActorRef actorRef){
senders.add(actorRef);
}
public static void removeSender(ActorRef actorRef){
senders.remove(actorRef);
}
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
for (ActorRef sender : senders) {
sender.tell(message, getSelf());
}
}
}
}
再一次,我知道这是一个糟糕的解决方案,我正在寻找一个更好的解决方案。我曾想过创建一个线程安全的单例类来保存当前连接。我还考虑过将当前连接列表保存在某个 Akka Actor 的实例中,并通过 Akka 消息修改列表,但是为了使这种方式工作,我必须静态存储一个 ActorRef 到该 Actor,以便它可以可以从不同的ActorSystems 访问。
解决我的问题最适合 Akka 意识形态的最佳方法是什么?
【问题讨论】:
-
嘿,当我尝试停止演员时,websocket 连接将关闭并且它不会再次打开,如果您有任何想法,请告诉我
标签: java playframework akka