2010-09-25 4 views
4

Je joue avec des acteurs à distance, mais je suis confronté à des difficultés.Comment mettre fin au client Scala Remote Actor?

Tenir compte de ce serveur:

object Server { 
    def main(args: Array[String]) { 
     val server = new Server 
     server.start 
    } 
} 

class Server extends Actor { 
    RemoteActor.alive(12345) 
    RemoteActor.register('server, this) 

    def act() { 
     while(true) { 
      receive { case x => println(x) } 
     } 
    } 
} 

J'ai écrit un client simple:

object Client { 
    def main(args: Array[String]) { 
     val server = RemoteActor.select(Node("localhost", 12345), 'server) 
     server ! "Hey!" 
    } 
} 

Comme prévu, les impressions du serveur "Hey".

Cependant, de manière inattendue, l'application cliente ne se termine jamais!

Il semble que de nombreux threads ont été démarrés sur l'application client, mais ils continuent à fonctionner après la fin de ma fonction principale! Que puis-je faire pour terminer l'application client?

Et plus encore: que se passe-t-il si je veux que mon client puisse démarrer et arrêter les connexions? Comment puis-je atteindre cet objectif?

Quelques informations supplémentaires (basées sur les réponses): J'utilise scala 2.8.0.final, et ce dont je parle ici est un serveur autonome et un client autonome. Ils devraient être lancés comme $ scala Server et $ scala Client. Ce que je veux arriver, c'est que l'application "Client" devrait finir, mais cela n'arrive jamais.

Merci!

+0

Voir aussi http://stackoverflow.com/questions/1058408/is-it-bad-practice-to-send -un-acteur-un-message-de-quelque-chose-qui-n'est-pas-un-acte. –

Répondre

3

Alors que Scala l'acceptera volontiers, c'est has consequences comme vous le voyez. Voici un code équivalent qui fonctionne:

import scala.actors.remote._ 

object Act extends scala.actors.Actor { 
    def act = { 
     val server = RemoteActor.select(Node("localhost", 12345), 'server) 
     server ! "Hey!" 
    } 
} 

object Client { 
    def main(args: Array[String]) { 
     Act.start() 
    } 
} 

Ou, plus simplement,

import scala.actors.Actor.actor 
import scala.actors.remote._ 

object Client { 
    def main(args: Array[String]) { 
     actor { 
     val server = RemoteActor.select(Node("localhost", 12345), 'server) 
     server ! "Hey!" 
     }   
    } 
} 
+0

Excellent! Merci pour l'information. –

0

Le code suivant fonctionne pour moi:

import scala.actors.Actor 
import scala.actors.remote.RemoteActor 
import scala.actors.remote.RemoteActor._ 
import scala.actors.remote.Node 

object Client { 
    def main(args: Array[String]) { 
     val server = RemoteActor.select(Node("localhost", 12345), 'server) 
     server ! "Hey!" 
     exit 
    } 
} 
+0

Ouais, ça marcherait, mais ça ne sent pas bon. Si c'est la seule solution, alors pour terminer les threads créés par le client nous aurions besoin de tuer toute l'application ... –

1

Dans le code client, Envelopper les instructions select et connexes dans un bloc Actor.actor, puis appeler exit() à la fin du bloc. Il ne semble pas que vous ayez besoin de faire cela, mais c'est la seule façon que j'ai trouvé qui termine tous les threads que l'appel de sélection commence. Ne pas envoyer de messages à d'autres acteurs de l'extérieur d'un acteur.

+0

Hmm, bonne idée! Merci! –

Questions connexes