您好我是Scala的新手,我无法弄清楚如何在第二个actor中存储actor引用,以便稍后发送消息。在我的代码中,我尝试向一个actor发送测试消息。当它收到此消息时,它应该将引用(OutputChannel)存储到第二个actor,稍后应该能够向第二个actor发送消息。我不想使用reply(),因为我只需要在调用响应时才需要发送消息。这是代码。谢谢你的帮助!
import scala.actors.Actor
import scala.actors.Actor._
import scala.collection.mutable.ArrayBuffer
import scala.actors.OutputChannel
object testactors {
case object TestMessage
case object Respond
class TestActor(name: String) extends Actor {
private var source : ArrayBuffer[OutputChannel[Any]] = new ArrayBuffer
def act() {
loop {
react{
case TestMessage =>
println("i received a TestMessage " + name)
source += sender
case Respond =>
println("i received a ResponseMessage " + name)
}
}
}
def sendMessage(dest: Actor) = dest ! TestMessage
def respond = {
println("responding... " + name)
source(0) ! Respond
}
}
def main(args: Array[String]) {
val actor1 = new TestActor("one")
actor1.start
val actor2 = new TestActor("two")
actor2.start
actor1.sendMessage(actor2)
Thread.sleep(5000)
actor2.respond
}
}
答案 0 :(得分:4)
1. 您可以创建集中式actor注册表。为了避免重新发明轮子,你可以使用一个好的现有实现 - Akka's Actor Registry (或者,至少,从中受到启发)。
2 您可以避免使用可更改的actor引用列表将其传递给react循环:
case class AddActor(actor: Actor)
case object NotifyAll
class StatefulActor extends Actor {
override def act = loop(Nil)
def loop(actors: List[Actor]):Unit = {
react {
case AddActor(actor) => println("Added new actor")
loop(actor :: actors)
case NotifyAll => println("Notifying actors: " + actors)
actors.foreach(_ ! "Hi!")
loop(actors)
case unknown => println("Unknown message: " + unknown)
loop(actors)
}
}
}
答案 1 :(得分:1)
这样做的一种方法是创建一个Actor Factory,用于存储可以从任何地方抓取的actor。
import scala.actors.Actor
import scala.actors.Actor._
import scala.collection.mutable._
消息可以是对象(没有“有效负载”),也可以是包含数据的类
abstract class Message
case object MessageType1 extends Message
case class MessageType2(str:String) extends Message
以下是一些演员类型。 Actor2实例“在运行中”实例化,并存储在ActorFactory中以供以后使用,就像在主
中显式声明的Actor1实例一样class MyActor1 extends Actor {
def act() {
loop {
react {
case MessageType1 =>
println("MessageType1 received")
ActorFactory.getActor2("B") ! MessageType2("Hello")
case _ =>
}
}
}
}
class MyActor2 extends Actor {
def act() {
loop {
react {
case MessageType2(theString) =>
println(theString+" from actor 2 instance")
case _ =>
}
}
}
}
以下ActorFactory创建并存储actor。在这里,您可以创建一个actor类型的多个实例,并按名称存储。
object ActorFactory {
val actorMap = new HashMap[String,Actor] with SynchronizedMap[String,Actor]
def getActor1(symbol:String): Actor = {
val actor = actorMap.getOrElseUpdate(symbol,new MyActor1().start)
actor
}
def getActor2(symbol:String): Actor = {
val actor = actorMap.getOrElseUpdate(symbol,new MyActor2().start)
actor
}
}
object Test {
def main(args : Array[String]) {
val actor1 = ActorFactory.getActor1("A")
actor1 ! MessageType1
}
}
这是
的输出MessageType1 received
Hello from actor 2 instance