Webcast.NET Remoting学习笔记(3)对象激活
在访问一个远程对象的实例之前,我们必须激活它进行创建和初始化,对于按引用列集这里有两种激活方式:服务器激活和客户端激活。按值列集不需要专门的激活方式,它是通过序列化得到的对象的副本,实际上是通过逆序列化实现激活的。下面主要介绍服务器和客户端两种激活方式。
我们将服务器激活类型称为well-know对象类型,因为服务器在激活对象实例之前会在一个众所周知的同一资源标识符上发布这个类型,并把他配置为一个众所周知的对象,并在特定的端点和地址发布对象。remoting提供两种激活模式:
1 singleton
任何时候只有一个类型实例处于活动状态,客户端首次访问时将它激活,以后的访问都由它处理,不管同一客户端还是不同客户端。
2 singlecall
每一次的调用方法都激活一个新的实例。支持一种无状态编程模式。 下面一个例子来看一下它们的不同
创建远程服对象
Client1 TCP HelloMethod Hi there Caveman1 Counter 1
Client1 HTTP HelloMethod Hi there Caveman2 Counter 1
Client1 HTTP HelloMethod Hi there Caveman3 Counter 1
所以每一次都是创建了一个新实例,然后我们把singlecall改为singleton结果变为
Client1 TCP HelloMethod Hi there Caveman1 Counter 1
Client1 HTTP HelloMethod Hi there Caveman2 Counter 2
Client1 HTTP HelloMethod Hi there Caveman3 Counter 3
可见在第一次激活一个实例后客户端的请求都是他来处理。
而客户端激活是服务器为每一个访问远程对象的客户端建立一个对象的实例,在每个实例的租约到期之前并且在被垃圾回收器回收之前每一个实例都处于激活的状态。这样就可以实现保存客户端的状态。
我们将服务器激活类型称为well-know对象类型,因为服务器在激活对象实例之前会在一个众所周知的同一资源标识符上发布这个类型,并把他配置为一个众所周知的对象,并在特定的端点和地址发布对象。remoting提供两种激活模式:
1 singleton
任何时候只有一个类型实例处于活动状态,客户端首次访问时将它激活,以后的访问都由它处理,不管同一客户端还是不同客户端。
2 singlecall
每一次的调用方法都激活一个新的实例。支持一种无状态编程模式。 下面一个例子来看一下它们的不同
创建远程服对象
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingSamples
{
public class HelloServer : MarshalByRefObject
{
public int callCounter = 0;
public HelloServer()
{
Console.WriteLine("HelloServer activated");
}
public String HelloMethod(String name,
out int counter)
{
counter = ++callCounter;
Console.WriteLine(
"Server Hello.HelloMethod : {0} Counter :{1}",
name, callCounter);
return "Hi there " + name;
}
}
}
创建服务器端控制台项目using System.Collections.Generic;
using System.Text;
namespace RemotingSamples
{
public class HelloServer : MarshalByRefObject
{
public int callCounter = 0;
public HelloServer()
{
Console.WriteLine("HelloServer activated");
}
public String HelloMethod(String name,
out int counter)
{
counter = ++callCounter;
Console.WriteLine(
"Server Hello.HelloMethod : {0} Counter :{1}",
name, callCounter);
return "Hi there " + name;
}
}
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace RemotingSamples
{
public class Server
{
public static int Main(string [] args)
{
TcpChannel chan1 = new TcpChannel(8085);
HttpChannel chan2 = new HttpChannel(8086);
ChannelServices.RegisterChannel(chan1);
ChannelServices.RegisterChannel(chan2);
RemotingConfiguration.RegisterWellKnownServiceType
(
typeof(HelloServer),
"SayHello",
WellKnownObjectMode.SingleCall
);
System.Console.WriteLine("Press Enter key to exit");
System.Console.ReadLine();
return 0;
}
}
}
创建客户端控制台项目using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace RemotingSamples
{
public class Server
{
public static int Main(string [] args)
{
TcpChannel chan1 = new TcpChannel(8085);
HttpChannel chan2 = new HttpChannel(8086);
ChannelServices.RegisterChannel(chan1);
ChannelServices.RegisterChannel(chan2);
RemotingConfiguration.RegisterWellKnownServiceType
(
typeof(HelloServer),
"SayHello",
WellKnownObjectMode.SingleCall
);
System.Console.WriteLine("Press Enter key to exit");
System.Console.ReadLine();
return 0;
}
}
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.IO;
namespace RemotingSamples
{
public class Client
{
public static void Main(string[] args)
{
//使用TCP通道得到远程对象
TcpChannel chan1 = new TcpChannel();
ChannelServices.RegisterChannel(chan1);
HelloServer obj1 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"tcp://localhost:8085/SayHello");
if (obj1 == null)
{
System.Console.WriteLine(
"Could not locate TCP server");
}
//使用HTTP通道得到远程对象
HttpChannel chan2 = new HttpChannel();
ChannelServices.RegisterChannel(chan2);
HelloServer obj2 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"http://localhost:8086/SayHello");
if (obj2 == null)
{
System.Console.WriteLine(
"Could not locate HTTP server");
}
//多次调用
int counter;
Console.WriteLine(
"Client1 TCP HelloMethod {0} Counter {1}",
obj1.HelloMethod("Caveman1", out counter),
counter);
Console.WriteLine(
"Client2 HTTP HelloMethod {0} Counter {1}",
obj2.HelloMethod("Caveman2", out counter),
counter);
Console.WriteLine(
"Client2 HTTP HelloMethod {0} Counter {1}",
obj2.HelloMethod("Caveman3", out counter),
counter);
Console.ReadLine();
}
}
}
这时是singlecall运行后显示using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.IO;
namespace RemotingSamples
{
public class Client
{
public static void Main(string[] args)
{
//使用TCP通道得到远程对象
TcpChannel chan1 = new TcpChannel();
ChannelServices.RegisterChannel(chan1);
HelloServer obj1 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"tcp://localhost:8085/SayHello");
if (obj1 == null)
{
System.Console.WriteLine(
"Could not locate TCP server");
}
//使用HTTP通道得到远程对象
HttpChannel chan2 = new HttpChannel();
ChannelServices.RegisterChannel(chan2);
HelloServer obj2 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"http://localhost:8086/SayHello");
if (obj2 == null)
{
System.Console.WriteLine(
"Could not locate HTTP server");
}
//多次调用
int counter;
Console.WriteLine(
"Client1 TCP HelloMethod {0} Counter {1}",
obj1.HelloMethod("Caveman1", out counter),
counter);
Console.WriteLine(
"Client2 HTTP HelloMethod {0} Counter {1}",
obj2.HelloMethod("Caveman2", out counter),
counter);
Console.WriteLine(
"Client2 HTTP HelloMethod {0} Counter {1}",
obj2.HelloMethod("Caveman3", out counter),
counter);
Console.ReadLine();
}
}
}
Client1 TCP HelloMethod Hi there Caveman1 Counter 1
Client1 HTTP HelloMethod Hi there Caveman2 Counter 1
Client1 HTTP HelloMethod Hi there Caveman3 Counter 1
所以每一次都是创建了一个新实例,然后我们把singlecall改为singleton结果变为
Client1 TCP HelloMethod Hi there Caveman1 Counter 1
Client1 HTTP HelloMethod Hi there Caveman2 Counter 2
Client1 HTTP HelloMethod Hi there Caveman3 Counter 3
可见在第一次激活一个实例后客户端的请求都是他来处理。
而客户端激活是服务器为每一个访问远程对象的客户端建立一个对象的实例,在每个实例的租约到期之前并且在被垃圾回收器回收之前每一个实例都处于激活的状态。这样就可以实现保存客户端的状态。