如何断开 Scala Remote Actor 的连接?

发布于 2024-10-05 22:14:18 字数 1680 浏览 8 评论 0原文

在 scala 中,与远程参与者建立连接非常容易,但文档没有告诉我有关断开连接的任何信息。简单地丢弃引用是行不通的,因为远程参与者是参与者,所以在停止之前不会收集它们。那么我该如何断开连接呢?

退出后不会终止:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

object SimpleClient{
    val messageHandler = new DaemonActor{
        def act{
            loop{
                react{
                    case message:String =>
                        println("got message: " + message)
                    case _ =>
                }
            }
        }
        start
    }

    def main(args:Array[String]){
        val server = RemoteActor.select(Node("localhost",9999),'server)
        server.send('Connect,messageHandler)

        var exit = false
        while(!exit){
            val message = Console.readLine
            if(message == "exit" || message == "quit") {
                exit = true
                server ! 'Disconnect
            }
            else
                server ! message
        }
    }
}

这是服务器:

import actors.{Actor,OutputChannel}
import actors.remote.RemoteActor

object Server extends Actor{
    val clients = new collection.mutable.HashSet[OutputChannel[Any]]
    def act{
        loop{
            react{
                case 'Connect =>
                    clients += sender
                case 'Disconnect =>
                    clients -= sender
                case message:String =>
                    for(client <- clients)
                        client ! message
            }
        }
    }

    def main(args:Array[String]){
        start
        RemoteActor.alive(9999)
        RemoteActor.register('server,this)
    }
}

In scala it is very easy to make a connection to a remote actor, but the documentation does not tell me anything about disconnecting. Simply throwing away the reference does not work, because remote actors are actors, so these won't be collected until stopped. So how do I disconnect?

This does not Terminate after exit:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

object SimpleClient{
    val messageHandler = new DaemonActor{
        def act{
            loop{
                react{
                    case message:String =>
                        println("got message: " + message)
                    case _ =>
                }
            }
        }
        start
    }

    def main(args:Array[String]){
        val server = RemoteActor.select(Node("localhost",9999),'server)
        server.send('Connect,messageHandler)

        var exit = false
        while(!exit){
            val message = Console.readLine
            if(message == "exit" || message == "quit") {
                exit = true
                server ! 'Disconnect
            }
            else
                server ! message
        }
    }
}

This is the Server:

import actors.{Actor,OutputChannel}
import actors.remote.RemoteActor

object Server extends Actor{
    val clients = new collection.mutable.HashSet[OutputChannel[Any]]
    def act{
        loop{
            react{
                case 'Connect =>
                    clients += sender
                case 'Disconnect =>
                    clients -= sender
                case message:String =>
                    for(client <- clients)
                        client ! message
            }
        }
    }

    def main(args:Array[String]){
        start
        RemoteActor.alive(9999)
        RemoteActor.register('server,this)
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小霸王臭丫头 2024-10-12 22:14:18

[免责声明:我是 Akka 的 PO]

我可以建议看一下 Akka,它从第一天起就考虑到了远程 Actor 的构建方式吗?
akka.io

[Disclaimer: I'm PO of Akka]

May I suggest taking a look at Akka, which was built with Remote Actors in mind from day 1?
www.akka.io

再浓的妆也掩不了殇 2024-10-12 22:14:18

您的问题对于您认为遇到的问题还不够清楚。 Actor相互“连接”(就像套接字一样)。您向参与者发送消息是因为您拥有对它的引用(或者在远程参与者的情况下是代理)。

拥有这样的引用并不能阻止参与者(任一参与者)关闭。如果不再有任何对 Actor 的引用并且它没有运行,则没有什么可以阻止它被垃圾收集

Your question is not really clear enough about what problem you think you are experiencing. Actors do not "connect" to each other (like a socket). You send an actor a message because you have a reference to it (or a proxy, in the case of remote actors).

Having such a reference does not prevent the actor (either actor) from shutting down. If there are no longer any references to an actor and it is not running, there is nothing to stop it being garbage-collected

独木成林 2024-10-12 22:14:18

Reactor 特征定义了 protected[actors] def exit(): Nothing,actor 在收到通知它这样做的消息后可以调用自己。

sealed trait Msg
case object Apoptosis extends Msg
// ... more messages


class RRActor extends Reactor[Msg] {
  def act =  loop {
    react {
      // ... Whatever messages the actor handles
      case Apoptosis => this.exit
    }
  }
}

编辑:我还没有对远程演员进行过测试。

The Reactor trait defines protected[actors] def exit(): Nothing which the actor can call itself upon reception of a message telling it to do so.

sealed trait Msg
case object Apoptosis extends Msg
// ... more messages


class RRActor extends Reactor[Msg] {
  def act =  loop {
    react {
      // ... Whatever messages the actor handles
      case Apoptosis => this.exit
    }
  }
}

Edit: I have not tested this ever with remote actors.

柠檬心 2024-10-12 22:14:18

这是源代码的工作版本,并内嵌注释了相关更改:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

case class Send(message: String)
case object Disconnect

object SimpleClient{
    val messageHandler = new DaemonActor{

       def act{
          // keep the reference to the proxy inside the client-side actor
          val server = RemoteActor.select(Node("localhost",9999),'server)
          server ! 'Connect
          loop{
             react{
                case message:String =>
                   println("got message: " + message)
                case Send(message) => server ! message
                case Disconnect => { 
                   // disconnect and exit the client-side actor
                   server ! 'Disconnect //'
                   exit
                }
                case _ =>
              }
          }
      }
      start
   }

   def main(args:Array[String]){
      var exit = false
      while(!exit){
         val message = Console.readLine
         if(message == "exit" || message == "quit") {
            exit = true
            // tell the client-side actor to exit
            messageHandler ! Disconnect
         } else {
            messageHandler ! Send(message)
         }
      }
   }
}

Here's a working version of your source, with pertinent changes commented inline:

import actors.{DaemonActor,remote}
import remote.{RemoteActor,Node}

case class Send(message: String)
case object Disconnect

object SimpleClient{
    val messageHandler = new DaemonActor{

       def act{
          // keep the reference to the proxy inside the client-side actor
          val server = RemoteActor.select(Node("localhost",9999),'server)
          server ! 'Connect
          loop{
             react{
                case message:String =>
                   println("got message: " + message)
                case Send(message) => server ! message
                case Disconnect => { 
                   // disconnect and exit the client-side actor
                   server ! 'Disconnect //'
                   exit
                }
                case _ =>
              }
          }
      }
      start
   }

   def main(args:Array[String]){
      var exit = false
      while(!exit){
         val message = Console.readLine
         if(message == "exit" || message == "quit") {
            exit = true
            // tell the client-side actor to exit
            messageHandler ! Disconnect
         } else {
            messageHandler ! Send(message)
         }
      }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文