- PR -

ASP(C#)とWindowsサービス(C#)間のHTTP Remotingについて

1
投稿者投稿内容
タグチ
会議室デビュー日: 2005/03/01
投稿数: 3
お住まい・勤務地: 神奈川
投稿日時: 2005-03-01 17:27
初めて書き込みさせていただきます。
現在ASPからWindowsサービスへの情報の受け渡しとしてHttpのRemoteingを使用しています。

一見上手く行っている様思えたのですが、ASPからWindowsサービスへの送信を5分ほど行わないと

RemoteingException:要求されたサービスが見つかりません.

と言うExceptionが上がってしまいWindowsサービスへの情報の受け渡しが出来なくなってしまいました。その後はASPより再送してもRemoteingExceptionが発生するばかりです。

ソースは下記の通りです。

/*
* windowsサービス(クラス内前後)サーバ
*/
  RemoteMsg remoteObj;
private void SetHttpRemote()
{
// 送受信用のクラスを作成
remoteObj = new RemoteMsg();
channel = new HttpChannel(m_tb_systemInfo.d_httpRmtPort);
// チャンネルを作成
ChannelServices.RegisterChannel(channel);
ObjRef oref = RemotingServices.Marshal( remoteObj, m_tb_systemInfo.d_httpRmtIventName );
// イベントを登録
remoteObj.CalledClient += new RemoteMsg.CalledClientHandler(RemoteCalled);
// リスナー開始
channel.StartListening( null );

}

/*
* ASP、windowsサービス中間クラス
*/

using System;

namespace ComSocket
{
public class RemoteMsg : MarshalByRefObject
{
public RemoteMsg()
{
}
public void CallServer( string msg )
{
if ( CalledClient != null )
{
// クライアントからのイベントを通知
CalledClient( msg );
}
}
// デリゲータ
public delegate void CalledClientHandler( string msg );
// イベント
public event CalledClientHandler CalledClient;
}
}

/*
* ASP(クラス内前後)クライアント
*/
private void Page_Load(object sender, System.EventArgs e)
{

HttpChannel channel = new HttpChannel(0);

try
{

if(ChannelServices.RegisteredChannels.Length == 0)
{
// チャンネル作成を作成し送信パスの登録を行う
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownClientType(
typeof(RemoteMsg), 指定URL);
}
// メッセージを設定
string msg = Request["リクエスト情報"];
// メッセージを送信
RemoteMsg remoteObj = new RemoteMsg();
remoteObj.CallServer(msg);
}
catch (Exception ex)
{
       エラー処理;
}
}

環境:
WindowsXP Pro
VS .net 2003
IIS

よろしくお願いいたします。
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2005-03-01 18:34
リース期間切れではないでしょうか?

System.Runtime.Remoting.Lifetime名前空間あたりを調べて、
スポンサーを実装してください。

<参考>
これからはじめる.NET Framework .NETリモーティング編
タグチ
会議室デビュー日: 2005/03/01
投稿数: 3
お住まい・勤務地: 神奈川
投稿日時: 2005-03-01 20:24
ご返信ありがとうございます。

>リース期間切れではないでしょうか?
>
>System.Runtime.Remoting.Lifetime名前空間あたりを調べて、
>スポンサーを実装してください。
>
><参考>
>これからはじめる.NET Framework .NETリモーティング編

仰られる箇所(System.Runtime.Remoting.Lifetime名前空間)を調べて記述してみました。。。
結果から言わせていただきますとまだ成功していません。

/*
*中間クラス
*/
using System;
using System.Runtime.Remoting.Lifetime;

namespace ComSocket
{
public class RemoteMsg : MarshalByRefObject
{
public RemoteMsg()
{
}

public override Object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
ClientSponsor sponsor = new ClientSponsor();
if(lease.CurrentState == LeaseState.Expired)
{
sponsor.Register(this);
sponsor.Renewal(lease);
}


return lease;
}

public void CallServer( string msg )
{
if ( CalledClient != null )
{
// クライアントからのイベントを通知
CalledClient( msg );
}
}
// デリゲータ
public delegate void CalledClientHandler( string msg );
// イベント
public event CalledClientHandler CalledClient;
}
}

やりたい事と言うのはリース期限切れになった場合再度リースを登録し処理を続行する、と言う部分です。

ただ、リース期限切れになっていた場合上記の中間クラスにクライアントからアクセスできて居ない気がします・・・。

動作的にはリース期限切れ後、再登録しいつでもリモート通信が行える状態にもっていきたいのですが良い方法がありますでしょうか。。
お願いいたします。
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2005-03-02 10:03
こんな感じでいかがでしょうか?

コード:
// メッセージを送信
RemoteMsg remoteObj = new RemoteMsg(); 

// スポンサーを登録(更新期間5秒)
ILease myLease = (ILease)RemotingServices.GetLifetimeService(remoteObj);
myLease.Register(new ClientSponsor(TimeSpan.FromSeconds(5)));

remoteObj.CallServer(msg); 


タグチ
会議室デビュー日: 2005/03/01
投稿数: 3
お住まい・勤務地: 神奈川
投稿日時: 2005-03-02 19:43
ご返信ありがとうございます。

仰られたソースを埋め込んでみたところセキュリティーに引っかかったようですが、@ITの過去ログにも同じ状態のものがあったのでそちらを参考しなんとか解決いたしました。
ただ、症状としては改善されないままです・・。

とりあえずの手段として

中間クラス側に

public override Object InitializeLifetimeService(){
// リリース期限を1000000日延長する。
ILease lease = (ILease)base.InitializeLifetimeService();
lease.Renew(TimeSpan.FromDays(1000000) );
}

と言う形で対処して見た目上は上手く行っているようです。。。

大変便利な方法なので次回使うまでには使いこなせるようになるまで勉強しておきます。。
ありがとうございました!
1

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