在Akka中理解自我的信息

时间:2017-08-02 08:38:33

标签: scala akka actor

我正在学习Akka,并且我正在尝试开发一个非常简单的PingPong应用程序。 我想知道为什么我没有所需的输出,即:

=> Pong
=> Ping
=> Pong
=> Ping 
.....

相反,我只得到one => Pong.

游戏应用:

import akka.actor.{ActorSystem, Props}
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.Await

case object Ping
case object Pong

object GamePPApp extends App{
  implicit val timeout = Timeout(2 second)
  val actorSystem = ActorSystem("Ping-Pong")

  val gamer1 = actorSystem.actorOf(Props[GamerActor], "gamer1")

  //  gamer1 ! Ping // I tried this too


  // asking for result from actor
  val future = (gamer1 ?  Ping)
  Await.result(future, 2 seconds)

}

GamerActor:

import akka.actor.Actor

class GamerActor extends Actor{

  override def receive: Receive = {
    case Ping =>
      println(s"=> Pong")
      sender ! Pong
    case Pong =>
      println(s"=> Ping")
      sender ! Ping
  }
}

任何人都可以向我解释原因吗?

[编辑]如果我将发件人更改为自己,它可以工作,但我想知道为什么我不能使用发件人,在我的情况下我认为自己是发件人

谢谢

2 个答案:

答案 0 :(得分:2)

您正在回复sender,而不是self,正如您所希望的那样。这可能只是代码中的一个错字。

答案 1 :(得分:0)

我认为最好的解决方案是将ActorRef作为参数传递:

案例类

case class Ping(actorRef: ActorRef)
case class Pong(actorRef: ActorRef)

发送讯息:

gamer1 ! Ping(gamer1)

GameActor:

class GamerActor extends Actor{

  override def receive: Receive = {
    case Ping(actorRef) =>
      println(s"=> Pong")
      println(actorRef)
      println(self)
      actorRef ! Pong(self)
    case Pong(actorRef) =>
      println(s"=> Ping")
      actorRef ! Ping(self)
  }

}

所以现在自我== actorRef

Actor[akka://Ping-Pong/user/gamer1#56928223]
Actor[akka://Ping-Pong/user/gamer1#56928223]

因为正如评论中所讨论的那样,当我使用ask时? pattern,sender()是/ temp下的临时演员。来自akka doc

  

" /温度"是所有短命系统创造的演员的守护者,   例如那些用于实现ActorRef.ask。

所以使用tell我认为你应该使用ActorRef