1

我希望能够确定流何时完成、取消或失败。

我有以下控制器操作:

def downloadAction(streamer: (String, String) => Future[ Either[ String, Result ] ],snr: String, fName: String ) = Action.async { implicit request =>
  streamer( snr, fName ).map {
    case Left(err) =>    Ok(views.html.errorPage( err ) )

    case Right(result) =>     result.withHeaders(CONTENT_DISPOSITION -> s"attachment; filename=$fName")
  }
}

我的第一种方法是向流媒体 Future 添加一个 onComplete:

def downloadAction(streamer: ( String, String ) => Future[ Either[ String, Result ] ], snr: String, fName: String ) = Action.async { implicit request =>
  val startTs = System.currentTimeMillis
  val streamFut = streamer(snr, fName).map {
    case Left(err) =>   Ok(views.html.errorPage(err))
    case Right(result) =>    result.withHeaders(CONTENT_DISPOSITION -> s"attachment; filename=$fName")
  }.onComplete( _ => {    
    val requestTime = System.currentTimeMillis - startTs
    Logger.info(s"${request.header.method} ${request.header.uri} took ${requestTime}ms and returned ${result.header.status}")
  })
  streamFut
}

该时间值约为 100 毫秒,而 100Mb 下载显然需要几分钟。所以这种方法是不正确的。

我意识到,因为 streamerFut 最初来自 HttpEntity.Streamed/HttpEntity.Chunked,所以即使流正在进行,Future 也会很快完成。我猜这种方法可能适用于 HttpEntity.Strict 但不适用于 HttpEntity.Streamed/HttpEntity.Chunked

在考虑查看客户端 JavaScript 之前,我正在寻找服务器端解决方案。

4

0 回答 0