2016-09-30 1 views
3

J'essaie de comprendre les bases de Java RMI.En utilisant Java RMI, pourquoi un appel de méthode distante génère-t-il le fuseau horaire du client au lieu de celui du serveur?

L'idée est d'avoir deux processus distincts en cours d'exécution, chaque apprêté par un principal séparé dans l'une des deux classes:

  • Client en cours d'exécution en tant que client
  • Server fonctionnant comme serveur

Une troisième classe Document agit comme l'objet partagé (c'est un simple collecteur de Strings), avec sa méthode addTimestamp() en enregistrant le courant Timestamp pour impression supplémentaire dans la console. Cette méthode est également disponible en tant que méthode distante, comme défini dans DocumentInterface.

L'exécution des deux conduites sur deux fenêtres cmd différents donne un système qui fonctionne parfaitement:

  • Server: java -cp rmi.jar Server

  • Client: java -cp rmi.jar Client

Comme prévu la sortie du client est :

CLIENT - Vue sur: 2016.09.30 01.53.01

SERVEUR - Vue sur: 2016.09.30 01.53.01

Quand je démarre le serveur sous un autre fuseau horaire que:

  • Server: java -Duser.timezone=PST -cp rmi.jar Server

  • Client: java -cp rmi.jar Client

Je reçois toujours la sortie du client d'origine:

CLIENT - Vu le: 2016.09.30 01.53.01

SERVEUR - Vu le: 30/09/2016 01.53.01

Je m'attendrais à ce que la deuxième ligne ait la base PST du serveur Timestamp. J'ai vérifié que le drapeau a été réglé correctement en l'imprimant directement par le serveur principal, et il est en effet différent:

2016.09.29 16.55.57

D'après ce que je l'ai compris jusqu'à présent, lorsque vous appelez la méthode addTimestamp() à distance sur l'objet distant:

  • le Document courant passe par copie au serveur
  • le Timezone est joint en annexe par le serveur, en utilisant son instance de la Document classe
  • le Document renvoyé est renvoyé par copie au client
  • le Document est affiché par le client

Dans ce cas, je me attends donc que Timezone à se baser sur les paramètres du serveur, pas le client de. Pourquoi n'est-ce pas le cas?

Voici quelques extraits de code des quatre classes:

Document.java:

public Document addTimestamp(Document document) throws RemoteException 
    { 
    String timestamp = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss").format(new Date()); 

    document.strings.add("Viewed on: "+timestamp); 

    return document; 
    } 

DocumentInterface.java:

public interface DocumentInterface extends Remote 
    { 
    public Document addTimestamp(Document document) throws RemoteException; 
    } 

Server.java - main:

Registry registry = LocateRegistry.createRegistry(1099); 
Document document = new Document(); 
Naming.bind("rmi:///Document", document); 

Client.java-main:

Document document = new Document(); 
DocumentInterface remoteDocument; 
try 
    { 
    remoteDocument = (DocumentInterface) Naming.lookup("rmi:///Document"); 

    document.addString("USER - "); 
    document.addTimestamp(document); 
    document.addString("\n"); 
    document.addString("SERVER - "); 
    document = remoteDocument.addTimestamp(document); 

    System.out.println(document.toString()); 
    } 
catch (Exception except) 
    { 
    } 
+1

Pouvez-vous imprimer l'heure dans addTimestamp et vérifier si elle fonctionne sur le client ou sur le serveur (par quelle fenêtre elle est imprimée)? – immibis

+0

Il est imprimé dans la fenêtre du client! Pourquoi donc? – Gliptal

+0

Parce qu'il fonctionne sur le client. Maintenant, je ne sais pas * pourquoi * ça marche sur le client ... – immibis

Répondre

1

Parce que Document est un objet distant exporté, il fonctionne comme un rappel au client. Pas par copie sur le serveur.

Supprimez l'interface distante et extends UnicastRemoteObject et rendez-la sérialisable.

+0

Merci, ça l'explique. Si je supprime l'interface 'Remote', je ne peux plus le lier au registre rmi (l'objet lié doit être de type' Remote'). Comment puis-je avoir un 'Document' lié par le serveur afin qu'il puisse être appelé par le client, et aussi ne pas le faire se comporter comme un rappel? – Gliptal

+1

Vous devez décider si vous créez un nouveau document chez le client ou si vous le recherchez dans le registre. À l'heure actuelle, vous faites les deux. Normalement, cela ne serait pas possible, car la classe d'objets distants 'Document' ne serait même pas présente sur le client. – EJP

+0

Ce que je voudrais faire, c'est que le client regarde dans le registre pour un 'Document' lié, et que le serveur exécute la méthode distante pour qu'elle affiche l'heure du serveur. J'utiliserais alors le client 'Document' pour tout afficher, et cette même méthode exécutée localement donne un horodatage différent. – Gliptal