我希望有一个基于演员的服务,可通过http访问 我是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
}
}
在createRoutes
方法中,我想使用指令创建分层路由树(或林),如:
private Route createRoutes() {
return pathPrefix("typeOne", () ->
path(PathMatchers.segment(), id ->
get(() -> handleTypeOneGetRequest(id))
.orElse(post(() -> handleTypeOnePostRequest(id, requestData)))
)
).orElse(pathPrefix("typeTwo", () ->
path(PathMatchers.segment(), id ->
get(() -> handleTypeTwoGetRequest(id))
.orElse(post(() -> handleTypeTwoPostRequest(id, requestData)))
)
));
}
处理请求时(例如handleTypeOneGetRequest
)我想将消息传递给相应的参与者(例如TypeOne
)并返回异步响应,该响应将在响应时完成消息从演员返回。
我的问题是,在处理指令时,我无法弄清楚如何访问RequestContext
。
我的问题是:
RequestContext
?答案 0 :(得分:2)
我不确定我的问题是否正确,但据我所知,您希望基本上让演员处理您的请求然后返回结果。我通常使用Scala,所以请不要介意我的Java8代码中可能的语法错误;)
我通常使用akka ask模式来检索actor发送的响应对象的未来,然后使用onSuccess指令从未来提取实际值。 由于参与者的响应默认为无类型,因此您需要检查它是否符合您的预期,然后您可以使用该值完成请求。 (你可能还需要施放对象,所以你的反应编组工作了。)
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)
)
)
));
}
询问模式:http://doc.akka.io/docs/akka/snapshot/java/futures.html
onSuccess指令:http://doc.akka.io/docs/akka/snapshot/java/http/routing-dsl/directives/future-directives/onSuccess.html
修改强>
你应该看一下extract *指令: http://doc.akka.io/docs/akka/2.4.7/java/http/routing-dsl/directives/alphabetically.html
final Route route = extract(
ctx -> ctx.getRequest().getUri().toString().length() // extract anything you need and pack into your object
len -> //use your object
);
我想这就是你需要的。
以下是该问题的完整解决方案,包括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(...)
)
)
)
)