首页 文章

期货与阿卡的演员一起使用

提问于
浏览
0

我想使用akka远程处理创建服务器/客户端系统 . 首先,我创建一个简单的远程服务器 . (我为了测试目的编写了下面的代码,并澄清了我的概念,所以它确实没有做太多 . )

我希望我的客户端向服务器发送用户名和密码,服务器可以验证并回复 . 起初我创建了一个客户端角色 . 从我的客户端对象,我发送此演员的用户名和密码(我在这里使用未来) . 然后,客户端actor使用另一个未来将此用户名和密码发送到服务器 .

我的代码中的服务器获取用户名和密码并将其打印出来 . 问题是我从服务器上得不到任何回报 . 由于我使用了将来将信息发送到服务器,因此它应该回复结果 . 这是我认为我有一个概念问题的地方 . 通过akka文档并未澄清这一点 . 但我确定我搞砸了一些非常基本的东西 . 服务器代码是:

EDITED after suggestions from TrustNoOne and cmbaxter.

package server


import collection.mutable
import akka.actor._
import com.typesafe.config.ConfigFactory
import shared._
import shared.CaseClass._

object Server extends App { 
val system = ActorSystem("ServerSystem",
     ConfigFactory.parseString("""
   akka {
     actor {
       provider = "akka.remote.RemoteActorRefProvider"
     }
     remote {
       netty.tcp {
         hostname = 127.0.0.1
         port = 5555
       }
     }
   }
 """))
system.actorOf(Props[ServerActorClass], "ServerActor")
}

class ServerActorClass extends Actor {
  def receive = {
    case userPass: UserPass => {
      sender ! verified()
      println(userPass)
    }
    case testMsg: String => println("Got a msg"+ testMsg)
  }
}

客户端代码是:

package client

import ...

object Client extends App {
  val system = ActorSystem("ClientSystem",
    ConfigFactory.parseString("""
   akka {
     actor {
       provider = "akka.remote.RemoteActorRefProvider"
     }
     remote {
       netty.tcp {
         hostname = 127.0.0.1
         port = 0
       }
     }
   }
  """))
  val clientActor = system.actorOf(Props[ClientActor], name = "ClientActor") //the local actor

  implicit val timout = Timeout(50 seconds)
  val f = ask(clientActor, UserPass("a","b"))
  f.onSuccess {
    case GO => println("Got something back from Client actor") //Still doesn't happen!
  }
}


class ClientActor extends Actor {

  // create the remote actor
  val server = context.actorFor("akka.tcp://ServerSystem@127.0.0.1:5555/user/ServerActor")

  implicit val timout = Timeout(1 seconds)

  def receive = {
    case a: String => println("back" + a)
    case a: UserPass => { 
      val f: Future[Any] = (server ? a) 
      f.onSuccess {
        case response: verified => {
          println("Got something back from server") //Does happen now!
          val asker = sender()
          asker ! GO()
        }
        case response: verificationFailed => {
           val asker = sender() 
           asker ! NO()
        }
      }
    }
  } 
}

客户端和服务器共享的案例类:

package shared
case object CaseClass {
  case class verified //Server msg to acknowledge user and pass successful verification
  case class verificationFailed //Server msg saying user pass verification failed
  case class GO
  case class NO
  case class UserPass(user:String, pass:String)

我想知道我做错了什么 . 如果有人可以解释而不是仅仅指出问题,那就太好了,因为我希望学习 .

2 回答

  • 1

    在服务器actor中,您发送的响应如下:

    sender ! CaseClass.verified
    

    您实际上是将"verified"类 companion object 发送回客户端 . 您应该将已验证的类作为案例对象,或者将已验证的 instance 发送回客户端:

    sender ! CaseClass.verified()
    

    您正在执行其他(无关)错误:

    • 在将来的回调中关闭发件人(创建一个本地别名 val replyTo = sender()

    • 不尊重命名约定(大写字母等)

    • 使用已弃用的"actorFor" . 你必须使用actorSelection(参见akka docs)

  • 1

    你正在退出而不等待回应 .

    implicit val timout = Timeout(50 seconds)
    val f: Future[Any] = clientActor ? UserPass("s","a")
    f.onSuccess {
      case GO => println("Got something back from Client actor") //Doesnt happen!
    }
    

    这为回调设置了一个处理程序,但是你的程序就存在了 .

    最低限度,你可以 scala.concurrent.Await.result(f)

相关问题