2

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

4 回答 4

3

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

我可以建议看一下 Akka,它从第一天就考虑到远程 Actor 构建?www.akka.io

于 2010-12-03T13:13:44.577 回答
2

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

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

于 2010-12-02T22:40:46.160 回答
2

Reactortrait 定义了actor在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
    }
  }
}

编辑:我从来没有用远程演员测试过这个。

于 2010-12-03T03:38:04.380 回答
1

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)
         }
      }
   }
}
于 2010-12-05T03:58:54.150 回答