我希望能够确定流何时完成、取消或失败。
我有以下控制器操作:
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 之前,我正在寻找服务器端解决方案。