1 回答
TA贡献2065条经验 获得超13个赞
文档确实需要更新,我认为在#5055 的websockets 重构中遗漏了一些位。
要获得异步处理,您应该使用acceptOrResult
以 aCompletionStage
作为返回类型而不是流的方法。然后可以使用函数式编程助手 ( ) 返回 aResult
或 Akka 。事实上,下面是该方法的实现方式:Flow
F.Either
accept
public WebSocket accept(Function<Http.RequestHeader, Flow<In, Out, ?>> f) { return acceptOrResult( request -> CompletableFuture.completedFuture(F.Either.Right(f.apply(request)))); }
如您所见,它所做的只是调用带有completedFuture
.
为了完全使其异步并达到我认为你想要实现的目标,你会做这样的事情:
public WebSocket ws() {
return WebSocket.Json.acceptOrResult(request -> {
if (sameOriginCheck(request)) {
final CompletionStage<Flow<JsonNode, JsonNode, NotUsed>> future = wsFutureFlow(request);
final CompletionStage<Either<Result, Flow<JsonNode, JsonNode, ?>>> stage = future.thenApply(Either::Right);
return stage.exceptionally(this::logException);
} else {
return forbiddenResult();
}
});
}
@SuppressWarnings("unchecked")
private CompletionStage<Flow<JsonNode, JsonNode, NotUsed>> wsFutureFlow(Http.RequestHeader request) {
long id = request.asScala().id();
UserParentActor.Create create = new UserParentActor.Create(Long.toString(id));
return ask(userParentActor, create, t).thenApply((Object flow) -> {
final Flow<JsonNode, JsonNode, NotUsed> f = (Flow<JsonNode, JsonNode, NotUsed>) flow;
return f.named("websocket");
});
}
private CompletionStage<Either<Result, Flow<JsonNode, JsonNode, ?>>> forbiddenResult() {
final Result forbidden = Results.forbidden("forbidden");
final Either<Result, Flow<JsonNode, JsonNode, ?>> left = Either.Left(forbidden);
return CompletableFuture.completedFuture(left);
}
private Either<Result, Flow<JsonNode, JsonNode, ?>> logException(Throwable throwable) {
logger.error("Cannot create websocket", throwable);
Result result = Results.internalServerError("error");
return Either.Left(result);
}
(这取自play-java-websocket-example,这可能很有趣)
如您所见,它首先经过几个阶段,然后返回 websocket 连接或 HTTP 状态。
添加回答
举报