【发布时间】:2015-12-25 10:31:31
【问题描述】:
我正在尝试向SmallestMailboxPool 中远程创建的演员发送ask 的内容,但我似乎从未得到回应。我的感觉是,这是因为我将消息发送到Router,但Routee 是正在响应的演员 - 不知道 Akka 询问的确切内部情况,我可以想象回复必须与 where 相同消息被发送到。另一方面,这似乎太简陋了,我无法想象它不会起作用。
我正在使用 Play framework 2.3.x 和 Akka remote 2.3.4
演员设置 我有 2 台机器,这些机器上有 2 个演员。我会尽量使示例保持简短。
机器 A/演员 A
实际询问是在机器 A 上发起的,我添加了一些 println 语句来显示参与者地址。代码如下。
class ActorA(remoteActor: ActorRef) extends Actor with ActorLogging {
...
def receive() = {
case a: String => {
println("Remote actor: " + remoteActor)
println("Self: " + self)
// This is where I get a timeout because I never get a reply
Await.result((remoteActor ? a), timeout.duration)
}
}
}
我在机器 A 上得到的输出如下:
Remote actor: Actor[akka.tcp://application@192.168.0.101:2552/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
Self: Actor[akka://application/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]
请注意,我传递给 ActorA 的 ActorRef(称为 remoteActor)是我在机器 B(见下文)上创建的 val actorRef,具有 MailboxPool。
机器 B/演员 B
在机器 B 上,我有一个 Actor B,它在 SmallestMailboxPool 中创建,并从 Actor A(通过路由器)接收消息,然后回复。
创建如下:
// Creation of the mailbox/Router
val actorRef = Akka.system.actorOf(
SmallestMailboxPool(1).props(
// sourceActor is the actorRef of Actor A, living on machine A
Props(ActorB, sourceActor)
),
name = java.util.UUID.randomUUID.toString
)
println("Mailbox is: " + actorRef)
实际的 Actor B 执行以下操作:
class ActorB(sourceActor: ActorRef) extends Actor with ActorLogging {
println("I am: " + self)
def receive() = {
case a: String => {
println("I got data from " + sender)
println("Sending it back to: " + sourceActor)
sourceActor ! d
}
}
}
我从演员 B 那里得到的是以下打印行:
Mailbox is Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
I am Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3/$a#46262703]
I got data from Actor[akka.tcp://application@192.168.0.132:2552/temp/$e]
I am sending it back to: Actor[akka.tcp://application@192.168.0.132:2552/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]
所以我不明白为什么 ActorA 的演员地址在 ActorB 这边显示为temp/$e。还可以看出,ActorB 从 ActorA 获取消息,ActorA 实际将消息发送到 Router。 ActorB 然后正确地尝试回复 ActorA,但它总是超时 - 这是因为 ActorB 的 ActorRef/地址与路由器/邮箱不同吗?我也尝试发回sender,而不是给定参数的sourceActor,但无济于事。
我知道我可以向邮箱询问其所有路由并直接向他们发送询问(尚未尝试过),但这违背了 MailboxPool 的全部目的。 编辑:试过了,也没用
编辑:
整个故事中最奇怪的是,如果我在机器 A 上创建 ActorB(例如,不是远程),一切正常 - 我可以询问路由器的 ActorRef,我得到了正确的答复。在机器 B 上创建 ActorB 后,我再也没有收到回复。我还试图看看如果我只是 tell ActorB 并继续 ActorA 而不关心结果会发生什么。然后发生的事情是我确实从ActorB 收到消息,这应该是我对原始问题的回应......因此ActorB 完全能够发送回ActorA 但对于某些人原因,Akka 不会用它来回答我原来的问题...
【问题讨论】:
-
您能否提供生成您传递给 ActorA 的 ActorRef 的代码?另外,
remoteGenerator是什么? -
我修正了错字,
remoteGenerator是 remoteActor。我还添加了用于从中获取 remoteActor 的代码(我传递给 ActorA 的 ActorRef) - 这是我在机器 B 上执行的val actorRef = ...的结果 -
您能否说明
sourceActor和remoteActor是如何创建的?即val sourceActor = ...和val remoteActor = ...。
标签: scala playframework akka remoting