Akka和Play,与非控制器库集成

时间:2015-10-27 13:45:59

标签: java akka playframework-2.3

我很难理解Akka与Play框架的集成。我想将Akka actor集成到我自己创建的非控制器库类中,但是文档仅提供了一个返回结果的控制器示例(Play 2.3)。我还没有写任何代码,因为我对如何前进感到非常烦恼。有没有人在控制器外正确使用Akka的例子?我找到了这个例子(Java 8):

<application
    android:allowBackup="true"
    android:icon="@mipmap/myicon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar" >

 <!--android:theme="@style/AppTheme"-->

但看起来它与Akka完全无关。我很难过,我甚至不确定我是否正确地提出这个问题,我为没有代码样本而道歉。

我的假设是:将上面的代码示例放在我的库类中并按照指定使用它,像处理任何其他方法一样处理“longRunningComputation()”,并保留它。我当时的担忧是,我并没有真正利用Akka提供的东西。

是否有人建议在这里提供帮助的Akka教程?

1 个答案:

答案 0 :(得分:2)

总体

请记住,Akka(实际上)与Play无任何关联或限制。在Akka之上构建了数千个与Play无关的系统。 Akka和Play一起玩得很好。

Akka + Play

在应用程序的非控制器部分使用Akka actor非常好。您只需要一种方法将控制器连接到actor系统。这意味着您需要找到一种与演员系统中的演员交谈的方法。在Akka中有(通常)两种方法。你或者向演员说(发送)或者问他什么。

告诉

Saying / send(也称为告诉 ing或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");
    }
}

当然,您绝不仅限于通过控制器的方法联系演员。

整个流程消息传递过程当然非常复杂 - 完全取决于您的业务逻辑。上面的演员 my-actor 现在会收到消息并在此时做很多事情 - 转发它,生成孩子,自杀,做计算等。

在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中执行此操作的示例。请记住,这次你得到了回报。这就是所谓的Future。一旦这个未来完成(成功),您将获得结果。然后你可以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,每个连接都由一个actor处理。现在想想一个聊天应用程序 - 一旦我在WebSocket上发送了一些东西,我希望该应用程序的每个其他用户都能收到它 - 现在这是“hello-world-Akka actors”的好例子,不是吗