咖啡馆

有空坐下来喝杯咖啡,放松下心情~
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.Net Remoting 入门(2)

Posted on 2007-06-02 22:23  mshwu  阅读(592)  评论(1编辑  收藏  举报

在此系列随笔中,注重代码实例,对原理的深入研究不想提及太多
远程对象的两个含义:
一,操作远程对象;
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

第二步,创建宿主应用程序
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

第三步,创建客户端程序
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

先启动Server,再启动Client,测试Demo
此Demo代码下载:
/Files/mshwu/RemotingDemo1.rar