2009-07-27 18 views
8

サーバー上で長時間実行されるプロセスを開始するクライアントがあります。定期的に、私はバックグラウンドで何が起こっているのかをユーザーに見せたいと思います。最も簡単なアプローチはサーバーをポーリングすることですが、Observerパターンを実装する方法がないかどうかは疑問です。残念ながら、私はRMIを使用してサーバーと通信しています。クライアントをRMIサーバーにする必要があることを恐れています。Java RMIでObserverパターンを実装する方法は?

別の方法がありますか?

+1

を与える... RMIはちょっと吸います! :) – JohnIdol

答えて

1

私はあなたが何かを欠けているとは思わない。 2つの方法は、定期的にサーバを呼び出してステータス(ポーリング)をチェックするか、サーバが定期的に呼び出すコールバックを登録することです(クライアントはメソッドを公開する必要があります)。 IMO、ポーリングはこれを処理するための完全に合理的な方法です。

3

一般に、RMIは双方向通信をサポートできます。 (そして、そうです、RMIはPITAをセットアップし、他に何かをします)。

しかし、CGIスクリプト(!)で動作するHTTPトランスポートはサポートしていません。ここにすべての答えを統合

+0

LocateRegistry.createRegistry()を使用してサーバー内のサーバーを起動すると、(Sunが提供する実行可能ファイルを使用する代わりに)サーバーを起動すると、それは当てはまりますか? –

+0

+1 "(ええと、RMIはPITAでセットアップし、他には何もしません)"私の学校に教えてください。 – Luc

2

、私は、クライアントがRMIレジストリ からサーバーのスタブを取得し、レジストリ

  1. を使用して、そのスタブを露出させ、サーバーとクライアントとサーバの間で2ウェイRMIを実装
  2. クライアントはObserverとしてスタブをサーバーのaddObserverメソッドに置きます
  3. サーバーはこのスタブを使用してクライアントに通知します

次のコードの意志は私もこれをやろうとしていると私は同じ結論に達したより良いアイデアに

import java.rmi.*; 
import java.rmi.registry.*; 
import java.rmi.server.*; 
import java.util.Observable; 
import java.util.Observer; 
import java.net.*; 

import javax.rmi.ssl.SslRMIClientSocketFactory; 
import javax.rmi.ssl.SslRMIServerSocketFactory; 

interface ReceiveMessageInterface extends Remote 
{ 
    /** 
    * @param x 
    * @throws RemoteException 
    */ 
    void receiveMessage(String x) throws RemoteException; 

    /** 
    * @param observer 
    * @throws RemoteException 
    */ 
    void addObserver(Remote observer) throws RemoteException; 
} 

/** 
* 
*/ 
class RmiClient extends UnicastRemoteObject 
{ 
    /** 
    * @param args 
    */ 
    static public void main(String args[]) 
    { 
     ReceiveMessageInterface rmiServer; 
     Registry registry; 
     String serverAddress = args[0]; 
     String serverPort = args[1]; 
     String text = args[2]; 
     System.out.println("sending " + text + " to " + serverAddress + ":" + serverPort); 
     try 
     { // Get the server's stub 
      registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue()); 
      rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer")); 

      // RMI client will give a stub of itself to the server 
      Remote aRemoteObj = (Remote) UnicastRemoteObject.exportObject(new RmiClient(), 0); 
      rmiServer.addObserver(aRemoteObj); 

      // call the remote method 
      rmiServer.receiveMessage(text); 
      // update method will be notified 
     } 
     catch (RemoteException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (NotBoundException e) 
     { 
      System.err.println(e); 
     } 
    } 

    public void update(String a) throws RemoteException 
    { 
     // update should take some serializable object as param NOT Observable 
     // and Object 
     // Server callsbacks here 
    } 
} 

/** 
* 
*/ 
class RmiServer extends Observable implements ReceiveMessageInterface 
{ 
    String address; 
    Registry registry; 

    /** 
    * {@inheritDoc} 
    */ 
    public void receiveMessage(String x) throws RemoteException 
    { 
     System.out.println(x); 
     setChanged(); 
     notifyObservers(x + "invoked me"); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public void addObserver(final Remote observer) throws RemoteException 
    { 
     // This is where you plug in client's stub 
     super.addObserver(new Observer() 
     { 
      @Override 
      public void update(Observable o, 
       Object arg) 
      { 
       try 
       { 
        ((RmiClient) observer).update((String) arg); 
       } 
       catch (RemoteException e) 
       { 

       } 
      } 
     }); 
    } 

    /** 
    * @throws RemoteException 
    */ 
    public RmiServer() throws RemoteException 
    { 
     try 
     { 
      address = (InetAddress.getLocalHost()).toString(); 
     } 
     catch (Exception e) 
     { 
      System.out.println("can't get inet address."); 
     } 
     int port = 3232; 
     System.out.println("this address=" + address + ",port=" + port); 
     try 
     { 
      registry = LocateRegistry.createRegistry(port); 
      registry.rebind("rmiServer", this); 
     } 
     catch (RemoteException e) 
     { 
      System.out.println("remote exception" + e); 
     } 
    } 

    /** 
    * 
    * @param args 
    */ 
    static public void main(String args[]) 
    { 
     try 
     { 
      RmiServer server = new RmiServer(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 
} 
+0

RmiServerクラスがaddObserverを実装しているときに、RmiClientクラスをサーバー上で使用することができます。 RmiClientクラスはクライアントとサーバーの両方で定義されていますか? – KUN

関連する問題