Akka-http中获取客户端IP

2023-12-31

我正在尝试编写一个 Akka HTTP 微服务(akka 版本 2.4.11,Scala 版本 2.11.8,在撰写本文时都是最新版本),它知道客户端服务的 IP(即远程地址),但我无法得到这个上班。

我可以创建并运行一个显示“Hello!”的服务使用这样的路线:

    val routeHello: Route = path("SayHello") {
      get {
        entity(as[String]) {
          body => complete {
            HttpResponse(entity = HttpEntity("Hello!"))
          }
        }
      }
    }

我构建了一条与上面类似的路由,对其进行了扩展,以便它能够了解客户端的 IP 地址。

我注意到我需要编辑 application.conf 文件并设置“remote-address-header = on”以启用添加Remote-Address标头保存客户端(远程)IP 地址。我已经这样做了,以防万一需要。

这是路线:

    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 语法糖。如果您能让我走上正确的道路,我将不胜感激!

EDIT:

我已经尝试了以下程序来回应拉蒙的有用答案。不幸的是它无法编译,我看不到需要做什么才能编译它。

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不适合您,因为发件人未指定必需的标头字段之一。来自文档 http://doc.akka.io/docs/akka/2.4/scala/http/routing-dsl/directives/misc-directives/extractClientIP.html#extractclientip:

提供 X-Forwarded-For、Remote-Address 或 X-Real-IP 的值 headers 作为 RemoteAddress 的实例。

您只需在发件人中打开正确的设置:

akka-http 服务器引擎将 Remote-Address 标头添加到每个 如果相应的设置自动请求 akka.http.server.remote-address-header 设置为 on。默认情况下是 设置为关闭。

通用解决方案

如果您希望它适用于任何 HttpRequest,而不仅仅是具有正确标头设置的 HttpRequest,那么您必须使用bind上的方法HttpExt http://doc.akka.io/api/akka/2.4/?_ga=1.42089507.723935664.1469018756#akka.http.scaladsl.HttpExt代替bindAndHandle:

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))
})

Edit

正如评论中所述:自从 akka10.0.13 use conn.handleWith.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Akka-http中获取客户端IP 的相关文章

随机推荐

  • 打印网页的安全宽度(以像素为单位)?

    打印网页的安全宽度 以像素为单位 是多少 我的页面包含大图像 我想确保它们在打印时不会被剪切 我了解不同的浏览器边距和 US Letter DIN A4 纸张尺寸 所以我们得到了标准的字母大小和一些默认的 DPI 值 但我可以将这些转换成p
  • 声明装饰器

    我们有一些如下所示的代码 from third party library import foo for n in range 3 try foo args break except print Retry i 3 n 我想使用装饰器 让我
  • std::search 和 std::find_first_of 之间的区别

    我试图理解之间的区别std search and std find first of 他们有相同的原型 template
  • 如何查找用户使用了哪个 Cmdlet 别名?

    如果您发现这是一个非常蹩脚的问题 请原谅 但由于我正在学习 Powershell 所以我需要问一下 这是发布的问题和收到的答案的下一部分here https stackoverflow com a 13584769 1095246 我有一个
  • Apache HttpClient 4.5:连接重置

    我正在使用 httpClient 版本 4 5 来连接我们的外部供应商站点 我们不需要任何连接池或持久连接 因此我使用 BasicHttpClientConnectionManager 来创建 HttpClient 这对于最少数量的请求来说
  • 如何修复 Python 中的 ValueError: Too much value to unpack”?

    我正在尝试使用文本文件 out3 txt 的内容填充字典 我的文本文件的形式为 vs 14100 mln 11491 the 7973 cts 7757 等等 我想要我的字典answer其形式为 answer vs 14100 answer
  • 如何使用AFNetworking 3.0下载文件并保存到本地?

    在我的项目中 我需要下载一个小视频 在之前的版本中 我使用的是 void downloadFileURL NSString aUrl savePath NSString aSavePath fileName NSString aFileNa
  • Linux调度程序如何在多核处理器上调度进程?

    多核处理器利用线程级并行性 这意味着多个线程并行运行 假设一个进程只有一个线程 那么在该进程执行过程中 其他核心是否保持空闲状态 在Linux系统中 调度程序将进程和线程都视为一个任务 它在调度时不区分进程和线程 那么 这是否意味着不同的核
  • 从 U3 dtype 到 ascii 的转换

    我正在从 mat 文件读取数据 数据采用 numpy 数组的形式 array u ABT dtype
  • 列出磁盘上的所有分区[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在用 C 为 Windows 不支持的文件系统创建一个实用程序 这意味着我不能只访问驱动器 我需要
  • Android API级别30,无法再从Android arp表获取wifi网络设备MAC地址

    我有一个小型网络扫描仪应用程序 它需要查找响应 ping 等的扫描设备的 MAC 地址 很快 Google 需要 targetSdkVersion 30 这意味着在没有响应的情况下无法再以任何方式访问 arp 表 没有权限 以前我用过 bu
  • 错误:您的要求无法解析为一组可安装的软件包。(在服务器上)

    我的项目使用 laravel 5 3 现在我正在将其设置到服务器 这样做时出现了问题 我陷入了这个错误点 当我跑步时 作曲家安装 no dev 命令出现以下错误 Problem 1 Installation request for fgro
  • 在 IE9 中使用 cookie 发出 CORS 请求?

    在 IE9 中 我尝试使用 cookie 发出跨源请求 但是 即使我将 Access Control Allow Origin Access Control Allow Credentials Access Control Allow Me
  • 从 Excel 导出注释

    有没有办法从 Excel 工作表中导出注释以及单元格值 以下是返回工作表中所有注释的函数示例 Sub CreateCommentsSummary Dim rgComments As Range rgCell As Range rgOutpu
  • Xcode 9 - 链接器命令失败,退出代码为 1

    编译应用程序时出现以下错误 使用比以前的文件 4 0 旧版本的 Swift 语言 3 0 编译的文件 请你帮助我好吗 使用 xcworkspace 来构建而不是 xcproject 当使用 Cocoapods 并且您从 xcproject
  • 如何自动发现 WCF 服务?

    有没有办法自动发现网络中特定的 WCF 服务 如果可能的话 我不想用地址配置我的客户端 是的 有一种自动发现服务的方法 NET 4 0 包含一个称为 WCF Discovery 的功能 它基于 WS Discovery 协议 这里有一个显示
  • sed -i 选项有什么作用?

    我正在调试 shell 脚本并尝试找出以下命令执行的任务 sed i 1 999d home org user data txt 我需要更改此命令 因为它失败并出现以下错误 illegal option sed i 但在更改之前 我需要了解
  • 在 Laravel 中动态使用模型

    在我的 laravel 项目中 我创建了一个控制器 用于从调用同一控制器的所有刀片中删除项目 通过传递动态 id 和模型名称 但显示找不到类的错误 例如 未找到 用户 类 如何添加使用用户 动态地在我的控制器中编写代码 namespace
  • 如何设置 hy 项目以便可以使用 pytest 进行测试

    我正在尝试使用 pytest 测试 hy 项目 但 pytest 发现我的测试时遇到问题 需要做什么才能让 pytest 能够获取用 hy 编写的测试 我假设测试可以用 hy 编写并由 pytest 发现 因为native tests主要
  • Akka-http中获取客户端IP

    我正在尝试编写一个 Akka HTTP 微服务 akka 版本 2 4 11 Scala 版本 2 11 8 在撰写本文时都是最新版本 它知道客户端服务的 IP 即远程地址 但我无法得到这个上班 我可以创建并运行一个显示 Hello 的服务