Scala 如何在客户端关闭连接后进行清理
我正在使用akka创建一个代理API,它在将请求转发到实际API之前做了一些准备。对于其中一个端点,响应是流式传输json数据,客户端可以随时关闭连接。Akka似乎会自动处理这个问题,但问题是我需要在客户端关闭连接后进行一些清理Scala 如何在客户端关闭连接后进行清理,scala,akka,Scala,Akka,我正在使用akka创建一个代理API,它在将请求转发到实际API之前做了一些准备。对于其中一个端点,响应是流式传输json数据,客户端可以随时关闭连接。Akka似乎会自动处理这个问题,但问题是我需要在客户端关闭连接后进行一些清理 path("query") { post { decodeRequest { entity(as[Query]) { query => // proxy does some preparations val
path("query") {
post {
decodeRequest {
entity(as[Query]) { query =>
// proxy does some preparations
val json: String = query.prepared.toJson.toString()
// proxy sends request to actual server
val request = HttpRequest(
method = HttpMethods.POST,
uri = serverUrl + "/query",
entity = HttpEntity(ContentTypes.`application/json`, json)
)
val responseFuture = Http().singleRequest(request)
val response: HttpResponse = Await.result(responseFuture, PROXY_TIMEOUT)
// proxy forwards server's response to user
complete(response)
}
}
}
}
我试过做类似的事情
responseFuture.onComplete(_ => doCleanup())
但这不起作用,因为即使在客户端关闭连接之前服务器继续发送数据,responseFuture也会立即完成。完成(响应)也会立即返回
因此,我想知道如何在客户端关闭连接后才能调用doCleanup()
path("query") {
post {
decodeRequest {
entity(as[Query]) { query =>
// proxy does some preparations
val json: String = query.prepared.toJson.toString()
// proxy sends request to actual server
val request = HttpRequest(
method = HttpMethods.POST,
uri = serverUrl + "/query",
entity = HttpEntity(ContentTypes.`application/json`, json)
)
val responseFuture = Http().singleRequest(request)
val response: HttpResponse = Await.result(responseFuture, PROXY_TIMEOUT)
// proxy forwards server's response to user
complete(response)
}
}
}
}
编辑:我需要做的清理是因为代理创建了一些数据流,这些数据流是临时的,只会持续到服务器发送最后一条消息为止。一旦发生这种情况,就需要删除这些流。您只需对代码进行少量更改即可完成此操作,如下所示:
val responseFuture = Http().singleRequest(request)
val response: HttpResponse = try {
Await.result(responseFuture, PROXY_TIMEOUT)
} finally {
doCleanup()
}
complete(response)
或者,您可以在不阻塞的情况下执行此操作:
val responseFuture = Http().singleRequest(request)
val cleaned = responseFuture.andThen{case _ => doCleanUp()}
complete(cleaned) //it's possible to complete response with Future
您只需对代码进行少量更改即可做到这一点,如下所示:
val responseFuture = Http().singleRequest(request)
val response: HttpResponse = try {
Await.result(responseFuture, PROXY_TIMEOUT)
} finally {
doCleanup()
}
complete(response)
或者,您可以在不阻塞的情况下执行此操作:
val responseFuture = Http().singleRequest(request)
val cleaned = responseFuture.andThen{case _ => doCleanUp()}
complete(cleaned) //it's possible to complete response with Future
你能解释一下你想做什么样的清理吗?很可能Http路由不是执行它的最佳位置。连接也是一个低级Tcp问题。不要认为你可以/应该在Http级别的代码中处理它。问题更新你能解释一下你想做什么样的清理吗?很可能Http路由不是执行它的最佳位置。连接也是一个低级Tcp问题。不要认为您可以/应该在Http级别的代码中处理它。问题已更新