简体   繁体   中英

How do I disconnect a Scala Remote Actor?

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

[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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM