在 Playframework 中使用流式 HTTP 分块响应

Using streaming HTTP chunked responses in Playframework

我正在尝试使用 Play 框架 2.6 在 Java 中构建一个 REST API,它将以块的形式向客户端发送响应。为此,我按照 documentation of Play HTTP Response streaming 遵循分块响应生成器示例。

在示例中(也在下面复制),发送块后,它正在关闭源。如何保持源打开并在经过一些处理后使用 sourceActor 继续发送更多消息?此处理可能发生在有权访问 sourceActor 的其他一些 actor 中。

public Result index() {
// Prepare a chunked text stream
Source<ByteString, ?> source = Source.<ByteString>actorRef(256, OverflowStrategy.dropNew())
    .mapMaterializedValue(sourceActor -> {
        sourceActor.tell(ByteString.fromString("kiki"), null);
        sourceActor.tell(ByteString.fromString("foo"), null);
        sourceActor.tell(ByteString.fromString("bar"), null);
        sourceActor.tell(new Status.Success(NotUsed.getInstance()), null);
        return NotUsed.getInstance();
    });
// Serves this stream with 200 OK
return ok().chunked(source);
}

使用BroadcastHub:

Pair<ActorRef, Source<ByteString, NotUsed>> source =
  Source.<ByteString>actorRef(256, OverflowStrategy.dropNew())
    .toMat(BroadcastHub.of(ByteString.class), Keep.both())
    .run(materializer);

ActorRef sourceActor = source.first();
Source<ByteString, NotUsed> matSource = source.second();

发送给物化actor的消息被发送到下游,你可以使用物化源来完成这个方法(注意这种方法没有背压):

sourceActor.tell(ByteString.fromString("kiki"), ActorRef.noSender());
// send more messages to sourceActor...

return ok().chunked(matSource);

您可能需要使用 keepAlive 将消息注入流以使其保持打开状态。