简体   繁体   中英

Not able to invoke Remote Actor

I wrote this code to create a remote actor

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")
  }
}

I started my server using activator run and this printed the message

[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]

but now when i try to call my remote actor using this client code

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}")
    })
  }
}

it throws an error message

[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'.

My Full code is available at

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

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

EDIT: I solved the problem based on the suggestion given by Mustafa Simov. The client side needed this configuration file

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

Then you create the actor using

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

I have looked at your client code and I think it is just a configuration problem. In order to use akka-remoting, you must configure your client too. So you must create an application.conf for client ActorSystem as you created for server.

Akka remoting is peer-to-peer and not really a good fit for client-server

Because of this both sides in remoting must be able to connect to the other side, as either of them can initiate communication. Both of your applications therefore needs to configure a remoting actor-ref provider and host+port pair that the other node can connect through. You can read details about how to do this in the akka docs here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM