Akka中Actorref.tell和inbox.send之间的区别 [英] Difference between Actorref.tell and inbox.send in Akka

查看:801
本文介绍了Akka中Actorref.tell和inbox.send之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我开始学习Akka并尝试使用Typesafe中的示例。
因此,Hello Akka应用程序具有以下代码:

So i have started learning Akka and trying out the examples in typesafe. So the Hello Akka app has the following code :

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

现在我被困在了解什么是,

Now i am stuck in understanding what is the difference between ,

greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

inbox.send(greeter, Greet)

据我所知,演员在

val inbox = Inbox.create(system)

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

Can someone please explain what exactly does the Actorref.tell do and then what is exactly achieved by the Inbox.send line.

推荐答案

tell 的目的,也表示为是向演员发送消息。当参与者通过消息传递进行通信时, tell 是用于支持该消息传递的机制。它与调用方是异步的,因此一旦调用方调用 tell ,目标操作者实例便将其与该消息的接收和处理分离。在此特定示例中,代码使用tell来使迎宾演员更新其内部状态。由于此交互不会导致任何形式的响应(接收方未响应此请求而未将消息发送回发送方),因此仅 tell 就足够了

The purpose of tell, also represented as ! is to send a message to an actor. As actors communicate via message passing, tell is the mechanism used to support that message passing. It is asynchronous to the caller, so that once the caller calls tell, they are decoupled from the receiving and processing of that message by the target actor instance. In this particular example, the code is using tell to cause the greeter actor to update its internal state. As this interaction does not result in a response of any kind (the receiving actor is not sending a message back to the sender in response to this request), tell alone is sufficient here.

要获得来自招呼者的问候,互动方式略有不同。在这种交互中,发件人期望收到响应消息。这种类型的请求/响应交互可以通过 ask (即)进行处理,在此过程中,调用者获得了 Future 返回,当接收方回复时将完成,但是此处未使用 ask 。在此示例中,编码人员使用收件箱来获取请求/响应的语义,而该行为可以充当参与者,从而消除了对期货的需求。收件箱必须看起来像 ActorRef 到接收者,以便它可以通过以下行将响应路由回它:

For getting a greeting response from the greeter, the interaction is slightly different. In this interaction, the sender is expecting a response message. This type of request/response interaction can be handed via ask (i.e. ?) in which the caller gets a Future back that will be completed when the receiver replies but ask was not used here. In this example, the coder got the request/response semantic by using an Inbox instead which can behave as an actor and it eliminates the need for futures. The inbox must look like an ActorRef to the receiver allowing it to route a response back to it with the following line:

sender ! Greeting(greeting)

sender()方法返回当前正在处理的消息中发送的任何人的 ActorRef 收件箱必须能够将自己表示为 ActorRef 才能正常工作。但是正如我之前所说,您也可以在此处使用 ask 来使请求/响应交互正常工作。我认为这只是选择问题。最重要的是, tell 用于解雇互动模型和收件箱(或另一个参与者或 )可以在需要请求/响应语义时使用。

The sender() method returns the ActorRef of whoever sent in the message being currently processed. The Inbox must be able to represent itself as an ActorRef for this to work. But as I said earlier, you also could have used ask here to get the request/response interaction working. I think it's just a matter of choice. The bottom line is that tell is used for the fire and forget interaction model and the inbox (or another actor or ask) can be used when a request/response semantic is needed.

这篇关于Akka中Actorref.tell和inbox.send之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆