①Client發送消息,Server接收并響應
本案例隻在本機測試(Server與Client在同一電腦上),也可以在不同電腦上測試(更改位址和端口等資訊,原理都相同,此處就不做介紹)
這裡我單獨寫了一個MessageController專門存放消息類
//服務端發送消息到用戶端
case class ServerMessage(msg:String)
//用戶端向伺服器發送消息
case class ClientMessage(msg:String)
服務端:一個接收處理msg消息,并向發送者回複Confirm消息的Actor
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
class Server extends Actor{
override def receive: Receive = {
case "start" => println("服務端已啟動")
case ClientMessage(msg) => {
println(s"服務端收到:$msg")
//延時3秒(自定義設定,測試用,也可不設定)
Thread.sleep()
//sender傳回給用戶端響應消息
sender ! ServerMessage("服務端已收到消息")
}
}
}
//建立服務端Actor
object Server extends App {
//服務端的IP位址
val host = "192.168.1.86"
//服務端的端口号(自定義設定,隻要端口不被占用即可)
val port =
//通信協定
val conf = ConfigFactory.parseString(
s"""|akka.actor.provider="akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname=$host
|akka.remote.netty.tcp.port=$port
""".stripMargin
)
val actorSystem = ActorSystem("server",conf)
val serverActorRef = actorSystem.actorOf(Props[Server],"server")
serverActorRef ! "start" //啟動本服務端,調用receive方法
}
啟動服務端:
Client端:一個發送msg消息,等待響應之後再繼續發送的Actor
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.io.StdIn
class Client(host:String,port:Int) extends Actor{
//建立服務端代理對象
var serverActorRef:ActorSelection= _ //null,注明值的類型
//在執行receive方法之前要調用的方法
override def preStart(): Unit = {
//[email protected]${host}:${port}/user/server
//第一個server是在服務端actorSystem設定時自己命名的
//host服務端ip位址,port服務端的端口号
//第二個server是在服務端actorSystem.actorOf()設定時自己命名的
serverActorRef = context.actorSelection(s"akka.tcp://[email protected]${host}:${port}/user/server")
}
override def receive: Receive = {
case "start" => println("用戶端已啟動")
case msg:String => {
serverActorRef ! ClientMessage(msg) //在用戶端向服務端發送消息
}
//服務端的響應消息
case ServerMessage(msg) => {
println(s"響應消息:$msg")
}
}
}
//建立用戶端Actor
object Client extends App{
//用戶端的IP位址
val host = "192.168.1.86"
//用戶端的端口号(自定義設定,隻要端口不被占用即可)
val port =
//目的(服務端)位址
val serverHost = "192.168.1.86"
//目的(服務端)端口号
val serverPort =
val conf = ConfigFactory.parseString(
s"""|akka.actor.provider="akka.remote.RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname=$host
|akka.remote.netty.tcp.port=$port
""".stripMargin
)
val clientSystem = ActorSystem("client",conf)
val actorRef = clientSystem.actorOf(Props(new Client(serverHost,serverPort)),"client")
actorRef ! "start" //啟動本用戶端,調用receive方法
while(true){
print("用戶端:")
val str = StdIn.readLine()//強制讀取控制台輸入
actorRef ! str
}
}
用戶端啟動:
服務端顯示: