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