【问题标题】:Akka and Play, integrating with non controller librariesAkka 和 Play,与非控制器库集成
【发布时间】:2015-10-27 13:45:59
【问题描述】:

我很难理解 Akka 与 Play 框架的集成。我想将 Akka 演员集成到我自己创建的非控制器库类中,但文档仅提供了控制器中返回结果的示例(播放 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 一点关系都没有。我很困惑,我什至不确定我问这个问题是否正确,对于没有代码示例,我深表歉意。

我的假设是这样的:将上面的代码示例放在我的库类中并按指定使用它,将“longRunningComputation()”视为我对任何其他方法调用的处理,然后将其保留。在这一点上,我担心的是我并没有真正利用 Akka 所提供的功能。

是否有任何人会推荐在这里提供帮助的 Akka 教程?

【问题讨论】:

    标签: java akka playframework-2.3


    【解决方案1】:

    总体

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


    Akka + 播放

    在应用程序的非控制器部分中使用 Akka 演员是非常好的。您只需要一种方法将您的控制器连接到您的演员系统。这意味着您需要找到一种与您的演员系统中的演员交谈的方法。在 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 现在将接收消息并在此时执行许多操作 - 转发消息、生成子节点、杀死自己、进行计算等。

    在 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 并且每个连接都由参与者处理。现在想想一个聊天应用程序——一旦我在 WebSocket 上发送了一些东西,我希望该应用程序的每个其他用户都能收到它——现在这对于“hello-world-Akka 演员”来说是一个很好的例子,不是吗

    【讨论】:

    • 你是一个绝对的救星。我查看了 Akka 文档,但在您提供的范围内找不到任何有用的东西。非常感谢!
    • 很高兴能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 2015-01-11
    • 2014-04-25
    相关资源
    最近更新 更多