- PR -

リモート処理のクライアントタイムアウト時間

1
投稿者投稿内容
よしぼん
会議室デビュー日: 2003/04/12
投稿数: 4
お住まい・勤務地: 東京・大田区
投稿日時: 2003-04-12 15:19
.NETリモート処理で、クライアントがサーバ側で処理するメソッド
の無限ループやネットワーク異常を検出する方法を教えてください。

サーバ側のレスポンスが一定時間帰ってこない場合、クライアント
側でタイムアウトを発生させ、メソッド呼出から戻ってくる方法が
分りません。

宜しくお願いします。
よしぼん
会議室デビュー日: 2003/04/12
投稿数: 4
お住まい・勤務地: 東京・大田区
投稿日時: 2003-04-14 11:11
追記します。

<テスト環境>
クライアント、サーバ共にWindows2000 Professional SP3
どちらも.NETframework SP1です。社内LAN(100Base-T)に
接続してテストしています。

<判っている現象>
(1)クライアントがリモートオブジェクトのメソッド呼出後、
  サーバのレスポンスが来る前にサーバのネットワーク
  ケーブルを抜くか、ローカルネットワークを無効にすると
クライアントのメソッド呼出から制御が戻ってこない。
(デッドロック)

(2)クライアントのネットワークを無効にすると、exception
  が発生する。

(3)シングルコール/シングルトンに関係なく上記現象が発生する。

下記URLにあるような、単純な.NETリモート処理のサンプルを使用
しても発生します。
http://ja.gotdotnet.com/QuickStart/howto/default.aspx?url=/quickstart/howto/doc/Remoting/mainfeatures.aspx

(1)の要因の時に(2)のような動作をしてほしいのですが、
方法がわかっておりません。

宜しく御願いします。
NothingButXMLInfoSet
ベテラン
会議室デビュー日: 2003/03/31
投稿数: 65
投稿日時: 2003-04-14 14:20
チャネルは何を使っていますか?HttpChannelであれば、2つの方法でタイムアウトを設定できます。
1) SOAPSUDS.EXEでプロキシを作っている場合は、そのプロキシにTimeoutプロパティがあるので、ms単位のタイムアウトまでの時間を設定できます。
2) Activator.GetObject(またはconfig)などを使っている場合は、次のコードでTimeoutプロパティにアクセスできます。

コード:
Remote rem = (Remote)Activator.GetObject(typeof(Remote), "http://localhost:82/Remote.rem");
System.Collections.IDictionary props = ChannelServices.GetChannelSinkProperties(rem);
props["Timeout"] = 1000;


TcpChannelを使っている場合は、上記2つの設定は無視されるので、別の方法が必要です。おそらく最も簡単なのは、非同期デリゲートを使う方法だと思います。

コード:
void method() {
  Remote rem = (Remote)Activator.GetObject(typeof(Remote), "tcp://localhost:82/Remote.rem");
  AddDeleg d = new AddDeleg(rem.Add);
  IAsyncResult ar = d.BeginInvoke(x, y, new AsyncCallback(Dummy), d);
// WaitOneでタイムアウトを設定する
  if (ar.AsyncWaitHandle.WaitOne(1000, true)) {
    int z = d.EndInvoke(ar);
    Console.WriteLine(z);
  }else
    Console.WriteLine("timeout");
}
delegate int AddDeleg(int x, int y);
static void Dummy(IAsyncResult ar) {
  AddDeleg d = (AddDeleg)ar.AsyncState;
  d.EndInvoke(ar);
}


本当なら、タイムアウトしたらEndInvokeは呼ばなくていいはずなんですが、どうも呼ばないとメモリリークする可能性があるらしいので、仕方なくDummyというコールバックを作っています。コールバックの中身はないものとして処理は進められるので、まあ問題ないと思いますが。

これら以外のチャネルを使っている場合は(非同期デリゲートの仕組みは使えるはずですが)チャネルがタイムアウト制御機能を持っていればそちらを使ったほうがいいでしょうね。
よしぼん
会議室デビュー日: 2003/04/12
投稿数: 4
お住まい・勤務地: 東京・大田区
投稿日時: 2003-04-14 17:30
さっそく試してみました。
今回は、HttpChannelを使い、非同期通信はしない予定
でしたので(2)の方法でうまくタイムアウトを検出するこ
とができました。

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

ところで、ご指摘頂いたプロパティ[ "Timeout" ]をここ(msdn)
から調べて見たのですが、調べ方が悪いのか見つかりませんでした。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconchannels.asp

次いでで申し訳ないのですが、チャネル関係のプロパティ一覧への
リンクがあれば教えてください。

お願いします。

NothingButXMLInfoSet
ベテラン
会議室デビュー日: 2003/03/31
投稿数: 65
投稿日時: 2003-04-14 18:29
本当は、これなんですが、どうもドキュメント化されてませんね。。。私の元ネタはここでTimeoutというプロパティを発見して、いろいろやってみたというところなんですが。。。

と思ったら.NET Framework 1.1のドキュメントにはちゃんと載ってました(Timeoutの話)からご安心を。
1

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