天天看點

Akka中Actor消息發送與接收(案例一)

①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方法
}
           

啟動服務端:

Akka中Actor消息發送與接收(案例一)

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
  }
}
           

用戶端啟動:

Akka中Actor消息發送與接收(案例一)

服務端顯示:

Akka中Actor消息發送與接收(案例一)