** Remoting ** ** 高级知识 ** ** **
** 一、 ** ** 如何使用 ** ** IIS ** ** 作为激活代理 ** ** **
.NET Remoting 和 DCOM 之间的一个区别是前者不支持自动运行的服务器进程。需要人工启动服务器进程来注册用来远程激活的类和监听请求。而对于 DCOM ,当远程客户端调用 CoCreateInstanceEx 或 者其他激活 API 时,会自动运行服务器进程。
.NET remoting 提供了两种方法来避免人工启动服务器。第一个是将服务器应用程序当做一个服务来实现。可以编写一个从
System.ServiceProcess.Service 派生的服务,重载其中关键的需方法例如 OnStart 和 OnStop 。将服务器当做一个服务来实现的好处是你可以配置该服务以便系统启动时能自动运行该服务。
第二个方法是使用 IIS 作为激活代理。 IIS 本身就是一个服务,在大多数 Web Servers 运行时会一直启动。而且 IIS 能够通过使用 .NET Remoting 机制来响应客户端激活对象的请求。使用 IIS 有以下几个好处:
1 、不再需要编写一个用来注册可远程化的类和监听端口的服务器, IIS 就是服务器。
2 、可以使用 IIS 鉴别远程调用者,也可以使用 SSL 来保护数据。
3 、可以使用 IIS 来管理端口。如果在一个机器上部署了两个传统的应用程序服务器,则需要你来保证这两个服务器使用不同的端口。使用 IIS 作为宿主,则 IIS 可以选择端口,这样可以简化发布和管理。
IIS 支持服务器端激活对象和客户端激活对象。可以使用程序注册 ( 在 Global.asax 中 ) ,也可以使用声明注册 ( 在 Web.config 中 ) 。
1 、服务器端激活对象
下面的 Web.config 注册了使用 IIS 激活的 Clock 类 :
1<configuration>
2
3
4 <system.runtime.remoting>
5
6
7 <application>
8
9
10 <service>
11
12
13 <wellknown mode="singlecall" objecturi="Clock.rem" type="Clock, ClockServer"></wellknown mode="singlecall">
14
15
16 </service>
17
18
19 </application>
20
21
22 </system.runtime.remoting>
23</configuration>
注意 Clock 的 URI : Clock.rem 。使用 IIS 注册的 URI 必须以 .rem 或者 .soap 结束,因为该扩展对应到 IIS 原数据中的 Aspnet_isapi.dll 和 Machine.config 中的 .NET remoting 子系统。
使用 IIS 激活对象都是通过 HTTP 通道来与客户端进行通信。客户端必须注册 HTTP 通道。下面是一个客户端如何创建一个 Clock 实例,假设 Clock 在本地机器上一个叫 MyClock 的虚拟目录中。
HttpClientChannel channel = new HttpClientChannel ();
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownClientType
(typeof (Clock),"http://localhost/MyClock/Clock.rem");
Clock clock = new Clock ();
注意服务器和客户端都没有指定端口, IIS 选择该端口
2 、客户端激活对象
Web.config 文件注册注册一个客户端激活对象 Clock
1<configuration>
2
3
4 <system.runtime.remoting>
5
6
7 <application>
8
9
10 <service>
11
12
13 <activated type="clock, clockserver"></activated type="clock, clockserver">
14
15
16 </service>
17
18
19 </application>
20
21
22 </system.runtime.remoting>
23</configuration>
下面是客户端的写法 ( 依然假设 Clock 在本地机器 MyClock 虚拟目录中 ) :
HttpClientChannel channel = new HttpClientChannel ();
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterActivatedClientType
(typeof (Clock), "http://localhost/MyClock");
Clock clock = new Clock ();
** ** ** 注意:使用 ** ** IIS ** ** 必须在虚拟目录中有一个可远程化的类,而且必须把 ** ** Web.config ** ** 放在单独的虚拟目录中(例如 ** ** MyClock ** ** ),把 ** ** DLL ** ** 放在 ** ** bin ** ** 子目录中 ** ** (MyClock\bin) ** ** 。 ** ** **
** 二、 ** ** 如何通过 ** ** HTTP ** ** 通道传递二进制格式数据 ** ** **
使用 IIS 的一个缺点是只能使用 HTTP 通道。 HTTP 通道将调用封装成 SOAP 消息,这样会增加消息的长度。 IIS 只支持 HTTP 通道,但它并不要求使用将通道调用封装成 SOAP 消息。默认情况下, HTTP 使用 SOAP ,因为它使用 SoapClientFormatterSinkProvide 和
SoapServerFormatterSinkProvider 来作为序列化和反序列化消息的格式。可以使用 BinaryClientFormatterSinkProvider 和
BinaryServerFormatterSinkProvder 来替换它们。二进制消息可以跟好的利用网络带宽。
下面的 Web.config 文件注册了一个可以被 IIS 激活的 Clock ,它使用二进制替换了缺省的 SOAP 格式。
1<configuration>
2
3
4 <system.runtime.remoting>
5
6
7 <application>
8
9
10 <service>
11
12
13 <wellknown mode="singlecall" objecturi="Clock.rem" type="Clock, ClockServer"></wellknown mode="singlecall">
14
15
16 </service>
17
18
19 <channels>
20
21
22 <channel ref="http server">
23
24
25 <serverproviders>
26
27
28 <formatter ref="binary"></formatter ref="binary">
29
30
31 </serverproviders>
32
33
34
35
36
37 </channel ref="http server"></channels>
38
39
40 </application>
41
42
43 </system.runtime.remoting>
44</configuration>
客户端写法如下:
HttpClientChannel channel = new HttpClientChannel
("HttpBinary", new BinaryClientFormatterSinkProvider ());
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownClientType
(typeof (Clock), "http://localhost/MyClock/Clock.rem");
Clock clock = new Clock ();
当使用配置文件时,写法为:
RemotingConfiguration.Configure ("Client.exe.config");
Clock clock = new Clock ();
配置文件内容如下:
1<configuration>
2
3
4 <system.runtime.remoting>
5
6
7 <application>
8
9
10 <client>
11
12
13 <wellknown type="clock, clockserver" url="http://localhost/MyClock/Clock.rem"></wellknown type="clock, clockserver">
14
15
16 </client>
17
18
19 <channels>
20
21
22 <channel ref="http client">
23
24
25 <clientproviders>
26
27
28 <formatter <SPAN lang=EN-US style</clientproviders></channel ref="http client"></channels></application></system.runtime.remoting></configuration>