在Future完成时将Html流式传输到浏览器

时间:2017-06-07 16:49:33

标签: scala playframework stream akka future

我试图将期货作为 Html (在Scala的Play 2.5.2中)流式传输,其理念是当时它们将在屏幕上呈现>期货完成。所以我会将 Source 作为 String 流式传输:

   def oneFuture = Action { request =>
     val source1: Source[String, NotUsed] = fromFuture(sc.makeServiceCall("async1"))
     Ok.chunked(source1)
   }

sc.makeServiceCall调用的地方:

   class ServiceClient @Inject() (ws: WSClient) {

     def makeServiceCall(serviceName: String): Future[String] = {
       ws.url(s"http://localhost:9000/mock/$serviceName").get().map(_.body)
     }

   }

引用:

   class Mock @Inject() (actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller {

     def mock(serviceName: String) = Action.async { request =>
       serviceName match {
         case "async1" => respond("asy1", 1.second)
         case "async2" => respond("asy2", 3.second)
       }
     }

     private def respond(data: String, delay: FiniteDuration): Future[Result] = {
       val promise: Promise[Result] = Promise[Result]()
       actorSystem.scheduler.scheduleOnce(delay) { promise.success(Ok(data)) }
       promise.future
     }

   }

1秒后返回asy1。因此,如果我想要流式传输模板页,那么如何在浏览器中呈现 Html ,例如views.html.async1.async1Message("a simple string") - 这是:

   @(async1Message: String)

   <span style="color: red; font-size: 22px; font-weight: bold;">@async1Message</span>

1 个答案:

答案 0 :(得分:0)

为什么你坚持流式传输结果?您可以异步返回整个页面,这是一个小模板。

话虽如此,如果这是出于学习目的,您应该知道Source.fromFuture使用单个元素创建一个Akka源。您需要自己将其拆分为块。你可以这样做:

val chunkSize = 512 // 512 characters of your string
val source = Source.fromFuture(sc.makeServiceCall("async1"))
  .mapConcat(_.grouped(chunkSize))
Ok.chunked(source)