Akka 和 Play,与非控制器库集成
Akka and Play, integrating with non controller libraries
我很难理解 Akka 与 Play 框架的集成。我想将 Akka actors 集成到我自己创建的非控制器库 class 中,但文档仅提供了一个控制器返回结果的示例 (Play 2.3)。我还没有编写任何代码,因为我对如何前进感到很烦恼。有没有人有关于在控制器外正确使用 Akka 的示例?我找到了这个例子 (Java 8):
import play.libs.F.Promise;
import play.mvc.*;
import static play.libs.F.Promise.promise;
public class Application extends Controller {
public static Promise<Result> index() {
return promise(() -> longComputation())
.map((Integer i) -> ok("Got " + i));
}
}
不过看起来和Akka一点关系都没有。我很困惑,我什至不确定我问的这个问题是否正确,对于没有代码示例,我深表歉意。
我的假设是:将上面的代码示例放在我的库 class 中并按指定使用它,像对待任何其他方法调用一样对待 "longRunningComputation()",然后就这样。我当时担心的是我并没有真正利用 Akka 提供的功能。
有没有任何人会推荐的 Akka 教程来提供帮助?
总体
请记住,Akka(实际上)与 Play 没有任何关联或限制。有成千上万的系统建立在 Akka 之上,与 Play 无关。 Akka 和 Play 一起玩得很好。
Akka + Play
在应用程序的 non-controller 部分使用 Akka actors 是完全没问题的。你只需要一种方法将你的控制器连接到你的演员系统。这意味着您需要找到一种方式与您的演员系统中的演员交谈。在 Akka 中(通常)有两种方法可以做到这一点。你要么对演员说(发送)一些东西,要么你问他一些东西。
告诉
说/发送(也称为 telling 或 fire-and-forget)在 Java 中用 actor.tell(message, getSelf())
完成,在 Scala 中用 actor ! message
import akka.actor.*;
import play.mvc.*;
import play.libs.Akka;
import play.libs.F.Promise;
import static akka.pattern.Patterns.ask;
public class Application extends Controller {
public static Result index() {
// select some actor from your system
ActorSelection actor = Akka.system().actorSelection("user/my-actor");
// now tell the actor something and do something else because we don't get a reply
actor.tell("Something");
return ok("Hello");
}
}
当然,您绝不仅限于通过控制器的方法联系演员。
整个消息传递过程当然可能非常复杂——这完全取决于您的业务逻辑。上面的 actor my-actor 现在将收到消息并在此时做很多事情 - 转发它,生成 children,杀死自己,进行计算等.
在 Java 中,您将拥有这样的演员:
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class MyUntypedActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
log.info("Received String message: {}", message);
// do whatever you want with this String message
} else
unhandled(message);
}
}
询问
询问完成...惊喜.. 询问模式 - 在 Scala 中 actor ? message
.
您已经在 Java 中找到了如何操作的示例。请记住,这次你会得到一些回报。这就是so-calledFuture
。一旦这个未来完成(成功),你就会得到你的结果。然后你可以 map
这个结果到其他一些结果。现在看看为什么会有 map()
调用?
import akka.actor.*;
import play.mvc.*;
import play.libs.Akka;
import play.libs.F.Promise;
import static akka.pattern.Patterns.ask;
public class Application extends Controller {
public static Promise<Result> index() {
// select some actor from your system
ActorSelection actor = Akka.system().actorSelection("user/my-actor");
// now ask the actor something and do something with the reply
return Promise.wrap(ask(actor, "how are you?", 1000))
.map(response -> ok(response.toString()));
}
}
个人经验的一些笔记:
- Akka 文档是您的朋友
- 查看 WebSocket 连接用例 - 为自己构建一个演示 Play 应用程序,您可以在其中支持 WebSocket 并且每个连接都由一个参与者处理。现在想想一个聊天应用程序——一旦我在 WebSocket 上发送了一些东西,我希望该应用程序的每个其他用户都能收到它——现在这对 "hello-world-Akka actors" 来说是很好的情况,不是吗
我很难理解 Akka 与 Play 框架的集成。我想将 Akka actors 集成到我自己创建的非控制器库 class 中,但文档仅提供了一个控制器返回结果的示例 (Play 2.3)。我还没有编写任何代码,因为我对如何前进感到很烦恼。有没有人有关于在控制器外正确使用 Akka 的示例?我找到了这个例子 (Java 8):
import play.libs.F.Promise;
import play.mvc.*;
import static play.libs.F.Promise.promise;
public class Application extends Controller {
public static Promise<Result> index() {
return promise(() -> longComputation())
.map((Integer i) -> ok("Got " + i));
}
}
不过看起来和Akka一点关系都没有。我很困惑,我什至不确定我问的这个问题是否正确,对于没有代码示例,我深表歉意。
我的假设是:将上面的代码示例放在我的库 class 中并按指定使用它,像对待任何其他方法调用一样对待 "longRunningComputation()",然后就这样。我当时担心的是我并没有真正利用 Akka 提供的功能。
有没有任何人会推荐的 Akka 教程来提供帮助?
总体
请记住,Akka(实际上)与 Play 没有任何关联或限制。有成千上万的系统建立在 Akka 之上,与 Play 无关。 Akka 和 Play 一起玩得很好。
Akka + Play
在应用程序的 non-controller 部分使用 Akka actors 是完全没问题的。你只需要一种方法将你的控制器连接到你的演员系统。这意味着您需要找到一种方式与您的演员系统中的演员交谈。在 Akka 中(通常)有两种方法可以做到这一点。你要么对演员说(发送)一些东西,要么你问他一些东西。
告诉
说/发送(也称为 telling 或 fire-and-forget)在 Java 中用 actor.tell(message, getSelf())
完成,在 Scala 中用 actor ! message
import akka.actor.*;
import play.mvc.*;
import play.libs.Akka;
import play.libs.F.Promise;
import static akka.pattern.Patterns.ask;
public class Application extends Controller {
public static Result index() {
// select some actor from your system
ActorSelection actor = Akka.system().actorSelection("user/my-actor");
// now tell the actor something and do something else because we don't get a reply
actor.tell("Something");
return ok("Hello");
}
}
当然,您绝不仅限于通过控制器的方法联系演员。
整个消息传递过程当然可能非常复杂——这完全取决于您的业务逻辑。上面的 actor my-actor 现在将收到消息并在此时做很多事情 - 转发它,生成 children,杀死自己,进行计算等.
在 Java 中,您将拥有这样的演员:
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class MyUntypedActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
log.info("Received String message: {}", message);
// do whatever you want with this String message
} else
unhandled(message);
}
}
询问
询问完成...惊喜.. 询问模式 - 在 Scala 中 actor ? message
.
您已经在 Java 中找到了如何操作的示例。请记住,这次你会得到一些回报。这就是so-calledFuture
。一旦这个未来完成(成功),你就会得到你的结果。然后你可以 map
这个结果到其他一些结果。现在看看为什么会有 map()
调用?
import akka.actor.*;
import play.mvc.*;
import play.libs.Akka;
import play.libs.F.Promise;
import static akka.pattern.Patterns.ask;
public class Application extends Controller {
public static Promise<Result> index() {
// select some actor from your system
ActorSelection actor = Akka.system().actorSelection("user/my-actor");
// now ask the actor something and do something with the reply
return Promise.wrap(ask(actor, "how are you?", 1000))
.map(response -> ok(response.toString()));
}
}
个人经验的一些笔记:
- Akka 文档是您的朋友
- 查看 WebSocket 连接用例 - 为自己构建一个演示 Play 应用程序,您可以在其中支持 WebSocket 并且每个连接都由一个参与者处理。现在想想一个聊天应用程序——一旦我在 WebSocket 上发送了一些东西,我希望该应用程序的每个其他用户都能收到它——现在这对 "hello-world-Akka actors" 来说是很好的情况,不是吗