scala – 在Akka-http中获取客户端IP
我正在尝试编写一个Akka HTTP微服务(akka版本2.4.11,Scala版本2.11.8,这两个版本在编写时都是最新版本),它们知道客户端服务的IP(即远程地址),我无法得到这个上班.
我可以创建并运行一个名为“你好!”的服务.使用这样的路线: val routeHello: Route = path("SayHello") { get { entity(as[String]) { body => complete { HttpResponse(entity = HttpEntity("Hello!")) } } } } 我已经构建了一个与上面相似的路由,它被扩展,以便它知道客户端的IP地址. 我注意到我需要编辑application.conf文件并设置’remote-address-header = on’以启用添加包含客户端(远程)IP地址的Remote-Address标头.如果需要,我已经这样做了. 这是路线: val routeHelloIp: Route = path("SayHelloIp") { get { // extractClientIp appears to be working as a filter // instead of an extractor - why? extractClientIp { clientIp => { entity(as[String]) { body => complete { HttpResponse(entity = HttpEntity("Hello!")) } } } } } } 但是,当我运行此路由时,我收到一条消息“无法找到所请求的资源.”. 看起来我在上面的例子中得到了Akka-http DSL语法糖错误.如果你能把我放在正确的道路上,我将不胜感激! 编辑: 我已经尝试了以下程序来回应Ramon的有用答案.不幸的是它没有编译,我无法看到我需要做什么才能使它编译. import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.Http.IncomingConnection import java.net.InetSocketAddress import akka.stream.ActorMaterializer import akka.stream.scaladsl.Sink import akka.http.scaladsl.server.Directives._ import java.net.InetSocketAddress object TestHttp { def main(args: Array[String]) { implicit val system = ActorSystem("my-system") implicit val materializer = ActorMaterializer() // allow connections from any IP val interface = "0.0.0.0" //from the question def createRoute(address: InetSocketAddress) = path("SayHelloIp") { get { extractRequestEntity { entity => entity(as[String]) { body => complete(entity = s"Hello ${address.getAddress().getHostAddress()}") } } } } Http().bind(interface).runWith(Sink foreach { conn => val address = conn.remoteAddress conn.handleWithAsyncHandler(createRoute(address)) }) } } 我有以下build.sbt以确保使用最新版本的Scala和akka-http: import sbt.Keys._ name := "Find my IP" version := "1.0" scalaVersion := "2.11.8" resolvers ++= Seq( "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/" ) libraryDependencies ++= { Seq( "com.typesafe.akka" %% "akka-actor" % "2.4.11","com.typesafe.akka" %% "akka-stream" % "2.4.11","com.typesafe.akka" %% "akka-http-experimental" % "2.4.11","com.typesafe.akka" %% "akka-http-core" % "2.4.11" ) } 我得到以下编译时错误: [error] /Users/tilopa/temp/akka-test/src/main/scala/Test.scala:24: akka.http.scaladsl.model.RequestEntity does not take parameters [error] entity(as[String]) { body => [error] ^ [error] /Users/tilopa/temp/akka-test/src/main/scala/Test.scala:25: reassignment to val [error] complete(entity = s"Hello ${address.getAddress().getHostAddress()}") [error] ^ [error] two errors found [error] (compile:compileIncremental) Compilation failed 解决方法
使用extractClientIp
extractClientIp不适合您,因为发件人尚未指定其中一个必需的标头字段.从documentation:
您只需在发件人中启用正确的设置:
通用解决方案 如果你想让它适用于任何HttpRequest,而不仅仅是那些具有正确头设置的HttpRequest,那么你必须在 import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.Http.IncomingConnection import java.net.InetSocketAddress implicit val actorSystem : ActorSystem = ??? implicit val actorMat = ActorMaterializer() //alow connections from any IP val interface = "0.0.0.0" //from the question def createRoute(address : InetSocketAddress) = path("SayHelloIp") { get { extractRequestEntity { entity => entity(as[String]) { body => complete(entity = s"Hello ${address.getAddress().getHostAddress()}") } } } } Http().bind(interface).runWith(Sink foreach { conn => val address = conn.remoteAddress conn.handleWithAsyncHandler(createRoute(address)) }) 编辑 如评论中所述:因为akka 10.0.13使用conn.handleWith. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |