Scala 如何在客户端关闭连接后进行清理

Scala 如何在客户端关闭连接后进行清理,scala,akka,Scala,Akka,我正在使用akka创建一个代理API,它在将请求转发到实际API之前做了一些准备。对于其中一个端点,响应是流式传输json数据,客户端可以随时关闭连接。Akka似乎会自动处理这个问题,但问题是我需要在客户端关闭连接后进行一些清理 path("query") { post { decodeRequest { entity(as[Query]) { query => // proxy does some preparations val

我正在使用akka创建一个代理API,它在将请求转发到实际API之前做了一些准备。对于其中一个端点,响应是流式传输json数据,客户端可以随时关闭连接。Akka似乎会自动处理这个问题,但问题是我需要在客户端关闭连接后进行一些清理

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级别的代码中处理它。问题已更新