Actor项目之服务端+客户端

本代码使用语言是scala,首先需要说明一下Actor的运行原理(图中只是说明了一个Actor对象给自己发消息,多个Actor发消息的原理相同):
在这里插入图片描述
这是一个Actor的运行机理,Actor的本质是自己给自己发消息。
1.首先创建一个class对象继承Actor,里面必须重写receive方法,receive方法是一个偏函数,所以需要用case捕获
2.创建一个object对象,利用ActorSystem创建一个工厂(这个工厂是用来创建该Actor对象的代理,注意一个Actor对象可以有多个代理)。
3.创建出Actor对象的代理,利用代理发消息到1,然后1再发给自己的2中,2再把消息发送给Actor对象。Actor对象的receive方法接收消息并处理。1,2,我们不需要关注,因为被封装在包里,我们直接调用就可以。
下面贴上代码:

package day04

import akka.actor.{Actor, ActorSystem, Props}

//HelloActor是一个Actor类
class HelloActor extends Actor{
    // 接受消息的
    override def receive: Receive = {
        // 接受消息并处理
        case "你好帅" => println("竟说实话,我喜欢你这种人!")
        case "丑" => println("滚犊子 !")
        case "stop" => {
            context.stop(self) // 停止自己的actorRef
            context.system.terminate() // 关闭ActorSystem
        }
    }
}


object HelloActor {

    private val nBFactory = ActorSystem("NBFactory")// 工厂
    private val helloActorRef = nBFactory.actorOf(Props[HelloActor], "helloActor")

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

        // 给自己发送消息
        helloActorRef ! "你好帅"
        helloActorRef ! "丑"

        helloActorRef ! "stop"

    }

}

下面以一个项目为例:
服务端(两段代码在一个文件中,只不过为了便于做笔记,分两个图片截图):
在这里插入图片描述
在这里插入图片描述
客户端:
在这里插入图片描述
在这里插入图片描述
代码如下:
服务端代码:

package cn.sheep.robot

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

class Edu360Server extends Actor{
    // 用来接受客户端发送过来的问题的
    override def receive: Receive = {
        case "start" => println("老娘已就绪 !")

        case ClientMessage(msg) => {
            println(s"收到客户端消息:$msg")
            msg match {
                case "你叫啥" => sender() ! ServerMessage("铁扇公主")
                case "你是男是女" => sender() ! ServerMessage("老娘是男的")
                case "你有男票吗" => sender() ! ServerMessage("没有")
                case _ => sender() ! ServerMessage("What you say ?") //sender()发送端的代理对象, 发送到客户端的mailbox中 -> 客户端的receive
            }
        }

    }
}

object Edu360Server {

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

        val host = "127.0.0.1"
        val port = 8088
		
		//设置一个配置
        val config = ConfigFactory.parseString(
            s"""
               |akka.actor.provider="akka.remote.RemoteActorRefProvider"
               |akka.remote.netty.tcp.hostname=$host
               |akka.remote.netty.tcp.port=$port
        """.stripMargin)

        // 将上面设置的配置作为参数传入,指定IP 和 端口,
        val actorSystem = ActorSystem("Server", config)

        val serverActorRef = actorSystem.actorOf(Props[Edu360Server], "shanshan")
        serverActorRef ! "start" // 到自己的mailbox -》 receive方法


    }
}

客户端代码:

package cn.sheep.robot

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

import scala.io.StdIn

class ClientActor(host: String, port: Int) extends Actor{

    var serverActorRef: ActorSelection = _ // 服务端的代理对象

    // 在receive方法之前调用
    override def preStart(): Unit = {
        // akka.tcp://[email protected]:8088
        serverActorRef = context.actorSelection(s"akka.tcp://Server@${host}:${port}/user/shanshan")
    }

    // mailbox ->receive
    override def receive: Receive = { // shit
        case "start" => println("牛魔王系列已启动...")
        case msg: String => { // shit
            serverActorRef ! ClientMessage(msg) // 把客户端输入的内容发送给 服务端(actorRef)--》服务端的mailbox中 -> 服务端的receive
        }
        case ServerMessage(msg) => println(s"收到服务端消息:$msg")
    }
}

object ClientActor  {


    def main(args: Array[String]): Unit = {
        val host = "127.0.0.1"
        val port  = 8089

        val serverHost = "127.0.0.1"
        val serverPort = 8088

        val config = 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", config)

        // 创建dispatch | mailbox
        val actorRef = clientSystem.actorOf(Props(new ClientActor(serverHost, serverPort.toInt)), "NMW-002")

        actorRef ! "start" // 自己给自己发送了一条消息 到自己的mailbox => receive

        while (true) {
            val question = StdIn.readLine() // 同步阻塞的, shit
            actorRef ! question // mailbox -> receive
        }
    }






}

样例类代码:

package cn.sheep.robot


// 服务端发送给客户端的消息格式
case class ServerMessage(msg: String)

// 客户端发送给服务器端的消息格式
case class ClientMessage(msg: String)

发布了51 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43316411/article/details/89166577