我有一个用于调用REST Web服务的Spray客户端。目前我正在创建此客户端的实例(使用new GeoSprayWebClient
)[参见下面的代码]并在我的actor中重用它来发出REST请求。但是,单个服务实例无法处理所有负载。因此,我想介绍REST服务的副本。
我是Spray的新手,仍在努力学习基础知识。我的问题是
1)我知道Spray内部使用Akka演员。在这种特殊情况下,我可以为客户端实例获取ActorRef
,以便我可以创建多个客户端ActorRef并使用它们来创建Akka路由器。
2)Spray客户端API是否提供支持我的用例的任何类型的路由功能?
import akka.actor.ActorSystem
import spray.client.pipelining._
import spray.http._
import scala.concurrent.Future
trait GeoWebClient {
def get(url: String, params: Map[String, String]): Future[String]
}
class GeoSprayWebClient(implicit system: ActorSystem) extends GeoWebClient {
import system.dispatcher
// create a function from HttpRequest to a Future of HttpResponse
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
// create a function to send a GET request and receive a string response
def get(path: String, params: Map[String, String]): Future[String] = {
val uri = Uri(path) withQuery params
val request = Get(uri)
val futureResponse = pipeline(request)
futureResponse.map(_.entity.asString)
}
}
答案 0 :(得分:0)
实现WebClientActor,它调用GeoSprayWebClient来完成您的工作。
创建路由器作为喷雾处理程序:
val handler = context.actorOf( 道具[WebClientActor] .withRouter(RoundRobinRouter(5)),name =" handlerRouter")
通过这种方式,我们有5个客户端实例来做请求。
我也是新手,但不确定是否符合您的目的。仅供参考。
欢呼〜!
答案 1 :(得分:0)
基于this,我得到了ActorRef
def createHttpRESTClient(host: String, port: Int): ActorRef = {
// execution context for future transformations below
import system.dispatcher
implicit val timeout: Timeout = 10 seconds
val ref: Future[ActorRef] = for {
Http.HostConnectorInfo(hostConnector: ActorRef, _) <- IO(Http) ? Http.HostConnectorSetup(host, port)
}
yield {
hostConnector
}
//FIXME - TODO fix this it's really bad. However, We are going to create this only once when we create the actor, so I guess it's okay for now.
Await.result(ref, 10 seconds)
}
这就是我发送请求并使用ActorRef从服务获取响应的方式。
def sendReq(text: String): Future[String] = {
import spray.http._
val params = Map(("key" -> text))
val uri = Uri("/myservice") withQuery params
val request = Get(uri)
//send GET request using the "ask" pattern; the timeout
//TODO - not sure if we can use tell instead of ask here ?
val response: Future[HttpResponse] = restSvrActorRef.ask(request).mapTo[HttpResponse]
log.debug(s"done with sending a request to the REST service")
response.map(_.entity.asString)
}