2011-09-10 18 views
2

こんにちは皆さん、RMIを使用したオブジェクト参照の受け渡し

私は本当にこの問題を解決しようとしています。誰もが私の問題を見て、私を助けてくれればと感謝しています。

Java RMIを使用して接続(register())を確立し、サーバーからの接続クライアント(get())のリストを受け取るクライアントが複数あります。私の目標は、クライアントがRMIを使用して互いに話をするようにすることです。登録する必要はなく、これまでのサーバーだけが登録されています。

クライアントオブジェクトの参照をサーバーに渡そうとしています。私はオブジェクト自体を渡したくないとして、(私は信じている)シリアル化を使用したくない

java.rmi.MarshalException: error marshalling arguments; nested exception is: 
    java.io.NotSerializableException: Client 

が、参照:

私は、次のエラーを取得しています。 Client1はclient2.messsage(String username、String message)を呼び出してClient2にメッセージを送信できるはずです。

私はちょうど私が私のコードを実装しているか、この時点であなたを示さなければならないと考えている:

public interface RMIClientIntf extends Remote { 
    public void message(String name, String message) throws RemoteException; 
    public String getName() throws RemoteException; 
} 

前のコードは、すべてのクライアントが実装すべきものです。 message()関数が別のクライアントから呼び出された場合、それは他のクラスがメッセージを送信していることを意味します。

私のクライアントクラス自体:

public class Client implements RMIClientIntf { 
    public Client() throws RemoteException { super(); } 
    public String getName() throws RemoteException { } 
} 

は今、クライアントのインスタンスを作成し、メインクラスは、サーバーへのリモートオブジェクトを送信するには、次のように呼び出します:サーバー上

final Client client = new Client(); 
server.register((RMIClientIntf) client, name); 

登録方法は、

public interface RMIServerIntf extends Remote { 
    public String register(RMIClientIntf cl, String userName) throws RemoteException; 
    public RMIClientIntf[] get() throws RemoteException; 
} 


public class Server extends UnicastRemoteObject implements RMIServerIntf { 
    public String register(RMIClientIntf cl, String userName) throws RemoteException { 
     ClientStruct newClient = new ClientStruct(cl, userName); 
     /* Store the ClientStruct */ 
     return new String("SUCCESS"); 
    } 
} 

として定義されます。登録後、各クライアントは次のようになります接続されたユーザーのリストを確認します。サーバー内の関数は以下の通りです:

public RMIClientIntf[] get() throws RemoteException { 
    RMIClientIntf[] users = new RMIClientIntf[openConnections.size()]; 
    /* Fill in users from ClientStruct */ 
    return users; 
} 

クライアントもSerializableを、その後、プログラムの実行を実装していたが、CLIENT2がclient1.message()、メッセージを()を呼び出したときにメソッドがクライアント2のために呼び出されるとスローした場合この時点でNullPointer。

私はこのリンクを参照していました:http://www.exampledepot.com/egs/java.rmi/args_Args.htmlこれはリモートではなく、シリアライゼーションで実装されるべきであるというヒントを与えてくれました。私の場合、なぜプログラムが不平を言っているのか分かりません。

本当にありがとうございます。私はしばらくの間、この問題を解決しようとしてきましたが、私は解決策を見つけることができません。

ありがとうございました!

答えて

1
あなたはクライアントをエクスポートして

編集サーバーにスタブを送信する必要があり

:これは動作するはずです、それはあなたがサーバーをエクスポートし、同じようにすべきである(ただし、のrmiregistryを使用せずに)

server.register((RMIClientIntf) UnicastRemoteObject.exportObject(client,0), name); 
+0

私はそれを行う方法がわかりません。チュートリアルをお願いしますか?私は現在、クラスパスの一部であるClient.javaファイルと、Client.javaコードを保持するServer、Client、およびInterfaceプロジェクト用のコードベースを持っています。 – Jary

+0

@jary編​​集を確認 –

+0

ありがとうございました!私はそれを働かせました。どうもありがとうございました! – Jary

1

RMI経由で任意の参照を渡すことはできません。クライアントはシリアライズ可能でなければならないので、ターゲット全体、またはエクスポートされたリモートオブジェクト自体に渡されるため、リモート参照が渡され、コールバックされます。

EDIT:後者があなたの意図であるように見えるので、ClientがUnicastRemoteObjectを拡張するようにするだけです。

Oracle/Sun​​の一部として優れたRMI Trailがあります。

+0

どのようにできましたエクスポートされたリモートオブジェクトiselfを作成してください。あなたは簡単なチュートリアルをお持ちですか? – Jary

+0

恐ろしい!私はそれが働くようになった、ありがとう!コードは次のとおりです。\t \t \t RMIClientIntf stub =(RMIClientIntf)UnicastRemoteObject.exportObject(client、0); \t \t \t文字列レスポンス= server.register(スタブ、名前); – Jary

関連する問題