RemotingServices
通过使用类 RemotingServices 提供的方法,我们可以很轻松实现这些目标。
ObjRef 是远程对象的可序列化表示,用于跨应用程序域边界传输对象引用。为对象创建 ObjRef 称为封送。可以通过信道将 ObjRef 传输到另一个应用程序域(可能在另一个进程或计算机上)。达到其他应用程序域后,需立即分析 ObjRef,以便为该对象创建一个代理(通常连接到实际的对象)。此操作称为拆收处理 (Unmarshaling)。在拆收处理过程中,分析 ObjRef 以提取远程对象的方法信息,并创建透明代理和 RealProxy 对象。在透明代理注册到公共语言运行库之前,将已分析的 ObjRef 的内容添加到透明代理中。
ObjRef 包含:描述所封送对象的 Type 和类的信息,唯一标识特定对象实例的 URI,以及有关如何到达对象所在的远程处理分支的相关通信信息。
通过使用类 RemotingServices 提供的方法,我们可以很轻松实现这些目标。
- Marshal: 用于将 MarshalByRefObject 转换为 ObjRef 类的实例。
- Connect:客户端可以用该方法创建远程代理对象的实例。
- Disconnect:断开服务器远程对象与信道的连接。客户端代理在断开后调用任何方法都会触发 RemotingException。
- Unmarshal:接受 ObjRef 并从它创建一个客户端代理对象。这个方法很少被使用,因为多数情况下我们并不会直接将 ObjRef 显示传递给客户端,而是交由 Remoting 基础结构来处理。
ObjRef 是远程对象的可序列化表示,用于跨应用程序域边界传输对象引用。为对象创建 ObjRef 称为封送。可以通过信道将 ObjRef 传输到另一个应用程序域(可能在另一个进程或计算机上)。达到其他应用程序域后,需立即分析 ObjRef,以便为该对象创建一个代理(通常连接到实际的对象)。此操作称为拆收处理 (Unmarshaling)。在拆收处理过程中,分析 ObjRef 以提取远程对象的方法信息,并创建透明代理和 RealProxy 对象。在透明代理注册到公共语言运行库之前,将已分析的 ObjRef 的内容添加到透明代理中。
ObjRef 包含:描述所封送对象的 Type 和类的信息,唯一标识特定对象实例的 URI,以及有关如何到达对象所在的远程处理分支的相关通信信息。
实现已知对象:
1.构建服务器端:
(1)添加对System.Runtime.Remoting.dll
(2)实现一个派生自MarshalByRefObject的类
(3)选择一种可用的通道,TCP,HTTP,然后用ChannelServices.RegisterChannel()方法注册此通道
(4)用RemotingConfiguration.RegisterWellKnownServiceType()方法把这个类注册为已知对象
(5)保持服务器处于激活态
首先是继承了MarshalByRefObject的类:
using System;
namespace MathLibrary
{
/// <summary>
/// SimpleMath 的摘要说明。
/// </summary>
public class SimpleMath:MarshalByRefObject
{
public SimpleMath()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public int Add(int a ,int b)
{
Console.WriteLine("SimpleMath.Add({0},{1})",a,b);
return a+b;
}
public int Subtract(int a, int b)
{
Console.WriteLine("SimpleMath.Subtract({0},{1})",a,b);
return a-b;
}
}
}
1.构建服务器端:
(1)添加对System.Runtime.Remoting.dll
(2)实现一个派生自MarshalByRefObject的类
(3)选择一种可用的通道,TCP,HTTP,然后用ChannelServices.RegisterChannel()方法注册此通道
(4)用RemotingConfiguration.RegisterWellKnownServiceType()方法把这个类注册为已知对象
(5)保持服务器处于激活态
首先是继承了MarshalByRefObject的类:



























接着构建服务器端:
1
using System;
2
using System.Runtime.Remoting;
3
using System.Runtime.Remoting.Channels;
4
using System.Runtime.Remoting.Channels.Http;
5
using MathLibrary;
6
7
namespace MathServer
8
{
9
/// <summary>
10
/// ServerMain 的摘要说明。
11
/// </summary>
12
public class ServerMain
13
{
14
public ServerMain()
15
{
16
//
17
// TODO: 在此处添加构造函数逻辑
18
//
19
}
20
public static void Main(string[] args)
21
{
22
//建立一个通道并指定段口号
23
HttpChannel channel = new HttpChannel(13101);
24
//通过运行时的远程服务来注册通道
25
ChannelServices.RegisterChannel(channel);
26
//注册被调用类为已知对象well-know
27
RemotingConfiguration.RegisterWellKnownServiceType(
28
typeof(MathLibrary.SimpleMath),//被注册的类
29
"MyURI.soap", //已知对象名称Well-Know Name
30
WellKnownObjectMode.Singleton); //被调用模式Singleton 或者 SingleCall
31
32
Console.WriteLine("Server started.Press Enter to End!");
33
Console.ReadLine();
34
}
35
}
36
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

然后构建客户端,注意代码注释:
需要知道如下信息:服务器机器名,通道类型,端口,分配给远程对象的URI
(1)添加引用如下所示
(2)添加对程序集的引用,本例中为MathLibrary.dll
(3)使用与服务器相同的通道类型注册一个通道,本例中为HTTP
(4)调用Activator.GetObject()方法,传递合适的URL以取得一个远程对象的代理
(5)找代理强制转换成合适的类型,并把他当真实对象使用
1
using
System;
2 using System.Runtime.Remoting;
3 using System.Runtime.Remoting.Channels;
4 using System.Runtime.Remoting.Channels.Http;
5 using MathLibrary;
6 namespace MathClient
7 {
8 /// <summary>
9 /// ClientMain 的摘要说明。
10 /// </summary>
11 public class ClientMain
12 {
13 public ClientMain()
14 {
15 //
16 // TODO: 在此处添加构造函数逻辑
17 //
18 }
19 public static void Main( string [] args)
20 {
21 // 创建并注册通道,没有指定段口号,所以不能接受消息
22 HttpChannel channel = new HttpChannel();
23 ChannelServices.RegisterChannel(channel);
24
25 // 获取远程对象的一个代理
26 Object remoteObj = Activator.GetObject( typeof (MathLibrary.SimpleMath), " Http://localhost:13101/MyURI.soap " );
27 // 将代理转换为所需要的类
28 SimpleMath math1 = (SimpleMath)remoteObj;
29
30 // 方法2
31 SimpleMath math2 = (SimpleMath)RemotingServices.Connect(
32 typeof (MathLibrary.SimpleMath),
33 " Http://localhost:13101/MyURI.soap "
34 );
35 // 方法3
36 RemotingConfiguration.RegisterWellKnownClientType(
37 typeof (MathLibrary.SimpleMath),
38 " Http://localhost:13101/MyURI.soap "
39 );
40 SimpleMath math3 = new SimpleMath();
41
42
43
44 Console.WriteLine( " 5+2={0} " ,math3.Add( 5 , 2 ));
45 Console.WriteLine( " 5-2={0} " ,math3.Subtract( 5 , 2 ));
46 Console.WriteLine( " Press enter to End " );
47 Console.ReadLine();
48 }
49 }
50 }
2 using System.Runtime.Remoting;
3 using System.Runtime.Remoting.Channels;
4 using System.Runtime.Remoting.Channels.Http;
5 using MathLibrary;
6 namespace MathClient
7 {
8 /// <summary>
9 /// ClientMain 的摘要说明。
10 /// </summary>
11 public class ClientMain
12 {
13 public ClientMain()
14 {
15 //
16 // TODO: 在此处添加构造函数逻辑
17 //
18 }
19 public static void Main( string [] args)
20 {
21 // 创建并注册通道,没有指定段口号,所以不能接受消息
22 HttpChannel channel = new HttpChannel();
23 ChannelServices.RegisterChannel(channel);
24
25 // 获取远程对象的一个代理
26 Object remoteObj = Activator.GetObject( typeof (MathLibrary.SimpleMath), " Http://localhost:13101/MyURI.soap " );
27 // 将代理转换为所需要的类
28 SimpleMath math1 = (SimpleMath)remoteObj;
29
30 // 方法2
31 SimpleMath math2 = (SimpleMath)RemotingServices.Connect(
32 typeof (MathLibrary.SimpleMath),
33 " Http://localhost:13101/MyURI.soap "
34 );
35 // 方法3
36 RemotingConfiguration.RegisterWellKnownClientType(
37 typeof (MathLibrary.SimpleMath),
38 " Http://localhost:13101/MyURI.soap "
39 );
40 SimpleMath math3 = new SimpleMath();
41
42
43
44 Console.WriteLine( " 5+2={0} " ,math3.Add( 5 , 2 ));
45 Console.WriteLine( " 5-2={0} " ,math3.Subtract( 5 , 2 ));
46 Console.WriteLine( " Press enter to End " );
47 Console.ReadLine();
48 }
49 }
50 }