- PR -

RMI通信の圧縮について

投稿者投稿内容
uzi
会議室デビュー日: 2004/05/10
投稿数: 13
投稿日時: 2004-05-10 18:08
 どうにも行き詰まってしまい、わからないので質問します。

RMI 通信の圧縮を行いたいのですが、 java.util.zip などのクラスを使用し
通信を行おうとしたところ、 Naming.Lookup に異常に時間がかかり(1min程 何かのタイムアウト?)
使用することが出来ませんでした。

SUN の RMI FAQ に Naming.Lookupに時間がかかる旨の記載があったため、HOSTSファイルに
IPと端末名の登録をしましたが、変化はありませんでした。

どこか悪いところがございますでしょうか?
Deflater(Inflater), GZIP , ZIP を使ってのRMI通信の圧縮は可能なのでしょうか?

ご存じの片いらっしゃいましたら教えてください。

ちなみに Windows2000 + JDK1.4.2 の環境です。

--------------------------ソース-----------------------------

class CompressionSocket extends Socket {

private InputStream in;
private OutputStream out;

public CompressionSocket() { super(); }

public CompressionSocket(String host, int port) throws IOException {
super(host, port);
}

public InputStream getInputStream() throws IOException {
if (in == null) {
in = new InflaterInputStream(super.getInputStream());
}
return in;
}

public OutputStream getOutputStream() throws IOException {
if (out == null) {
out = new DeflaterOutputStream(super.getOutputStream());
}
return out;
}

public synchronized void close() throws IOException {
OutputStream o = getOutputStream();
o.flush();

super.close();
}

}

class CompressionServerSocket extends ServerSocket {

public CompressionServerSocket(int port) throws IOException {
super(port);
}

public Socket accept() throws IOException {
Socket s = new CompressionSocket();
implAccept(s);
return s;
}
}


public class CompressionClientSocketFactory
implements RMIClientSocketFactory, Serializable
{

public CompressionClientSocketFactory() {
}

public Socket createSocket(String host, int port)
throws IOException {
return new CompressionSocket(host, port);
}

}

public class CompressionServerSocketFactory
implements RMIServerSocketFactory, Serializable
{
public CompressionServerSocketFactory() {
}

public ServerSocket createServerSocket(int port) throws IOException
{
return new CompressionServerSocket(port);
}
}

public class XXXXImpl extends UnicastRemoteObject implements IRmiUserApprovalOperation, Remote
{
public RmiUserApprovalOperationImpl() throws RemoteException
{
super(0,new CompressClientSocketFactory(),new CompressSocketFactory());
}

 // 省略

}

uzi
会議室デビュー日: 2004/05/10
投稿数: 13
投稿日時: 2004-05-10 18:35
自己レスです。

発生する Exception は

java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out

です。

更に補足しますと、現在複数のRMI通信を行っており、 それに伴い複数回 Naming.Lookup を行って
いるのですが、その最中(10個目辺り)でこの Exception が発生します。

山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-05-12 05:10
問題が起きているのは gzip で圧縮しているからですか?それとも同時に通信する本数が多いからですか?
uzi
会議室デビュー日: 2004/05/10
投稿数: 13
投稿日時: 2004-05-12 09:34
引用:

インギさんの書き込み (2004-05-12 05:10) より:
問題が起きているのは gzip で圧縮しているからですか?それとも同時に通信する本数が多いからですか?



恐らくどちらでもないと思います。
圧縮は Deflate/Infrate を用いていますし、1通信のみでも同様(Naming.lookup に時間がかかる)です。

ちなみに、 Zip(Out/In)putStream, GZIP(Out/In)putStream でも試してみたのですが、
同様でした。

これらを使っての RMI 通信はそもそも可能なのでしょうか?こちら側の勘違いだと良いのですが・・
parolibre
常連さん
会議室デビュー日: 2002/12/30
投稿数: 33
投稿日時: 2004-05-12 17:05
> 恐らくどちらでもないと思います。
おそらくというのは、キチンとした検証を行っていないと言うことですよね?
当事者がキチンとした検証を行った上でないと、環境が見えない場所にいる第三者の誰も答えようがないと思うのですが。

> これらを使っての RMI 通信はそもそも可能なのでしょうか?こちら側の勘違いだと良いのですが・・
RMI通信自体は可能です。
Javaのリファレンスをご覧になったことはありますか?

■RMIチュートリアル-RMI 入門
| リモートメソッドに渡す引数、またはリモートメソッドからの戻り値は、Java プラッ
| トフォーム用のどのデータ型であっても構いません。さらに、インタフェース
| java.io.Serializable を実装したオブジェクトであれば、オブジェクト型であって
| も構いません。java.lang および | java.util 内のコア Java クラスの大部分は、
| Serializable インタフェースを実装しています。RMI では、次のようになります。
と書いてあります。

ただ、uziさんの現在の環境でRMI通信が正常に行われているのかどうかは分かりません。

RMIを利用しているネットワーク環境(RMIサーバへの通信経路)なども影響しているように思います。
前川
常連さん
会議室デビュー日: 2004/04/27
投稿数: 38
お住まい・勤務地: 1DK
投稿日時: 2004-05-12 18:05
引用:

parolibreさんの書き込み (2004-05-12 17:05) より:
■RMIチュートリアル-RMI 入門

そこで引用されている部分は、RMIでやり取りできる値についての記述であって、RMIが使用できるストリームについてではありません。今回の質問とは無関係でしょう。

>uzi さん

似た要件に挑まれた方を見つけましたが[JavaHouse-Brewers:37462][JavaHouse-Brewers:38346]、この方は断念されたようですね。
# ですが、uzi さんとは違う現象で困っていたようです。

ZIP圧縮でない、他のストリームでは通信に成功してますか?

---- もう一例見つけたので追加
RMI-USERS



[ メッセージ編集済み 編集者: 前川 編集日時 2004-05-12 18:15 ]
uzi
会議室デビュー日: 2004/05/10
投稿数: 13
投稿日時: 2004-05-12 19:30
引用:

前川さんの書き込み (2004-05-12 18:05) より:

ZIP圧縮でない、他のストリームでは通信に成功してますか?




RMISocketFactory.getDefaultSocketFactory() や SUNのカスタムソケットのサンプルでは
動作を確認指定しています。

java.util.zip.* のストリームはそのままでは使えないような気がしていました・・・まだ、テスト中ですが
それらを継承してちょっと手を加えたら、 Naming.lookup のタイムアウトは解消しました。 が、
その後の通信に失敗しました。片手落ちだったようです。

引き続き何かご存じの方いらっしゃいましたらよろしくお願いします!
uzi
会議室デビュー日: 2004/05/10
投稿数: 13
投稿日時: 2004-05-18 16:04
自己レスです。

いろいろ試した結果、
InflaterInputStream , DeflaterOutputStream をそのまま使った
RMIの圧縮は出来ないと言うことがわかりました。

で、さんざん悩んだ挙げ句、これらのサブクラスを作り、
read(byte[] buf, int off, int len) , flush() などを拡張して
なんとか圧縮することが出来ました。(若干怪しいところもありますが)


#結構圧縮されるので、回線の細い環境には有効かとおもいます。

スキルアップ/キャリアアップ(JOB@IT)