问题描述
因为我们可以使用 HttpResponse
但它不会在响应中产生任何延迟,有没有办法在其中添加延迟?
解决方法
是的,您可以,也可以不使用 Thread.sleep。因为它会阻塞线程,如果您需要模拟一个有大量请求的服务,这不是一个好的选择。检查这个旧的实现,也许它可以帮助:https://github.com/EmiCareOfCell44/http-retarder
,在本例中,我使用 Thread.sleep(value)
模拟延迟。但请注意,当您从浏览器请求 http GET|POST localhost:8081/home?timeout=5000
此方法被阻塞时,即使 HttpResponse
在 Future
内,它也会延迟您作为参数传递的时间。
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.IncomingConnection
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.Location
import akka.stream.scaladsl.{Flow,Sink}
import scala.concurrent.Future
object BasicServerLowLevel {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("BasicServerLowLevel")
import system.dispatcher
def getHtmlFuture(value: Int) = {
Thread.sleep(value) // SIMULATING A LONG COMPUTATION HERE
Future(HttpResponse(
StatusCodes.OK,// HTTP 200
entity = HttpEntity(
ContentTypes.`text/html(UTF-8)`,s"""
|<html>
| <body>
| Async Hello Akka HTTP timeout: $value milliseconds
| </body>
|</html>
|""".stripMargin)
))
}
/** serve back HTTP response ASYNCHRONOUSLY */
val asyncRequestHandler: HttpRequest => Future[HttpResponse] = {
case HttpRequest(HttpMethods.GET | HttpMethods.POST,uri@Uri.Path("/home"),headers,entity,protocol) =>
val timeout = uri.query().get("timeout").map(_.toInt)
println(s"timeout: $timeout milliseconds")
timeout match {
case None =>
getHtmlFuture(0)
case Some(value: Int) =>
getHtmlFuture(value)
}
case request: HttpRequest =>
request.discardEntityBytes()
Future(HttpResponse(
StatusCodes.NotFound,// HTTP 404
entity = HttpEntity(
ContentTypes.`text/html(UTF-8)`,"""
|<html>
| <body>
| OOPS! async page not found =(<br>try http://localhost:8081/home
| </body>
|</html>
|""".stripMargin)
))
}
val httpAsyncConnectionHandler = Sink.foreach[IncomingConnection] { connection =>
connection.handleWithAsyncHandler(asyncRequestHandler)
}
println(s"call on the console: 'http GET localhost:8081/home'")
println(s"call on the console: 'http GET localhost:8081/home?timeout=5000'")
// manual version >>>
// Http().newServerAt("localhost",8081).connectionSource().runWith(httpAsyncConnectionHandler)
// short version >>>
Http().newServerAt("localhost",8081).bind(asyncRequestHandler)
}
}
,
梅比有这样的想法吗?基于akka.pattern.after。 测试延迟 10 秒 -> http://localhost:9000/example?delay=10000
object Main extends App with Directives {
implicit val system: ActorSystem = ActorSystem()
val routes: Route = {
(get & path("example")) {
parameter("delay".as[Int]) { delay =>
complete {
akka.pattern.after(delay.millis) {
Future.successful(response(delay))
}
}
}
}
}
def response(delay: Int): HttpResponse = {
HttpResponse(
StatusCodes.OK,entity = HttpEntity(
ContentTypes.`text/html(UTF-8)`,s"""
|<html>
| <body>
| Example request with delay $delay
| </body>
|</html>
|""".stripMargin
)
)
}
val (host,port) = ("localhost",9000)
Http().newServerAt(host,port).bind(routes)
}