Scala入门五——使用Akka编写rpc入门案例

依赖

dependencies {
    // https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor
    compile group: 'com.typesafe.akka', name: 'akka-actor_2.12', version: '2.5.11'
    // https://mvnrepository.com/artifact/com.typesafe.akka/akka-stream
    compile group: 'com.typesafe.akka', name: 'akka-stream_2.12', version: '2.5.12'
    // https://mvnrepository.com/artifact/com.typesafe.akka/akka-http
    compile group: 'com.typesafe.akka', name: 'akka-http_2.12', version: '10.1.1'

    // https://mvnrepository.com/artifact/com.typesafe.akka/akka-remote
    compile group: 'com.typesafe.akka', name: 'akka-remote_2.12', version: '2.5.12'

    compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.6' //添加scala基本库
    testCompile group: 'org.scalatest', name: 'scalatest_2.11', version: '3.0.5' //添加scala测试相关的依赖
}

Master代码

package com.ghq.rpc

import akka.actor.{ ActorSystem, Actor, ActorRef, Props, PoisonPill }
import language.postfixOps
import com.typesafe.config.ConfigFactory
import akka.event.Logging
/**
  * @author : Administrator
  */
class Master extends Actor{
  val log = Logging(context.system, this)

  println("constructor invoked")

  override def preStart(): Unit = {
    println("preStart(): Unit")
  }

  override def receive: Receive = {
    case "connect" => {
      log.info("a client connected")
      sender ! "reply"
    }

    case "hello" => log.info("hello message")
  }
}

object Master {
  def main(args: Array[String]): Unit = {

    val host = "127.0.0.1"
    val port = 8888

    val str =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "$host"
         |akka.remote.netty.tcp.port = "$port"
       """.stripMargin
    val config = ConfigFactory.parseString(str)
    //获取ActorSystem,用来创建并监控Actor
    //MasterSystem 为ActorSystem 的名字
    val actorSystem = ActorSystem.apply("MasterSystem",config)

    //创建Actor
    val master = actorSystem.actorOf(Props[Master],"Master")
    master ! "hello"

    //actorSystem.
  }
}

运行Master结果如下:

[INFO] [09/17/2018 10:43:45.521] [main] [akka.remote.Remoting] Starting remoting
[INFO] [09/17/2018 10:43:45.868] [main] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://[email protected]:8888]
[INFO] [09/17/2018 10:43:45.868] [main] [akka.remote.Remoting] Remoting now listens on addresses: [akka.tcp://[email protected]:8888]
constructor invoked
preStart(): Unit
[INFO] [09/17/2018 10:43:46.071] [MasterSystem-akka.actor.default-dispatcher-14] [akka.tcp://[email protected]:8888/user/Master] hello message

Worker代码

package com.ghq.rpc

import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

/**
  * @author : Administrator
  */
class Worker(val masterHost:String,val masterPort:Int) extends Actor{

  var master: ActorSelection = _
  //在Worker启动前建立和Master的链接
  override def preStart(): Unit = {
    //path:String Master的路径
    val path:String = s"akka.tcp://MasterSystem@$masterHost:$masterPort/user/Master"
    //获取到Master的引用
    master = context.actorSelection(path)
    //通过Master的引用向Master发消息
    master ! "connect"
  }
  override def receive: Receive = {
    //接收Master返回的reply信息
    case "reply" => {
      //得到reply信息后处理的业务逻辑
      println("master reply")
    }
  }
}

object Worker {
  def main(args: Array[String]): Unit = {
    val host = "127.0.0.1"
    val port = 9999
    val masterHost = "127.0.0.1"
    val masterPort = 8888
    val path:String = s"akka.tcp://MasterSystem@$masterHost:$masterPort/user/Master"

    val str =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "$host"
         |akka.remote.netty.tcp.port = "$port"
       """.stripMargin
    val config = ConfigFactory.parseString(str)
    //获取ActorSystem,用来创建并监控Actor
    val actorSystem = ActorSystem.apply("WorkerSystem",config)
    //创建Worker的Actor对象
    actorSystem.actorOf(Props(new Worker(masterHost,masterPort)),"Worker")

  }
}

启动Worker

  • Master控制台结果:
[INFO] [09/17/2018 10:44:21.902] [MasterSystem-akka.actor.default-dispatcher-3] [akka.tcp://[email protected]:8888/user/Master] a client connected
  • Worker控制台结果:
[INFO] [09/17/2018 10:44:21.099] [main] [akka.remote.Remoting] Starting remoting
[INFO] [09/17/2018 10:44:21.432] [main] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://[email protected]:9999]
[INFO] [09/17/2018 10:44:21.432] [main] [akka.remote.Remoting] Remoting now listens on addresses: [akka.tcp://[email protected]:9999]
master reply

猜你喜欢

转载自blog.csdn.net/guo20082200/article/details/82733889