无法调用远程Actor

时间:2016-01-11 02:29:59

标签: scala akka

我写了这段代码来创建一个远程演员

object Main extends App {
  val system = ActorSystem("keyvalue")
  system.actorOf(Props[KeyValueActor], name = "keyvalue-db")
}

class KeyValueActor extends Actor {
  val map = new util.HashMap[String, Object]
  val log = Logging(context.system, this)

  override def receive = {
    case SetRequest(key, value) => {
      log.info(s"received set request key ${key} value ${value}")
      map.put(key, value)
      sender() ! Status.Success
    }
    case GetRequest(key) => log.info(s"recieved get request ${key}")
      sender() ! KeyValue(map.get(key))
    case _=> log.info("unknown message")
  }
}

我使用activator run启动了我的服务器,并打印了消息

[info] Running com.abhi.akka.Main
[INFO] [01/10/2016 20:21:52.461] [run-main-0] [Remoting] Starting remoting
[INFO] [01/10/2016 20:21:52.617] [run-main-0] [Remoting] Remoting started;
listening on addresses :[akka.tcp://keyvalue@127.0.0.1:2552]
[INFO] [01/10/2016 20:21:52.619] [run-main-0] [Remoting] 
Remoting now listens on addresses: [akka.tcp://keyvalue@127.0.0.1:2552]

但现在当我尝试使用此客户端代码调用我的远程actor时

object KeyValueClient {

  def main(args: Array[String]) : Unit = {
    implicit val system = ActorSystem("LocalFileSystem")
    implicit val timeout = Timeout(2 seconds)
    val keyValueActorRef = system.actorSelection("akka.tcp://keyvalue@127.0.0.1:2552/user/keyvalue-db")
    keyValueActorRef ! SetRequest("foo", "bar")
    (keyValueActorRef ? GetRequest("foo")).onSuccess({
      case x : KeyValue => println(s"got value ${x.value}")
    })
  }
}

它会抛出错误消息

[INFO] [01/10/2016 20:25:33.345] [LocalFileSystem-akka.actor.default-dispatcher-2] [akka://LocalFileSystem/deadLetters] Message [com.abhi.akka.messages.SetRequest] from Actor[akka://LocalFileSystem/deadLetters] to Actor[akka://LocalFileSystem/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [01/10/2016 20:25:33.346] [LocalFileSystem-akka.actor.default-dispatcher-2] [akka://LocalFileSystem/deadLetters] Message [com.abhi.akka.messages.GetRequest] from Actor[akka://LocalFileSystem/temp/$a] to Actor[akka://LocalFileSystem/deadLetters] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

我的完整代码可在

找到

https://github.com/abhitechdojo/keyvaluedb.git

https://github.com/abhitechdojo/keyvalueclient.git

编辑:我根据Mustafa Simov的建议解决了这个问题。客户端需要此配置文件

akka {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
    deployment {
      /keyvalue-db {
        remote = "akka.tcp://keyvalue@127.0.0.1:2552"
      }
    }
  }
}

然后使用

创建actor
val actor = system.actorOf(Props[KeyValueActor], "keyvalue-db")

2 个答案:

答案 0 :(得分:1)

我查看了您的客户端代码,我认为这只是一个配置问题。要使用akka-remoting,您还必须配置您的客户端。因此,您必须为您为服务器创建的客户端ActorSystem创建application.conf

答案 1 :(得分:0)

Akka远程处理是点对点的,not really a good fit for client-server

因此,远程处理的双方必须能够连接到另一侧,因为它们中的任何一方都可以启动通信。因此,两个应用程序都需要配置远程处理actor-ref提供程序和另一个节点可以连接的主机+端口对。您可以阅读details about how to do this in the akka docs here