首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Actorref.tell与inbox.send在Akka中的差异

Actorref.tell与inbox.send在Akka中的差异
EN

Stack Overflow用户
提问于 2014-12-09 14:51:42
回答 2查看 3.4K关注 0票数 8

因此,我开始学习Akka,并在打字机上试用这些例子。因此,Hello应用程序有以下代码:

代码语言:javascript
复制
    import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._

case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)

class Greeter extends Actor {
  var greeting = ""

  def receive = {
    case WhoToGreet(who) => greeting = s"hello, $who"
    case Greet           => sender ! Greeting(greeting) // Send the current greeting back to the sender
  }
}

object HelloAkkaScala extends App {

  // Create the 'helloakka' actor system
  val system = ActorSystem("helloakka")

  // Create the 'greeter' actor
  val greeter = system.actorOf(Props[Greeter], "greeter")

  // Create an "actor-in-a-box"
  val inbox = Inbox.create(system)

  // Tell the 'greeter' to change its 'greeting' message
  greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

  // Ask the 'greeter for the latest 'greeting'
  // Reply should go to the "actor-in-a-box"
  inbox.send(greeter, Greet)

  // Wait 5 seconds for the reply with the 'greeting' message
  val Greeting(message1) = inbox.receive(5.seconds)
  println(s"Greeting: $message1")

  // Change the greeting and ask for it again
  greeter.tell(WhoToGreet("typesafe"), ActorRef.noSender)
  inbox.send(greeter, Greet)
  val Greeting(message2) = inbox.receive(5.seconds)
  println(s"Greeting: $message2")

  val greetPrinter = system.actorOf(Props[GreetPrinter])
  // after zero seconds, send a Greet message every second to the greeter with a sender of the greetPrinter
  system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter)

}

// prints a greeting
class GreetPrinter extends Actor {
  def receive = {
    case Greeting(message) => println(message)
  }
}

现在我只想弄清楚,

代码语言:javascript
复制
greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

代码语言:javascript
复制
inbox.send(greeter, Greet)

根据我的理解,演员在

代码语言:javascript
复制
val inbox = Inbox.create(system)

请有人解释一下Actorref.tell到底做了什么,然后Inbox.send行实现了什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-09 15:28:33

tell (也表示为! )的目的是向参与者发送消息。当参与者通过消息传递进行通信时,tell是用来支持消息传递的机制。它对调用方是异步的,因此一旦调用方调用tell,它们就会与目标参与者实例接收和处理该消息的过程分离。在这个特殊的例子中,代码使用tell来使更好的参与者更新其内部状态。由于这种交互不会导致任何类型的响应(接收方没有将消息发送回发送方以响应此请求),因此这里仅使用tell就足够了。

为了从问候者那里得到问候响应,交互方式略有不同。在此交互中,发送方期望收到响应消息。这种类型的请求/响应交互可以通过ask (即?)传递,其中调用方获得一个Future,当接收方回复时将完成该Future,但是这里没有使用ask。在这个例子中,编码器通过使用一个Inbox来获得请求/响应语义,它可以作为一个参与者来运行,并且它不需要将来。收件箱必须看起来像接收方的ActorRef,允许它用下面的行将响应路由回它:

代码语言:javascript
复制
sender ! Greeting(greeting)

sender()方法返回当前正在处理的消息中发送的人的ActorRefInbox必须能够将自己表示为ActorRef才能工作。但是,正如我前面所说的,您也可以在这里使用ask来实现请求/响应交互。我觉得这只是一个选择的问题。底线是tell用于触发和忘记交互模型,当需要请求/响应语义时,可以使用收件箱(或另一个参与者或ask)。

票数 14
EN

Stack Overflow用户

发布于 2014-12-09 15:25:29

当您执行以下操作时,您将直接处理ActorRef

代码语言:javascript
复制
greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

另一方面,当你使用Inbox时,你处理的不是演员,而是演员。当您不想创建自己的参与者,但仍然希望与其他参与者异步交互时,这是一个很有帮助的场景。请参阅

收件箱是一个像演员一样的对象,从外部询问。它包含一个参与者,其引用可以像往常一样传递给其他参与者,并且可以监视其他参与者的生命周期。

参与者在线程池上运行(使用dispatcher配置)。您可以通过配置或放入代码来决定该参与者使用哪个调度程序来执行它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27381815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档