我如何从 finagle 客户端发出带有参数的请求?

How I can make a request with params from finagle client?

我正在开始使用 Finagle 服务器 (twitter/finagle):

import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._

object Server extends App {
  val service = new Service[HttpRequest, HttpResponse] {
    def apply(req: HttpRequest): Future[HttpResponse] =
      Future.value(new DefaultHttpResponse(
        req.getProtocolVersion, HttpResponseStatus.OK))
  }
  val server = Http.serve(":8080", service)
  Await.ready(server)
}

客户(twitter/finagle):

import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._

object Client extends App {
  val client: Service[HttpRequest, HttpResponse] =
    Http.newService("localhost:8080")
  val request =  new DefaultHttpRequest(
    HttpVersion.HTTP_1_1, HttpMethod.GET, "/")
  val response: Future[HttpResponse] = client(request)
  response onSuccess { resp: HttpResponse =>
    println("GET success: " + resp)
  }
  Await.ready(response)
}

如何从客户端向服务器发送类似Map("data_id" -> 5)的数据?我在服务器的什么地方收到它?我必须向服务器添加回调吗?

我搜索没找到。如果你能给我一个link和一个例子就足够了。

Finagle 是一个非常精简的库。这意味着您必须自己处理大部分 "magic"。

为了使用来自客户端的参数发出请求,我使用了这些辅助方法:

  def buildUri(base: String, path: String, params: Map[String, String] = Map.empty): String = {
    val p = if (params.isEmpty) ""
    else params map { case (k,v) => urlEncode(k) + "=" + urlEncode(v) } mkString ("?", "&", "")
    base + path + p
  }

  def urlEncode(url: String): String = URLEncoder.encode(url, "UTF-8")

然后我这样称呼它:

val url = buildUri(baseAddress, path, defaultParams ++ params)
val req = RequestBuilder().url(url).setHeader("Accept", "*/*").buildGet
client(req)

至于服务器你必须做基本相同的事情并手动解析参数。使用 java.net.URI 甚至 org.jboss.netty.handler.codec.http.QueryStringDecoder.

当然你也可以使用URIQueryStringEncoder来编码,而不是使用我的辅助方法。

就是说,如果您想在更高级别上这样做,您可以使用 Finagle 之上的这些库之一: