16.5.3 Actor通过网络通讯升级版

前面的案例中, Actor通讯时使用的数据类型是字符串.

当传递的数据比较多的时候, 只用字符串不太方便.

我们可以传递自定义类型的数据.

使用样例类做传递的数据类型最为方便.

把传递的数据类型改为样例类

MessageProtocol.scala

package com.atguigu.akka.net2

/*
客户端发给服务器端的数据类型
 */
case class ClientMessage(msg: String)
/*
服务器发给客户端的数据类型
 */
case class ServerMessage(msg: String)

ServerActor.scala

package com.atguigu.akka.net2

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


class ServerActor extends Actor {
    override def receive: Receive = {
        case "start" => println("客服可以开始工作了...")
        case ClientMessage(msg) => {
            msg match {
                case a: String if a.contains("地址") => {
                    sender() ! ServerMessage("北京市 昌平路 xxxx")
                }
                case a: String if a.contains("学费") => {
                    sender() ! ServerMessage("大数据学费 20098 元")
                }
                case a: String if a.contains("技术") => {
                    sender() ! ServerMessage("大数据 java 前段 python 区块链")
                }
                case a: String => {
                    sender() ! ServerMessage("你说的话小妹没有听懂, 再说一遍...")
                }
            }
        }
    }
}

object ServerActor {
    def main(args: Array[String]): Unit = {
        // 创建Config对象, 并监听指定的ip地址和端口
        val config: Config = ConfigFactory.parseString(
            s"""
               |akka.actor.provider="akka.remote.RemoteActorRefProvider"
               |akka.remote.netty.tcp.hostname=localhost
               |akka.remote.netty.tcp.port=10000
            """.stripMargin)
        val actorSystem: ActorSystem = ActorSystem("Server", config)
        val serverActor: ActorRef = actorSystem.actorOf(Props(classOf[ServerActor]), "ServerActor")
        serverActor ! "start"
    }
}

ClientActor

package com.atguigu.akka.net2

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

import scala.io.StdIn

class ClientActor(serverHost: String, serverPort: Int) extends Actor {
    var serverSelection: ActorSelection = _

    /**
      * 当一个Actor启动的时候回调这个方法.
      * 通常在这个方法内部做一些初始化的工作
      */
    override def preStart(): Unit = {
        println(serverHost)
        serverSelection = context.actorSelection(s"akka.tcp://Server@${serverHost}:${serverPort}/user/ServerActor")
    }

    override def receive: Receive = {
        case "start" => {
            println("客户端已经开启, 可以向客服咨询问题...")
            // 使用serverSelection向服务器发送信息
            serverSelection ! ClientMessage(StdIn.readLine())
        }
        case ServerMessage(msg) => {
            println("客服: " + msg)
            serverSelection ! ClientMessage(StdIn.readLine()) // 收到客服的恢复之后, 继续向客服咨询问题
        }
        case _ => {

        }
    }
}

object ClientActor {

    def main(args: Array[String]): Unit = {
        // 客户端监听配置
        val config: Config = ConfigFactory.parseString(
            s"""
               |akka.actor.provider="akka.remote.RemoteActorRefProvider"
               |akka.remote.netty.tcp.hostname=localhost
               |akka.remote.netty.tcp.port=9999
            """.stripMargin)
        val clientSystem: ActorSystem = ActorSystem("Client", config)
        val clientActor: ActorRef = clientSystem.actorOf(Props(classOf[ClientActor], "localhost", 10000), "clientActor")
        clientActor ! "start"
    }
}
Copyright © 尚硅谷大数据 2019 all right reserved,powered by Gitbook
该文件最后修订时间: 2019-04-12 09:01:17

results matching ""

    No results matching ""