我想使用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 回答
在服务器actor中,您发送的响应如下:
您实际上是将"verified"类 companion object 发送回客户端 . 您应该将已验证的类作为案例对象,或者将已验证的 instance 发送回客户端:
您正在执行其他(无关)错误:
在将来的回调中关闭发件人(创建一个本地别名
val replyTo = sender()
)不尊重命名约定(大写字母等)
使用已弃用的"actorFor" . 你必须使用actorSelection(参见akka docs)
你正在退出而不等待回应 .
这为回调设置了一个处理程序,但是你的程序就存在了 .
最低限度,你可以
scala.concurrent.Await.result(f)