现在我正在使用akka-stream
和akka-HTTP
来构建文件流API。因此,我将流式源注入实体,以便将数据直接传输到HTTP客户端,如下所示:
complete(HttpEntity(ContentTypes.`application/octet-stream`, source))
但是,如果由于某种原因导致流失败,则连接将被akka-http关闭,无需进一步说明或记录。
我需要两件事:
谢谢
答案 0 :(得分:0)
如评论中所述,HTTP协议不允许向客户端发出错误信号。
关于记录: 对我来说,它归结为缺少akka http中的正确访问日志指令。
在我当前的项目中,我们有装饰器,它在为http实体提供acoka http之前注册onComplete处理程序。
private def onResponseStreamEnd(response: HttpResponse)(action: StatusCode => Unit): HttpResponse =
if (!response.status.allowsEntity() || response.entity.isKnownEmpty()) {
action(response.status)
response
} else {
val dataBytes =
onStreamEnd(response.entity) { result =>
val overallStatusCode =
result match {
case Success(_) =>
response.status
case Failure(e) =>
logger.error(e, s"error streaming response [${e.getMessage}]")
StatusCodes.InternalServerError
}
action(overallStatusCode)
}
response.withEntity(response.entity.contentLengthOption match {
case Some(length) => HttpEntity(response.entity.contentType, length, dataBytes)
case None => HttpEntity(response.entity.contentType, dataBytes)
})
}
private def onStreamEnd(entity: HttpEntity)(onComplete: Try[Done] ⇒ Unit): Source[ByteString, _] =
entity.dataBytes.alsoTo { Sink.onComplete(onComplete) }
用法:
complete(onResponseStreamEnd(HttpResponse(StatusCodes.OK, HttpEntity(ContentTypes.`application/octet-stream`, source))){ statusCode => .... })
类似的方法,但使用自定义图表阶段,您可以找到here