无法与Akka建立远程通信
Cannot establish remote communication with Akka
我最近才开始使用 Akka 和 Scala,我正在尝试制作一个实现基本 Akka 远程处理的简单项目。
当我在不远程的情况下尝试以下代码时一切正常,但是当我将数据库 actor 放在远程 actor 系统上但仍在同一台机器中时,出现错误 "deadletters encountered"
这是将数据存储在哈希图中的数据库参与者的代码:
class ActorDB extends Actor {
val data = new HashMap[String, Object]
val log = Logging(context.system, this)
override def receive = {
case Set(key, value) =>
log.info("received the pair:" + key +","+ value)
data.put(key, value)
sender() ! Status.Success
case Get(key) =>
val value = data.get(key)
value match {
case Some(v) =>
log.info("found the pair"+ key + "," + v)
sender() ! v
case None =>
log.info("the key:" + key + ", has no corresponding value in the database")
sender() ! Status.Failure(KeyNotFoundException(key))
}
case _ => Status.Failure(new ClassNotFoundException)
}
}
object Main extends App {
val config = ConfigFactory.parseString(
"""
|akka {
| actor {
| provider = "akka.remote.RemoteActorRefProvider"
| }
| remote {
| enabled-transports = ["akka.remote.netty.tcp"]
| netty.tcp {
| hostname = "127.0.0.1"
| port = 2552
| }
| }
|}
""".stripMargin)
val system = ActorSystem("AkkaIMDB", ConfigFactory.load(config))
val database = system.actorOf(Props(new ActorDB),"ImdbActor")
}
这是客户端的代码
object main extends App {
implicit val timeout = Timeout(1 seconds)
val config = ConfigFactory.parseString(
"""
|akka {
| actor {
| provider = "akka.remote.RemoteActorRefProvider"
| }
| remote {
| enabled-transports = ["akka.remote.netty.tcp"]
| netty.tcp {
| hostname = "127.0.0.1"
| port = 2553
| }
| }
|}
""".stripMargin)
val system = ActorSystem("ClientSystem", ConfigFactory.load(config))
val DBreference = system.actorSelection(s"AkkaIMDB@127.0.0.1:2552/user/ImdbActor")
var key: String = ""
var value: Object = None
println("Type S to send or R to receive a (key value) pair")
StdIn.readLine() match {
case "S" => {
println("print key: ")
key = StdIn.readLine()
println("print value: ")
value = StdIn.readLine()
(DBreference ? messages.Set(key , value)).map({case akka.actor.Status.Success => println("Data added successfully")})
}
case "R" => {
println("print key: ")
key = StdIn.readLine()
(DBreference ? messages.Get(key)).map(
{case akka.actor.Status.Failure(KeyNotFoundException(k)) => println(s"No pair has been found with the key $k")
case v => println(s"the key $key corresponds to the value $v")} )
}
case _ => {}
}
}
您程序中的所有内容都是正确的,除了您 LocalApplication 中的演员选择应该如下所示:
val DBreference = system.actorSelection(s"akka.tcp://AkkaIMDB@127.0.0.1:2552/user/ImdbActor")
更新后它应该可以工作。
永远记住,actor 的 url 以协议名称 akka.tcp://
开头。
我最近才开始使用 Akka 和 Scala,我正在尝试制作一个实现基本 Akka 远程处理的简单项目。
当我在不远程的情况下尝试以下代码时一切正常,但是当我将数据库 actor 放在远程 actor 系统上但仍在同一台机器中时,出现错误 "deadletters encountered"
这是将数据存储在哈希图中的数据库参与者的代码:
class ActorDB extends Actor {
val data = new HashMap[String, Object]
val log = Logging(context.system, this)
override def receive = {
case Set(key, value) =>
log.info("received the pair:" + key +","+ value)
data.put(key, value)
sender() ! Status.Success
case Get(key) =>
val value = data.get(key)
value match {
case Some(v) =>
log.info("found the pair"+ key + "," + v)
sender() ! v
case None =>
log.info("the key:" + key + ", has no corresponding value in the database")
sender() ! Status.Failure(KeyNotFoundException(key))
}
case _ => Status.Failure(new ClassNotFoundException)
}
}
object Main extends App {
val config = ConfigFactory.parseString(
"""
|akka {
| actor {
| provider = "akka.remote.RemoteActorRefProvider"
| }
| remote {
| enabled-transports = ["akka.remote.netty.tcp"]
| netty.tcp {
| hostname = "127.0.0.1"
| port = 2552
| }
| }
|}
""".stripMargin)
val system = ActorSystem("AkkaIMDB", ConfigFactory.load(config))
val database = system.actorOf(Props(new ActorDB),"ImdbActor")
}
这是客户端的代码
object main extends App {
implicit val timeout = Timeout(1 seconds)
val config = ConfigFactory.parseString(
"""
|akka {
| actor {
| provider = "akka.remote.RemoteActorRefProvider"
| }
| remote {
| enabled-transports = ["akka.remote.netty.tcp"]
| netty.tcp {
| hostname = "127.0.0.1"
| port = 2553
| }
| }
|}
""".stripMargin)
val system = ActorSystem("ClientSystem", ConfigFactory.load(config))
val DBreference = system.actorSelection(s"AkkaIMDB@127.0.0.1:2552/user/ImdbActor")
var key: String = ""
var value: Object = None
println("Type S to send or R to receive a (key value) pair")
StdIn.readLine() match {
case "S" => {
println("print key: ")
key = StdIn.readLine()
println("print value: ")
value = StdIn.readLine()
(DBreference ? messages.Set(key , value)).map({case akka.actor.Status.Success => println("Data added successfully")})
}
case "R" => {
println("print key: ")
key = StdIn.readLine()
(DBreference ? messages.Get(key)).map(
{case akka.actor.Status.Failure(KeyNotFoundException(k)) => println(s"No pair has been found with the key $k")
case v => println(s"the key $key corresponds to the value $v")} )
}
case _ => {}
}
}
您程序中的所有内容都是正确的,除了您 LocalApplication 中的演员选择应该如下所示:
val DBreference = system.actorSelection(s"akka.tcp://AkkaIMDB@127.0.0.1:2552/user/ImdbActor")
更新后它应该可以工作。
永远记住,actor 的 url 以协议名称 akka.tcp://
开头。