Akka http从指令返回异步响应(java)
我想要一个基于参与者的服务,可以通过http访问。Akka http从指令返回异步响应(java),java,akka,akka-http,Java,Akka,Akka Http,我想要一个基于参与者的服务,可以通过http访问。 我是akka的新手,但经过研究,我得出结论,使用akka http将是我最好的方法 我正在实现一个使用akka http的服务器,如下所示: class MyServer extends AllDirectives { private final Http http; private final Materializer materializer; private final Flow<HttpRequest, H
我是akka的新手,但经过研究,我得出结论,使用akka http将是我最好的方法 我正在实现一个使用akka http的服务器,如下所示:
class MyServer extends AllDirectives {
private final Http http;
private final Materializer materializer;
private final Flow<HttpRequest, HttpResponse, NotUsed> routes;
private ServerBinding binding;
MyServer(final ActorSystem system) {
this.http = Http.get(system);
this.materializer = ActorMaterializer.create(system);
this.routes = this.createRoutes().flow(system, materializer);
}
CompletionStage<ServerBinding> start() {
return this.http
.bindAndHandle(this.routes, ConnectHttp.toHost("localhost", DEFAULT_PORT), this.materializer)
.thenApplyAsync(serverBinding -> {
this.binding = serverBinding;
return serverBinding;
});
}
CompletionStage<BoxedUnit> stop() {
return this.binding.unbind();
}
private Route createRoutes() {
// create routes
}
}
在处理请求时(例如,handleTypeOneGetRequest
),我希望将消息传递给适当的参与者(例如,TypeOne
),并返回一个异步响应,当参与者返回响应消息时,将执行该响应
我的问题是,在处理指令时,我不知道如何访问RequestContext
我的问题是:
- 如何获取指令中的
RequestContext
- 我这样做对吗?有更好的方法吗
- 不太确定我是否正确回答了你的问题,但就我回答你的问题而言,你基本上希望让演员处理你的请求,然后返回结果。我通常使用Scala,所以请不要介意我在Java8代码中可能出现的语法错误;)
我通常使用akka ask模式检索参与者发送的响应对象的未来,然后使用onSuccess指令从未来提取实际值。
由于actor响应在默认情况下是非类型化的,所以您需要检查它是否是您期望的,然后您可以使用该值完成您的请求。(您可能还需要强制转换对象,以便响应封送器工作)
提问模式:
onSuccess指令:
编辑
您应该看看extract*指令:
具体摘录:
我想这就是你需要的
编辑(由OP编辑) 以下是该问题的完整解决方案,包括
HttpContext
,使用Actor
进行异步响应,以及如何使其在java中工作:
pathPrefix("typeOne", () ->
path(PathMatchers.segment(), segment ->
get(() ->
extract(
context -> context,
context -> onSuccess(() ->
FutureConverters.toJava(Patterns.ask(ACTOR_REF, MESSAGE, TIMEOUT)),
extraction -> complete(DO_SOMETHING_WITH(segment, context, extraction))
).orElse(...)
)
)
)
)
谢谢,这部分回答了我的问题(如何返回异步响应并要求参与者处理请求)。另一部分是如何访问指令中的
RequestContext
,也就是说,当将消息传递给参与者时,我希望该消息包含RequestContext
中的信息(post/get数据、标题等),但我还没有找到获取该信息的方法,您不需要RequestContext。根据我的回答改编得很有趣。谢谢你!我会在接下来的几天里玩它,当我使用它的时候,我可能会有更多关于这个的问题。那我就把答案记为正确答案。再次感谢!感谢您的回答,这基本上是正确的,我只需要将这两个问题结合起来(使用和actor以及获取RequestContext
),还需要从scalaFuture
转换为javaCompletionStage
。为了未来读者的利益,我编辑了您的答案并添加了完整的解决方案。再次感谢!
Timeout timeout = new Timeout(Duration.create(5, "seconds"));
private Route createRoutes() {
return pathPrefix("typeOne", () ->
path(PathMatchers.segment(), id ->
get(() ->
onSuccess(() -> Patterns.ask(actor, id, timeout),
extraction -> if (extraction instanceof WhatEverYouExpect) complete(extraction)
)
)
));
}
final Route route = extract(
ctx -> ctx.getRequest().getUri().toString().length() // extract anything you need and pack into your object
len -> //use your object
);
pathPrefix("typeOne", () ->
path(PathMatchers.segment(), segment ->
get(() ->
extract(
context -> context,
context -> onSuccess(() ->
FutureConverters.toJava(Patterns.ask(ACTOR_REF, MESSAGE, TIMEOUT)),
extraction -> complete(DO_SOMETHING_WITH(segment, context, extraction))
).orElse(...)
)
)
)
)