我正在学习 Akka 2.1 中的远程参与者,并尝试修改Typesafe 提供的反例。我从控制台实现了一个快速'n'dirty UI 来发送滴答声。并退出询问(并显示结果)当前计数。
这个想法是启动一个将运行 Counter actor 的主节点和一些将通过远程处理向其发送消息的客户端节点。但是,我想通过配置和对代码的最小更改来实现这一点。因此,通过更改配置,可以使用本地演员。
我发现这个关于类似问题的博客条目,即使有许多实例正在运行,所有 API 调用都必须通过一个参与者。
我写了类似的配置,但我无法让它工作。我当前的代码确实使用了远程处理,但它在主节点上为每个新节点创建了一个新的参与者,如果没有明确地给它路径(并且无视配置点),我无法让它连接到现有参与者。然而,这不是我想要的,因为状态不能以这种方式在 JVM 之间共享。
可通过 git repo获得完整的可运行代码
这是我的配置文件
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
deployment {
/counter {
remote = "akka://ticker@127.0.0.1:2552"
}
}
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
log-sent-messages = on
netty {
hostname = "127.0.0.1"
}
}
}
和完整的来源
import akka.actor._
import akka.pattern.ask
import scala.concurrent.duration._
import akka.util.Timeout
import scala.util._
case object Tick
case object Get
class Counter extends Actor {
var count = 0
val id = math.random.toString.substring(2)
println(s"\nmy name is $id\ni'm at ${self.path}\n")
def log(s: String) = println(s"$id: $s")
def receive = {
case Tick =>
count += 1
log(s"got a tick, now at $count")
case Get =>
sender ! count
log(s"asked for count, replied with $count")
}
}
object AkkaProjectInScala extends App {
val system = ActorSystem("ticker")
implicit val ec = system.dispatcher
val counter = system.actorOf(Props[Counter], "counter")
def step {
print("tick or quit? ")
readLine() match {
case "tick" => counter ! Tick
case "quit" => return
case _ =>
}
step
}
step
implicit val timeout = Timeout(5.seconds)
val f = counter ? Get
f onComplete {
case Failure(e) => throw e
case Success(count) => println("Count is " + count)
}
system.shutdown()
}
我用sbt run
和在另一个窗口sbt run -Dakka.remote.netty.port=0
中运行它。