2010-09-15 11 views
2

Scénario:Est-il acceptable d'utiliser des objets multiples pour la communication RMI

  • client C se connecte au serveur S via RMI
  • C demande S pour créer un gestionnaire H, S retourne H à C
  • C parle alors à H

maintenant, je pourrais le faire de deux façons:

  • M ake le gestionnaire et un Remote soit S retourner le talon à elle, de sorte que C peut parler directement à celui (h.say(String msg);)
  • donner le gestionnaire d'ID et revenir à ce que C. C parlera de H par l'intermédiaire de S (s.sayToHandler(int id, String msg);)

Le premier est plus agréable OO, mais qu'en est-il de la performance? Une connexion TCP supplémentaire sera-t-elle ouverte ou la connexion existante entre S et H est-elle utilisée?

Répondre

2

Je ne connais pas l'implémentation. Je ne pense pas qu'une nouvelle connexion est faite. Mais ce que je sais, c'est que plus vous partagez d'objets à distance, plus il y a d'objets qui dépendent du déréférencement à distance pour récupérer les ordures (il y aura donc plus d'objets qui vivent plus longtemps).

approche alternative

Je recommande une approche mixte. Utilisez l'approche agréable pour le client, mais la mettre en œuvre le pas si beau sens interne:

interface Server { 

    public Handler getHandler(...); 
} 

interface Handler extends Serializable { 
    // it gets copied! 
    public X doThis(...); 
    public Y doThat(...); 
} 

class HandlerImpl implements Handler { 
    public X doThis(...) { 
    backDoor.doThis(this, ...); 
    } 
    public Y doThat(...) { 
    backDoor.doThat(this, ...); 
    } 

    private BackDoor backDoor; 
} 

interface BackDoor { 
    public X doThis(Handler h, ...); 
    public Y doThat(Handler h, ...); 
} 

class ServerImpl imlpements Server, BackDoor { 
    public Handler getHandler(...) { 
    return /*a handler with a self reference as backdoor, only ONE remote obj shared via TWO interfaces */ 
    } 
    ... 
    // it does everything 
    // it receives the handler 
} 

BackDoor et gestionnaire sont des interfaces sync'ed. Le premier a les méthodes avec Handler comme argument, le dernier a les méthodes pures. Je ne pense pas que ce soit un gros problème. Et les deux interfaces différentes vous permettent de travailler proprement sans que le client ne sache rien et permettent au Handler sériable de faire le sale boulot.

J'espère que vous l'aimez!

+0

J'ai utilisé cette approche pour donner à un client GWT (google web toolkit, donc c'est javascript) des "tickets" pour obtenir des données paginées. La méthode de requête principale (getCustomers) retourne un ticket, et le client peut demander au ticket des données partielles (retreive de X à Y). Le ticket fait: 'pageddataservice.retrieve (this, X, Y)'. Pageddataservice (un service bien connu) trouve le fournisseur de données d'origine pour le ticket (un registre central) et fait provider.retrieve (ticket, X, Y). Cela semble compliqué mais pour le client c'est presque magique. – helios

+0

Si cela ne vous dérange pas, vous pouvez fusionner le serveur et Backdoor en laissant l'utilisateur invoquer 'myServer.doThis (gestionnaire, ...)' ou invoquer le plus agréable 'handler.doThis (...)'. Cela simplifie un peu l'implémentation au prix de la publication des méthodes de réception des gestionnaires. – helios

1

La spécification RMI ne dit pas vraiment si une nouvelle connexion doit être établie ou si la connexion existante doit être réutilisée. Le protocole filaire permet à la fois, en utilisant soit multiplexing ou une connexion TCP par appel (qui pourrait être réutilisé pour suivre les appels au même objet sever, je ne suis pas sûr). Si vous avez besoin de tunnelliser via HTTP, un seul message par connexion est autorisé.

Je n'ai trouvé rien sur la façon de configurer le type de protocole à utiliser (autre que la désactivation de la tunnellisation HTTP).

Si vous souhaitez vous assurer qu'une seule connexion TCP est utilisée, utilisez des fabriques personnalisées de sockets client et serveur qui effectuent le tunneling de plusieurs connexions. Ce sera probablement moins efficace que ce que le système d'exécution RMI ferait là.