4

假设我问(?)同一个演员的两个回答。它存储发件人以供以后使用。稍后,它会将消息返回给发件人。我们得到了正确的发件人(散列到消息的那个),但是 Akka 怎么知道响应是针对哪条消息的呢?ActorRef 中是否有指示每个响应的消息的内容?

是“频道”吗?

我想更好地了解底层技术。我会尝试同时阅读源代码,但我认为这是一个非常好的问题。

代码示例:

class TestActor
[...]
def onReceive = {
case r: MessageToGoOut ⇒
      messageId += 1
      val requestId = clientConnectionId + messageId 
      senders += (requestId -> sender) //store sender for later
      anotherActor ! WrappedUpMessage(requestId, MessageOut))

case m: MessageToGoBackToSender ⇒
          val requestId = m.requestId
          senders.get(requestId) map { client ⇒
            client ! Response(m.message)
            senders -= requestId
          }
}


val futures = for(i <- 1 to 100) yield testActor ? new MessageToGoOut ("HEYO!" + i)

现在,akka 如何确保消息返回给正确的参与者?

4

1 回答 1

3

每个Actor人都有一条路。从内部Actor,你可以说:

context.path

从外面Actor看,如果你有一个ActorRef,你可以说:

ref.path

如果该路径是该单个参与者实例的地址,那么我认为内部路由系统将消息路由到参与者实例的邮箱。当您在 之外时Actor,就像您在示例中循环和发送消息时一样,当您使用ask( ?) 时,会启动一个临时Actor实例,以便当Actor接收到消息的 需要响应时,它有一个路径回应。这可能有点过于简单化,并且可能不是您正在寻找的详细程度,所以如果我错过了您问题的要点,我深表歉意。

此外, an 中的sendervarActor是 an ActorRef,因此它具有路径,因此您可以路由回它。

当 aFuture被创建时,akka 会创建一个临时的(和可寻址的)Actor,它基本上是为它服务的Future。当那个临时Actor发送给另一个Actor时,它ActorRef作为发送者被传输。当接收参与者正在处理该特定消息时,发送者var被设置ActorRef为该临时参与者,这意味着您有一个地址要响应。即使您决定稍后保留该发件人,您仍然有一个地址可以发送回并最终完成Future临时参与者正在服务的地址。关键是,只要你有一个ActorRef,无论是请求还是响应,它所做的就是将消息路由到那个路径ActorRef

Ask (?)tell (!)没有太大的不同。 Ask基本上是tell发送者期望接收者将tell消息返回给它的地方。

于 2013-04-25T21:54:56.020 回答