在此系列随笔中,注重代码实例,对原理的深入研究不想提及太多
远程对象的两个含义:
一,操作远程对象;
1,对象运行在远程,客户端向其发送消息.
2,继承之MarshalByRefObject
二,传递远程对象;
1,将远程对象拿到本地,或者将本地对象发送过去;
2,对副本进行操作,对远程对象没有影响;
3,添加[Serializable]属性或实现ISerizable接口.
对于远程对象的激活,有两种方式,一是服务器端激活,一是客户端激活
远程对象是使用通道发送和接收消息的,首先,服务器端选择一个通道来监听请求(request),而客户端选择通道来和服务器通讯,.Net Remoting框架中内置了TCP与HTTP通道,我们也可以开发我们自己的通道类型.
一般的Remoting开发分三个步骤:
1,创建远程对象;
2,创建"宿主(host)"应用程序,以接收客户端请求;
3,创建一个客户端对远程对象进行调用.
下面,说一下一个最简单的Remoting Demo
第一步.创建远程对象,在VS.NET中新建一个类库,新建一个类HelloServer,跟普通类没有不同,必须有不带参构造器且继承于类MarshalByRefObject或实现接口ISerizable(同添加[Serizable]属性)代码如下:
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace General
6{
7 /// <summary>
8 /// 第一步,创建远程对象
9 /// 继承于System.MarshalByRefObject类(客户端由一个代理类得到此对象的一个引用)]
10 /// 或标识为 [Serializable],客户端得到对象的一个副本,客户端对副本的操作不会影响服务器端的对象
11 /// </summary>
12 public class HelloServer:System.MarshalByRefObject
13 {
14 private int count=0;
15 public HelloServer()//必须有不带参的构造器
16 {
17 Console.Write("Hello Server activated");
18 }
19
20 public string HelloMethod(string str)
21 {
22 Console.Write("Hello Server:"+str);
23 return "Hi there " + str;
24 }
25
26 //传递自定义参数类型
27 public string HelloUserMethod(User user)
28 {
29 string title = user.Male == true ? "女士" : "先生";
30 Console.Write("Server HelloUserMethod:{0}{1}", user.Name, title);
31 return "您好," + user.Name + title;
32 }
33
34 //测试SingleTon和SingleCall
35 public string HellTonOrCall(string name,out int counter)
36 {
37 counter = ++count;
38 Console.WriteLine("Hell {0}Couter:{1}",name,counter);
39 return "HI,There " + name;
40 }
41 }
42}
43
2using System.Collections.Generic;
3using System.Text;
4
5namespace General
6{
7 /// <summary>
8 /// 第一步,创建远程对象
9 /// 继承于System.MarshalByRefObject类(客户端由一个代理类得到此对象的一个引用)]
10 /// 或标识为 [Serializable],客户端得到对象的一个副本,客户端对副本的操作不会影响服务器端的对象
11 /// </summary>
12 public class HelloServer:System.MarshalByRefObject
13 {
14 private int count=0;
15 public HelloServer()//必须有不带参的构造器
16 {
17 Console.Write("Hello Server activated");
18 }
19
20 public string HelloMethod(string str)
21 {
22 Console.Write("Hello Server:"+str);
23 return "Hi there " + str;
24 }
25
26 //传递自定义参数类型
27 public string HelloUserMethod(User user)
28 {
29 string title = user.Male == true ? "女士" : "先生";
30 Console.Write("Server HelloUserMethod:{0}{1}", user.Name, title);
31 return "您好," + user.Name + title;
32 }
33
34 //测试SingleTon和SingleCall
35 public string HellTonOrCall(string name,out int counter)
36 {
37 counter = ++count;
38 Console.WriteLine("Hell {0}Couter:{1}",name,counter);
39 return "HI,There " + name;
40 }
41 }
42}
43
第二步,创建宿主应用程序
1,注册通道(内置TCP,HTTP)
2,注册服务器激活的远程对象(WellKnow)
这里要说一下WellKnownObjectMode中的Singleton与Singlecall,个人理解:
Singleton 服务器端只产生单例,任何请求共用,保存状态,
Singlecall 客户端每一次请求,服务器端都会产生一个新的实例,没有状态
在VS.NET中新建一个控制台应用程序,新建类Server,代码:
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Runtime.Remoting.Channels;
5using System.Runtime.Remoting;
6using System.Runtime.Remoting.Channels.Tcp;
7using System.Runtime.Remoting.Channels.Http;
8using General;
9namespace Server
10{
11 public class Server
12 {
13 /// <summary>
14 /// 第二步,创建服务器端
15 /// </summary>
16 /// <param name="args"></param>
17 /// <returns></returns>
18 static int Main(string[] args)
19 {
20 //Remoting内置的两种通道,也可自定义自己的通道
21 TcpChannel tcpChannel = new TcpChannel(8085);//tcp通道
22 HttpChannel httpChannel = new HttpChannel(8086);//http通道
23
24
25 //服务器端对通道进行注册,注册完后,服务器就对通道进行监听
26 ChannelServices.RegisterChannel(tcpChannel,false);
27 ChannelServices.RegisterChannel(httpChannel,false);
28
29 //把远程对象注册到服务器上,注册众所周知的服务类型,WellKnown---都是服务器激活的对象
30 RemotingConfiguration.RegisterWellKnownServiceType(typeof(HelloServer),"SayHello",WellKnownObjectMode.Singleton);
31 /*
32 * Singleton 服务器端只产生单例,任何请求共用,保存状态,
33 * Singlecall 客户端一个请求对应一个实例,没有状态
34 *
35 *
36 *
37 *
38 */
39 Console.Write("服务器开始监听,按任意銉退出");
40 Console.ReadLine();
41 return 0;
42 }
43 }
44}
45
2using System.Collections.Generic;
3using System.Text;
4using System.Runtime.Remoting.Channels;
5using System.Runtime.Remoting;
6using System.Runtime.Remoting.Channels.Tcp;
7using System.Runtime.Remoting.Channels.Http;
8using General;
9namespace Server
10{
11 public class Server
12 {
13 /// <summary>
14 /// 第二步,创建服务器端
15 /// </summary>
16 /// <param name="args"></param>
17 /// <returns></returns>
18 static int Main(string[] args)
19 {
20 //Remoting内置的两种通道,也可自定义自己的通道
21 TcpChannel tcpChannel = new TcpChannel(8085);//tcp通道
22 HttpChannel httpChannel = new HttpChannel(8086);//http通道
23
24
25 //服务器端对通道进行注册,注册完后,服务器就对通道进行监听
26 ChannelServices.RegisterChannel(tcpChannel,false);
27 ChannelServices.RegisterChannel(httpChannel,false);
28
29 //把远程对象注册到服务器上,注册众所周知的服务类型,WellKnown---都是服务器激活的对象
30 RemotingConfiguration.RegisterWellKnownServiceType(typeof(HelloServer),"SayHello",WellKnownObjectMode.Singleton);
31 /*
32 * Singleton 服务器端只产生单例,任何请求共用,保存状态,
33 * Singlecall 客户端一个请求对应一个实例,没有状态
34 *
35 *
36 *
37 *
38 */
39 Console.Write("服务器开始监听,按任意銉退出");
40 Console.ReadLine();
41 return 0;
42 }
43 }
44}
45
第三步,创建客户端程序
1,注册通道(TCP,HTTP or Other);
2,根据URL得到对象代理;
3,使用代理调用远程对象
在VS.NET中新建一个控制台应用程序,新建类Client,代码:
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Runtime.Remoting.Channels.Tcp;
5using System.Runtime.Remoting.Channels.Http;
6using System.Runtime.Remoting.Channels;
7using General;
8namespace Client
9{
10 class Client
11 {
12 /// <summary>
13 /// 第三步,创建客户端
14 /// </summary>
15 /// <param name="args"></param>
16 public static void Main(string[] args)
17 {
18 //使用TCP通道得到远程对象代理,不用监听
19 TcpChannel tcpChannel1 = new TcpChannel();
20 ChannelServices.RegisterChannel(tcpChannel1,false);
21 HelloServer helloServer1 = (HelloServer)Activator.GetObject(typeof(General.HelloServer), "tcp://localhost:8085/SayHello");
22 if (helloServer1 == null)
23 {
24 Console.Write("Could not locate TCP server");
25 }
26
27
28 //使用HTTP通道得到远程对象代理,不用监听
29 HttpChannel httpChannel2 = new HttpChannel();
30 ChannelServices.RegisterChannel(httpChannel2, false);
31 HelloServer helloServer2 = (HelloServer)Activator.GetObject(typeof(General.HelloServer), "http://localhost:8086/SayHello");
32 if (helloServer2 == null)
33 {
34 Console.Write("Could not locate HTTP server");
35 }
36
37 //一般方法调用
38 Console.WriteLine("TCP HelloMethod {0}", helloServer1.HelloMethod("TcpChannel"));
39 Console.WriteLine("HTTP HelloMethod {0}", helloServer2.HelloMethod("HTTPChannel"));
40
41 //传递自定义类型参数
42 Console.WriteLine("TCP HelloMethod {0}", helloServer1.HelloUserMethod(new User("wumaosheng",false)));
43 Console.WriteLine("http HelloMethod {0}", helloServer2.HelloUserMethod(new User("heqichang", true)));
44
45
46 //测试SingleTon和SingleCall,多次调用
47 int count;
48 Console.WriteLine("TCP HelloMethod {0} count:{1}", helloServer1.HellTonOrCall("mswu",out count),count);
49 Console.WriteLine("http HelloMethod {0} count:{1}", helloServer2.HellTonOrCall("mswu", out count), count);
50 Console.WriteLine("http HelloMethod {0} count:{1}", helloServer2.HellTonOrCall("mswu", out count), count);
51
52 Console.ReadLine();
53 }
54 }
55}
56
2using System.Collections.Generic;
3using System.Text;
4using System.Runtime.Remoting.Channels.Tcp;
5using System.Runtime.Remoting.Channels.Http;
6using System.Runtime.Remoting.Channels;
7using General;
8namespace Client
9{
10 class Client
11 {
12 /// <summary>
13 /// 第三步,创建客户端
14 /// </summary>
15 /// <param name="args"></param>
16 public static void Main(string[] args)
17 {
18 //使用TCP通道得到远程对象代理,不用监听
19 TcpChannel tcpChannel1 = new TcpChannel();
20 ChannelServices.RegisterChannel(tcpChannel1,false);
21 HelloServer helloServer1 = (HelloServer)Activator.GetObject(typeof(General.HelloServer), "tcp://localhost:8085/SayHello");
22 if (helloServer1 == null)
23 {
24 Console.Write("Could not locate TCP server");
25 }
26
27
28 //使用HTTP通道得到远程对象代理,不用监听
29 HttpChannel httpChannel2 = new HttpChannel();
30 ChannelServices.RegisterChannel(httpChannel2, false);
31 HelloServer helloServer2 = (HelloServer)Activator.GetObject(typeof(General.HelloServer), "http://localhost:8086/SayHello");
32 if (helloServer2 == null)
33 {
34 Console.Write("Could not locate HTTP server");
35 }
36
37 //一般方法调用
38 Console.WriteLine("TCP HelloMethod {0}", helloServer1.HelloMethod("TcpChannel"));
39 Console.WriteLine("HTTP HelloMethod {0}", helloServer2.HelloMethod("HTTPChannel"));
40
41 //传递自定义类型参数
42 Console.WriteLine("TCP HelloMethod {0}", helloServer1.HelloUserMethod(new User("wumaosheng",false)));
43 Console.WriteLine("http HelloMethod {0}", helloServer2.HelloUserMethod(new User("heqichang", true)));
44
45
46 //测试SingleTon和SingleCall,多次调用
47 int count;
48 Console.WriteLine("TCP HelloMethod {0} count:{1}", helloServer1.HellTonOrCall("mswu",out count),count);
49 Console.WriteLine("http HelloMethod {0} count:{1}", helloServer2.HellTonOrCall("mswu", out count), count);
50 Console.WriteLine("http HelloMethod {0} count:{1}", helloServer2.HellTonOrCall("mswu", out count), count);
51
52 Console.ReadLine();
53 }
54 }
55}
56
先启动Server,再启动Client,测试Demo
此Demo代码下载:
/Files/mshwu/RemotingDemo1.rar