Не удается установить удаленную связь с Akka - PullRequest
0 голосов
/ 07 ноября 2018

Я только недавно начал использовать Akka и Scala, и я пытаюсь создать простой проект, который реализует базовое удаленное взаимодействие Akka.

Когда я пытаюсь выполнить следующий код без удаленного взаимодействия, все работает нормально, однако, когда я помещаю субъект базы данных в удаленную систему субъекта, но все еще на той же машине, у меня появляется ошибка "встретились тупики"

вот код субъекта базы данных, который хранит данные внутри хэш-карты:

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 _ => {}
    }

}

1 Ответ

0 голосов
/ 08 ноября 2018

Все в вашей программе правильно, за исключением того, что выбор актера в вашем LocalApplication должен быть ниже:

val DBreference = system.actorSelection(s"akka.tcp://AkkaIMDB@127.0.0.1:2552/user/ImdbActor")

После обновления это должно работать.

Всегда помните, URL-адрес актера начинается с имени протокола akka.tcp://.

...