1

我是 AKKA2 的新手。以下是我的问题:

有一个服务器参与者和几个客户端参与者。服务器存储客户端参与者的所有 ref。

我想知道服务器如何检测哪个客户端断开连接(关闭,崩溃......)

如果有办法告诉客户端服务器已经死了。

4

3 回答 3

2

有两种方法可以与 Actor 的生命周期进行交互。首先,参与者的父级定义了一个处理参与者故障的监督策略,并且可以选择在故障后重新启动、停止、恢复或升级。另外,一个非监督的actor可以“监视”一个actor来检测actor死亡时产生的Terminated消息。文档的这一部分涵盖了该主题: http ://doc.akka.io/docs/akka/2.0.1/general/supervision.html

这是使用规范中的手表的示例。我启动了一个演员,然后为 Termination 设置了一个观察者。当 actor 收到 PoisonPill 消息时,观察者会检测到该事件:

"be able to watch the proxy actor fail" in {
      val myProxy = system.actorOf(Props(new VcdRouterActor(vcdPrivateApiUrl, vcdUser, vcdPass, true, sessionTimeout)), "vcd-router-" + newUuid)
      watch(myProxy)
      myProxy ! PoisonPill
      expectMsg(Terminated(`myProxy`))
}

这是一个自定义主管策略的示例,如果由于身份验证异常而失败,则停止子actor,因为这可能无法纠正,或者如果失败是由于其他原因,则将故障升级到更高的主管:

override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 5, withinTimeRange = 1 minutes) {

    // presumably we had a connection, and lost it.  Let's restart the child and see if we can re-establish one.
    case e: AuthenticationException ⇒
      log.error(e.message + "  Stopping proxy router for this host")
      Stop

    // don't know what it was, escalate it.
    case e: Exception ⇒
      log.warning("Unknown exception from vCD proxy. Escalating a {}", e.getClass.getName)
      Escalate
}

在参与者中,您可以通过抛出异常或处理 PoisonPill 消息来生成故障。

如果您不想生成失败,另一种可能有用的模式是向发送者响应失败。然后,您可以与来电者进行更私人的消息交换。例如,调用者可以使用 ask 模式并使用 onComplete 块来处理响应。调用方:

vcdRouter ? DisableOrg(id) mapTo manifest[VcdHttpResponse] onComplete {
      case Left(failure) => log.info("receive a failure message")  
      case Right(success) ⇒ log.info("org disabled)    
}

被调用方:

val org0 = new UUID("00000000-0000-0000-0000-000000000000")
def receive = {
  case DisableOrg(id: UUID) if id == org0 => sender ! Failure(new IllegalArgumentException("can't disable org 0")
  case DisableOrg(id: UUID) => sender ! disableOrg(id)
}
于 2012-05-20T10:58:45.963 回答
1

在即将发布的 Akka 2.2 版本(RC1 昨天发布)中,Death Watch 可以在本地和远程工作。如果您在另一个系统上观察 root 监护人,当您为他终止时,您就知道远程系统已关闭。

希望有帮助!

于 2013-06-05T07:02:18.383 回答
1

为了使您的服务器对远程客户端状态的变化做出反应,您可以使用类似以下的内容(示例适用于 Akka 2.1.4)。

在 Java 中

@Override
public void preStart() {
    context().system().eventStream().subscribe(getSelf(), RemoteLifeCycleEvent.class);
}

或者在 Scala 中

override def preStart = {
     context.system.eventStream.subscribe(listener, classOf[RemoteLifeCycleEvent])
}

如果您只在客户端断开连接时感兴趣,您可以只注册 RemoteClientDisconnected

更多信息在这里(java)这里(scala)

于 2013-06-04T14:42:33.840 回答