如何断开Scala Remote Actor的连接?

时间:2010-12-02 21:44:41

标签: scala actor disconnect

在scala中,很容易与远程actor建立连接,但文档并没有告诉我任何关于断开连接的信息。简单地丢弃引用不起作用,因为远程actor是actor,所以在停止之前不会收集它们。那我怎么断开连接?

退出后不会终止:

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)
    }
}

4 个答案:

答案 0 :(得分:3)

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

我可以建议你看一下从第1天开始用远程演员构建的Akka吗? www.akka.io

答案 1 :(得分:2)

您的问题对于您认为自己遇到的问题并不是很清楚。演员彼此“连接”(如套接字)。您向actor发送一条消息,因为您有一个对它的引用(或者是远程actor的代理)。

拥有这样的引用并不会阻止actor(任一actor)关闭。如果没有任何对actor的引用并且它没有运行,那就没有什么可以阻止它被垃圾收集了

答案 2 :(得分:2)

Reactor特征定义了protected[actors] def exit(): Nothing,演员可以在收到消息后自行调用它。

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
    }
  }
}

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

答案 3 :(得分:1)

以下是您的来源的工作版本,内联注释相关更改:

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)
         }
      }
   }
}