我有一个服务器\客户端应用程序,它需要通过激活器请求两个不同的远程代理。
我遇到了一种情况,如果您在Activator.GetObject
不创建通道的情况下请求远程对象,然后再创建一个通道并尝试获取一个单独的对象,那么第二个对象将失败。让我展示一个示例应用程序来演示该问题:
这是两个远程对象:
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;
}
这是客户。如果您传入任何参数,那么它将首先注册一个命名通道。然后它将获取两个远程代理并在它们上调用一个方法。如果您不给它任何参数,它将首先获取第一个对象的代理,然后为第二个代理创建一个通道,然后尝试对这两个对象采取行动。
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);
}
如果您先注册一个频道,然后再激活,那么一切正常。
让激活器先运行,然后获取第二个对象,然后您会遇到异常。
如果您不尝试激活两个对象,而只是让激活器获取一个对象,那么这也可以。我很想知道这是为什么?
我很好奇,因为假设我不关心通道属性,那么我可以轻松地创建一个通道并完成它,但是,如果一个对象需要在通道上使用超时,但另一个对象确实如此不是,那么我需要创建两个单独的频道。那么有没有办法将对象绑定到通道?
我也知道远程处理已经走上了 wcf 的道路,但这不是我现在的选择。