如何在访问 URL 时向演员发送告知消息?

How to send actor a tell message when a URL is accessed?

我正在尝试将 Akka HTTP 与 Actors 连接起来。我有一个简单的演员,它接收 "hello" 并发回 "Hello world"

class TestActor extends Actor{
  def receive={
    case "hello"=>{
      sender!"Hello World"
    }
  }
}

我定义了以下路线:

object Main extends App{

  val route1: Route =
    get {
      path("hello") {
        complete {
          "This is hello"
        }
      }
    }

  implicit val materializer = ActorMaterializer()
  implicit val system = ActorSystem("h")
  Http().bindAndHandle(route1, "localhost", 8185)
}

我想在 URL 中访问 /hello 时向 TestActor 发送一条告诉消息,并显示消息 "Hello World" 作为响应。我该怎么做?

第 1 步 - 创建 Actor 实例。

第 2 步 - 获取对它的引用。

第 3 步 - 向其发送消息

class TestActor extends Actor{
  def receive = {
    case "hello" => {
      sender() ! "Hello World"
    }
  }
}

object TestActor {
  def props: Props = Props(classOf[TestActor])
}

现在……

import akka.pattern.ask

object Main extends App{

  val actorSystem = ActorSystem("actor-system")

  implicit val implicitActorSystem = actorSystem
  implicit val materializer = ActorMaterializer()

  // actually create the actor
  val testActor = actorSystem.actorOf(TestActor.props, "test-actor")

  val route1: Route =
    get {
      path("hello") {
        // get actor's reference using selection
        val testActorSelection = actorSystem.actorSelection("/user/test-actor")
        // now send using selection
        val responseFuture = testActorSelection ? "hello"

        // or send using the "val testActor" reference which we already have
        val responseFuture = testActor ? "hello"

        onComplete(responseFuture) {
          case Success(message) => complete(message)
          case Failure(ex) => complete(ex.message)
        }
      }
    }

  Http().bindAndHandle(route1, "localhost", 8185)
}

你有两个选择。选项 1 是使用 "Ask" 模式。您可以 "ask" 像下面这样的演员。 "Ask" returns 您可以映射并进行其他操作的未来。您也可以用 future 完成请求。这里的警告是它需要超时。你必须配置一个超时才能工作,这在一个更大的项目中维护起来会很乏味。

implicit val timeout: Timeout = 2 seconds
val responseFuture = (actor ? message).mapTo[String] // This will return a Future[String]
complete(responseFuture)

选项 2 是使用 "Tell" 模式。这比 "ask" 模式更受欢迎。您可以阅读此 here。您需要将请求上下文传递给新参与者并使用该新参与者完成请求。您将执行如下操作。

val testActor = actorSystem.actorOf(Props(classOf[TestActor], reqContext), "test-actor")

然后在 testActor 中,您将完成请求。您可以查看 here and here 以获取有关此模式的更多信息。