Akka Actor发送消息示例详解

本文概述

在Akka中, Actor通过发送和接收消息来相互交流。


Akka Actor发送消息

Akka提供了两个预定义的方法tell()和ask()进行消息交换。Actor可以通过以下方法将消息发送给另一个Actor。

1)Akka Actor tell()方法

它用于异步发送消息。它不会等待并阻止线程发送消息。它适用于”忘火”方法。你也可以使用! (bang)感叹号发送消息。这是发送消息的首选方式。它提供了最佳的并发性和可伸缩性。

如果从Actor内部调用此方法, 则发送Actor的引用将与消息一起隐式传递。

如果从不是Actor的实例调用此方法, 则默认情况下, 发送者将是deadLetters actor引用。


Actor tell()方法示例

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

class ActorExample extends Actor{
  def receive = {
    case message:String => println("Message received: "+message+ " from - "+ self.path.name); 
    println("sender:"+ sender());  // returns ActorRef
  }
}

object ActorExample{
  def main(args:Array[String]){
    val actorSystem = ActorSystem("ActorSystem");
    val actor = actorSystem.actorOf(Props[ActorExample], "RootActor");
    actor ! "Hello"             // Sending message by using !
    actor.tell("Hello", null);  // Sending message by using tell() method
					// Sender is not passed here.
  }
}

输出

Message received: Hello from - RootActor
sender:Actor[akka://ActorSystem/deadLetters]  // ActorRef refers to deadLetters
Message received: Hello from - RootActor
sender:Actor[akka://ActorSystem/deadLetters] // ActorRef refers to deadLetters

Akka Actor tell()方法示例2

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

class ActorExample extends Actor{
  def receive = {
    case message:String => println("Message received: "+message+ " from - "+ self.path.name);
    println("Sender: "+sender())
    var child = context.actorOf(Props[Actor2], "ChildActor");
    child ! "Hello"
    
        
  }
}

class Actor2 extends Actor{
  def receive = {
    case message:String => println("Message received: "+message+ " from - "+ self.path.name);
    println("Sender: "+sender());
  }
}

object ActorExample{
  def main(args:Array[String]){
    val actorSystem = ActorSystem("ActorSystem");
    val actor = actorSystem.actorOf(Props[ActorExample], "RootActor");
    actor ! "Hello"
  }
}

输出

Message received: Hello from - RootActor
Sender: Actor[akka://ActorSystem/deadLetters]	// Called from outside Actor
Message received: Hello from - ChildActor
Sender: Actor[akka://ActorSystem/user/RootActor#1451914889]	// Called from within Actor

2)Akka Actor询问方法

在akka中, ask是一种模式, 涉及参与者和期货。 Ask用于异步发送消息, 它返回一个Future, 表示可能的答复。如果Actor没有回复并完成未来, 它将在超时期限后过期。超时时间过后, 它将引发TimeoutException。你可以使用其中一个吗? (问号)或ask()发送消息。

如果你要响应, 则应始终倾向于使用Tell方法来提高性能, 而Ask方法则要优先。


Akka Actor询问方法示例

import akka.actor.{Actor, ActorSystem, Props};
import akka.util.Timeout;
import scala.concurrent.Await
import akka.pattern.ask
import scala.concurrent.duration._

class ActorExample extends Actor{
  def receive = {
    case message:String => println("Message recieved: "+message);
  }
}

object ActorExample{
  def main(args:Array[String]){
    val actorSystem = ActorSystem("ActorSystem");
    val actor = actorSystem.actorOf(Props[ActorExample], "RootActor");
    implicit val timeout = Timeout(2 seconds);
    val future = actor ? "Hello";
    val result = Await.result(future, timeout.duration);
    println(result);
  }
}

输出

Message recieved: Hello
Exception in thread "main" java.util.concurrent.TimeoutException: Futures timed out after [2 seconds]

Akka Actor ask()方法示例2

import akka.actor.{Actor, ActorSystem, Props, ActorRef};
import akka.util.Timeout;
import scala.concurrent.Await
import akka.pattern.ask
import scala.concurrent.duration._

class ActorExample extends Actor{
  def receive = {
    case message:String => println("Message received: "+message+" from outside actor instance");
    println("Replaying");
    val senderName = sender();
    senderName ! "Hello, I got your message."; 		// Replying message
  }
}

object ActorExample{
  def main(args:Array[String]){
    val actorSystem = ActorSystem("ActorSystem");
    val actor = actorSystem.actorOf(Props[ActorExample], "RootActor");
    implicit val timeout = Timeout(10 seconds);
    val future = actor ? "Hello";
    val result = Await.result(future, timeout.duration);
    println("Message received: "+result);
  }
}

输出

Message received: Hello from outside actor instance
Replaying
Message received: Hello, I got your message.

Akka Actor询问方法示例3

import akka.actor.{Actor, ActorSystem, Props};
import akka.util.Timeout;
import scala.concurrent.Await
import akka.pattern.ask
import scala.concurrent.duration._

class ActorExample extends Actor{
  def receive = {
    case message:String => println("Message received: "+message+" from outside actor instance");
    Thread.sleep(5000);      // actor thread is sleeping 
    println("Replaying");
    val senderName = sender();
    senderName ! "Hello, I got your message."; 		// Replying message
  }
}

object ActorExample{
  def main(args:Array[String]){
    val actorSystem = ActorSystem("ActorSystem");
    val actor = actorSystem.actorOf(Props[ActorExample], "RootActor");
    implicit val timeout = Timeout(2 seconds);
    val future = actor ? "Hello";
    val result = Await.result(future, timeout.duration);
    println("Message received: "+result);
  }
}

输出

Message received: Hello from outside actor instance
Exception in thread "main" java.util.concurrent.TimeoutException: Futures timed out after [2 seconds]
微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?