【问题标题】:How to send actor a tell message when a URL is accessed?访问 URL 时如何向参与者发送告诉消息?
【发布时间】:2017-01-10 21:34:26
【问题描述】:

我正在尝试将 Akka HTTP 与 Actor 连接起来。我有一个简单的演员,它接收“你好”并发回“你好世界”

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”作为响应。我该怎么做?

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    你有两个选择。选项 1 是使用“询问”模式。你可以像下面这样“问”演员。 “询问”返回一个未来,您可以对其进行映射并执行其他操作。你也可以用future完成请求。这里需要注意的是它需要超时。您必须为此配置超时才能工作,这在大型项目中可能会变得乏味。

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

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

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

    并且在 testActor 中,您将完成请求。您可以查看herehere 以获取有关此模式的更多信息。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我稍微修改了代码和我的要求。演员正在发回消息而不是打印它。此消息需要显示为响应。
      • 但我不想问。我希望它被告知。
      猜你喜欢
      • 1970-01-01
      • 2021-02-23
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多