文档

§Comet

§使用分块响应与 Comet

分块响应 的一个常见用途是创建 Comet 套接字。

Comet 套接字是一个分块的 text/html 响应,其中只包含 <script> 元素。对于每个块,我们都会写入一个包含 JavaScript 的 <script> 标签,该标签会立即由 Web 浏览器执行。这样,我们就可以从服务器实时将事件发送到 Web 浏览器:对于每条消息,将其包装在一个调用 JavaScript 回调函数的 <script> 标签中,并将其写入分块响应。

由于 ok().chunked 利用 Pekko 流 来获取 Flow<ByteString>,因此我们可以发送一个元素流并对其进行转换,以便每个元素都经过转义并包装在 Javascript 方法中。Comet 助手会自动执行 Comet 套接字,为浏览器兼容性推送初始空白缓冲区数据,并支持字符串和 JSON 消息。

§Comet 导入

要使用 Comet 助手,请导入以下类

import org.apache.pekko.NotUsed;
import org.apache.pekko.stream.javadsl.Source;
import play.core.j.JavaHandlerComponents;
import play.libs.Comet;
import play.libs.Json;
import play.mvc.Http;
import play.mvc.Result;

您还需要一个物化器,最好从您的 DI 系统 中提取 pekko.stream.Materializer

§使用 Comet 与字符串流

要通过流推送字符串消息,请执行以下操作

public static Result index() {
  final Source<String, NotUsed> source = Source.from(Arrays.asList("kiki", "foo", "bar"));
  return ok().chunked(source.via(Comet.string("parent.cometMessage"))).as(Http.MimeTypes.HTML);
}

§使用 Comet 与 JSON 流

要通过流推送 JSON 消息,请执行以下操作

public static Result index() {
  final ObjectNode objectNode = Json.newObject();
  objectNode.put("foo", "bar");
  final Source<JsonNode, NotUsed> source = Source.from(Collections.singletonList(objectNode));
  return ok().chunked(source.via(Comet.json("parent.cometMessage"))).as(Http.MimeTypes.HTML);
}

§使用 Comet 与 iframe

Comet 助手通常应与 forever-iframe 技术一起使用,HTML 页面如下所示

<script type="text/javascript">
  var cometMessage = function(event) {
    console.log('Received event: ' + event)
  }
</script>

<iframe src="/comet"></iframe>

注意:将以下配置添加到您的 application.conf 文件中,并确保您已设置路由映射,以便查看上述彗星的运行情况。

play.filters.headers {
  frameOptions = "SAMEORIGIN"
  contentSecurityPolicy = "connect-src 'self'"
}

有关彗星助手示例,请参见 Play 流式传输示例

§调试彗星

调试无法正常工作的彗星流的最简单方法是使用 log() 操作来显示与通过流映射数据相关的任何错误。

§传统彗星功能

以前存在的彗星功能仍然可以通过 play.libs.Comet 使用,但已弃用,建议您迁移到基于 Pekko 流的版本。

由于 Java 彗星助手基于回调,因此将基于回调的功能直接转换为 org.reactivestreams.Publisher 并使用 Source.fromPublisher 创建源可能更容易。

下一步:WebSockets


在此文档中发现错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区开始对话。