アクティベーターを介して2つの異なるリモートプロキシを要求する必要があるserver\clientアプリケーションがあります。
チャネルを作成せずにリモートオブジェクトを要求しActivator.GetObject
、後でチャネルを作成して別のオブジェクトを取得しようとすると、2番目のオブジェクトが失敗するという状況に遭遇しました。問題を実証するためのサンプルアプリケーションを示しましょう。
2つのリモートオブジェクトは次のとおりです。
namespace HelloRemoteObject
{
public class FirstObject : MarshalByRefObject
{
public String FirstObjectMethod()
{
return "FirstObjectMethod";
}
}
public class SecondaryObject : MarshalByRefObject
{
public String SecondObjectMethod()
{
return "Secondary object method return string";
}
}
}
これがサーバーです。特定のポートにhttpサーバーチャネルを登録して待機します。
public static int Main(string[] args)
{
// register the channel
IDictionary properties = new Hashtable
{
{"timeout", 1000},
{"port", 9099}
};
var serverChannel = new HttpServerChannel(properties, new BinaryServerFormatterSinkProvider());
ChannelServices.RegisterChannel(serverChannel, false);
// register two known types
RemotingConfiguration.RegisterWellKnownServiceType(typeof(FirstObject), "FirstObjectUri", WellKnownObjectMode.Singleton);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SecondaryObject), "SecondaryObjectUri", WellKnownObjectMode.Singleton);
Console.WriteLine("Hit <enter> to exit...");
Console.ReadLine();
return 0;
}
そして、これがクライアントです。引数を渡すと、最初に名前付きチャネルが登録されます。次に、2つのリモートプロキシを取得し、それらに対して1つのメソッドを呼び出します。引数を指定しない場合は、最初に最初のオブジェクトへのプロキシを取得し、次に2番目のプロキシ用のチャネルを作成してから、2つを操作してみます。
static void Main(string[] args)
{
var registerChannelFirst = args.Length > 0;
if(registerChannelFirst)
{
Console.WriteLine("Registering channel first");
RegisterHttpChannel();
}
else
{
Console.WriteLine("Letting Activator.GetObject register an http client channel by default");
}
var firstRemoteObject = (FirstObject)Activator.GetObject(typeof(FirstObject), "http://127.0.0.1:9099/FirstObjectUri");
if(!registerChannelFirst)
{
RegisterHttpChannel();
}
var secondRemoteObject = (SecondaryObject)Activator.GetObject(typeof(SecondaryObject), "http://127.0.0.1:9099/SecondaryObjectUri", );
Console.WriteLine(firstRemoteObject.FirstObjectMethod());
Console.WriteLine(secondRemoteObject.SecondObjectMethod());
}
private static void RegisterHttpChannel()
{
// register the channel
IDictionary properties = new Hashtable
{
{"name" , "ChannelName"}
};
var clientChannel = new HttpClientChannel(properties, new BinaryClientFormatterSinkProvider());
ChannelServices.RegisterChannel(clientChannel, false);
}
最初にチャネルを登録すると、アクティブ化する前に、すべてが正常に機能します。
アクティベーターを最初に移動させてから2番目のオブジェクトを取得すると、例外が発生します。
2つのオブジェクトをアクティブ化しようとせず、アクティベーターにオブジェクトを取得させるだけの場合は、それも機能します。これがなぜなのか知りたいのですが?
チャネルのプロパティを気にしないと言うと、1つのチャネルを簡単に作成してそれを実行できますが、一方のオブジェクトがチャネルのタイムアウトを利用する必要があるが、もう一方のオブジェクトはそれを使用する場合は、興味があります。そうではなく、2つの別々のチャネルを作成する必要があります。次に、オブジェクトをチャネルにバインドする方法はありますか?
また、リモーティングがwcfの道を進んでいることも認識していますが、それは今のところ私にとっての選択肢ではありません。