①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(3000)
//sender返回给客户端响应消息
sender ! ServerMessage("服务端已收到消息")
}
}
}
//创建服务端Actor
object Server extends App {
//服务端的IP地址
val host = "192.168.1.86"
//服务端的端口号(自定义设置,只要端口不被占用即可)
val port = 5555
//通信协议
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 = {
//server@${host}:${port}/user/server
//第一个server是在服务端actorSystem设置时自己命名的
//host服务端ip地址,port服务端的端口号
//第二个server是在服务端actorSystem.actorOf()设置时自己命名的
serverActorRef = context.actorSelection(s"akka.tcp://server@${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 = 7777
//目的(服务端)地址
val serverHost = "192.168.1.86"
//目的(服务端)端口号
val serverPort = 5555
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
}
}
客户端启动:
服务端显示: