服务器激活
服务器激活的对象是生存期直接受服务器直接控制的对象。仅当客户端对对象进行方法调用时,服务器应用程序域才会创建这些对象,而不是当客户端调用
new
或
Activator.GetObject
的时候。客户端请求服务器激活类型的实例时,会在客户端应用程序域中创建一个代理。服务器激活类型只允许使用默认构造器。如果想使用特定的采用参数的构造器创建实例的类型,可以使用客户端激活,也可以动态发布特定实例。
服务器激活的对象有两种激活模式:
Singleton
和
SingleCall
,这两种模式又叫已知对象,由枚举类型:
WellKnownObjectMode
来标识。
Singleton
类型在任一时刻只有一个实例。所有的客户端请求都将由这个实例提供服务。如果不存在实例,则服务器创建一个,且所有的后来的客户端请求都将由这个实例提供服务。对于单件类型,会关联到默认的生存期。
SingleCall
类型针对每个客户端请求创建一个实例。下一个方法调用将由其他服务器实例提供服务,即使在系统尚未回收前一个实例的引用的情况下也是这样。
类
RemotingConfiguration
方法
RegisterWellKnownServiceType
将服务器上的对象类型注册为已知类型
public
static
void
RegisterWellKnownServiceType(
Type
type,
string
objectUri,
WellKnownObjectMode
mode)
所有知道已注册已知对象的
URI
的客户都可以获取该对象的代理,方法是:用
ChannelServices
注册信道,然后调用
new
或
Activator.GetObject
方法来激活对象。
·
当用
new
来激活对象时,须先要使用
RegisterWellKnownClientType
方法在客户端注册该已知对象类型。调用
RegisterWellKonwnClientType
方法向远程处理基础结构提供远程对象的位置,使
new
关键字可以创建它。
·
当用
Activator.GetObject
方法来激活已知对象时,须将对象的
URL
作为参数提供给该方法,所以在这种情况下,不用预先在客户端注册。
当调用到达服务器后,系统从消息中提取
URI
,检查远程处理表以定位与该
URI
匹配的对象的引用,然后实例化该对象,将方法调用转发给该对象。如果是
SingleCall
,则在方法调用完成后,该对象被销毁。为每个方法创建对象的一个新实例。
Activator.GetObject
与
new
的区别是:
Activator.GetObject
可以指定
URL
作为参数,
new
的时候是从配置中获取
URL
(
1
)通过
Actovator.GetObject
方法来获取代理
Activator
类位于
System
下。它包含一些方法,用于在本地或从远程创建对象类型,或获取对现有远程对象的引用。其中
GetObject
这个方法有
2
个重载,方法的意义是:为已知对象或
XML Web services
创建一个代理。
GetObject(Type, String)
为指定类型和
URL
所指示的已知对象创建一个代理。
GetObject(Type, String, Object)
为指定类型、
URL
和通道数据所指示的已知对象创建一个代理。
以第一个
2
个参数的方法为例子:第一个参数
Type
,是在服务端注册为已知类型的类型,第二个参数是已知对象的
URL
HttpChannel
_channel =
new
HttpChannel
(10001);
ChannelServices
.RegisterChannel(_channel,
false
);
Console
.WriteLine(
"http
通道
remoting
服务开始
……"
);
RemotingConfiguration
.RegisterWellKnownServiceType(
typeof
(
selfRemoteObject
),
"selfRemoteObject"
,
WellKnownObjectMode
.Singleton);
public
void
TestService()
selfRemoteObject
app =
(
selfRemoteObject
)
Activator
.GetObject(
typeof
(
selfRemoteObject
),
"http://localhost:10001/selfRemoteObject"
);
Assert
.AreEqual(13,app.Plus(3, 10));
(
2
)通过
new
来创建代理
当用
new
来激活对象时,先要使用
RegisterWellKnownClientType
方法在客户端注册该已知对象类型。然后使
new
关键字可以创建它。
服务端还是(
1
)中的服务端
public
void
TestServiceNew()
RemotingConfiguration
.RegisterWellKnownClientType(
typeof
(
selfRemoteObject
),
"http://localhost:10001/selfRemoteObject"
);
selfRemoteObject
app =
new
selfRemoteObject
();
Assert
.AreEqual(13, app.Plus(3, 10));
以上两种方法在创建代理后,调用方法时,服务端会管理已知类型对象的创建工作,这种生成对象是按默认的构造器(无参)来进行。
客户端激活
客户端激活的对象由调用应用程序域控制其生存期的对象,这种情况与应用程序域控制本地对象生存期一样。
创建客户端激活对象时,客户端将调用服务器。服务器实例化远程对象,并将对象引用返回给客户端。客户端使用这个引用创建远程对象的代理。每当客户端创建客户端激活对象的实例时,都会收到与远程对象的特定服务器实例进行通信的代理,直至其租约过期,内存被回收为止。
采用客户端激活方式的步骤:
·
要在服务器上创建客户端激活的对象的实例,要知道它的
Type
·
使用
RegisterActivatedServiceType
方法在服务端注册它。
客户端步骤:
·
客户端先向
ChannelServices
注册一个通道,
·
通过调用
new
或
Activator.CreateInstance
激活对象。
创建客户端激活类型实例的两种方式:
·
以
new
来进行
·
以
Activator.CreateInstance
的调用中传递远程对象
先准备服务端:
HttpChannel
_channel =
new
HttpChannel
(10001);
ChannelServices
.RegisterChannel(_channel,
false
);
Console
.WriteLine(
"http
通道
remoting
服务开始
……"
);
RemotingConfiguration
.ApplicationName =
"selfRemoteObject"
;
RemotingConfiguration
.RegisterActivatedServiceType
(
typeof
(
selfRemoteObject
));
Console
.Read();
服务端要通过
RegisterActivatedServiceType
方法来注册类型,且先要设定
ApplicationName
,这个就相当于
URL
(
1
)以
new
来进行
public
void
TestClientNew()
HttpChannel
_channel =
new
HttpChannel
();
ChannelServices
.RegisterChannel(_channel,
false
);
RemotingConfiguration
.RegisterActivatedClientType
typeof
(
selfRemoteObject
),
"http://localhost:10001/selfRemoteObject"
);
selfRemoteObject
app1 =
new
selfRemoteObject
();
Assert
.AreEqual(10, app1.Plus(1, 9));
通过
new
来激活客户端对象类型,先使用
RegisterActivatedClientType
方法在客户端注册该对象类型,然后
new
就可以了。
(
2
)
Activator.CreateInstance
如果用
CreateInstance
,则要提供远程应用程序的
URL
作为参数,不用在客户端注册类型。如果要用到
URL
做参数,则
URL
要封装在
UrlAttribute
类实例中。
public
void
TestClientInstance()
HttpChannel
_channel =
new
HttpChannel
();
ChannelServices
.RegisterChannel(_channel,
false
);
object
[] url={
new
UrlAttribute
(
"http://localhost:10001/selfRemoteObject"
)};
selfRemoteObject
app1 =
(
selfRemoteObject
)
Activator
.CreateInstance(
typeof
(
selfRemoteObject
),
null
, url);
Assert
.AreEqual(10, app1.Plus(1, 9));
客户端激活方式可以使用带参构造器来创建远程对象实例。
修改远程对象,添加一属性一个带参构造器:
public
int
Unid {
get
;
set
; }
public
selfRemoteObject() { }
public
selfRemoteObject(
int
iUnid)
Unid = iUnid;
添加了带参构造器,要显示声明默认的无参构造器。
通过
new
方法来创建对象实例。
selfRemoteObject
app1 =
new
selfRemoteObject
();
Assert
.AreEqual(0, app1.Unid);
selfRemoteObject
app2 =
new
selfRemoteObject
(10);
Assert
.AreEqual(10, app2.Unid);
激活方式,是远程对象实例创建的的管理方式。服务器端激活就是由服务端来管理远程对象的创建,在这种方式下,当客户端调用方法时,才创建实例;客户端激活由客户端来管理远程对象的创建,在这种方式下,当客户端发出调用就创建实例。
RemotingConfiguration
类的类型注册方法:
RegisterActivatedClientType
将客户端上的对象
Type
注册为可在服务器上激活的类型。
RegisterActivatedServiceType
将服务端上的对象
Type
注册为可根据请求从客户端激活的类型。
RegisterWellKnownClientType
将客户端上的对象
Type
注册为已知类型(
“
单个调用
”(singlecall)
或
singleton
)。
RegisterWellKnownServiceType
将服务端上的对象
Type
注册为已知类型(
“
单个调用
”(singlecall)
或
singleton
)。
RemotingServices.Disconnect
这个方法用于阻止对象通过注册的远程处理信道再接收消息。它的参数须是实例化的对象(要关闭的),服务端注册类型要通过
Marshal
方法来进行:
HttpChannel
_channel =
new
HttpChannel
(10001);
ChannelServices
.RegisterChannel(_channel,
false
);
Console
.WriteLine(
"http
通道
remoting
服务开始
……"
);
selfRemoteObject
obj=
new
selfRemoteObject
();
RemotingServices
.Marshal(obj,
"selfRemoteObject"
);
断开时,通过
Disconnect
方法:
RemotingServices
.Disconnect(obj);