汪和康

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一,remoting基础

       一种分布式处理方式,可以说是DCOM的一种升级

       跨过应用程序域,与另外的应用程序域进行通信,即穿越边界

       在remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的

优缺点:
      优点:
      1、能让我们进行分布式开发
      2、Tcp通道的Remoting速度非常快
      3、虽然是远程的,但是非常接近于本地调用对象
      4、可以做到保持对象的状态
      5、没有应用程序限制,可以是控制台,winform,iis,windows服务承载远程对象
     缺点:
      1、非标准的应用因此有平台限制
      2、脱离iis的话需要有自己的安全机制

两种通道:

       1,Tcp    

       2,Http

       System.Runtime.Remoting.Channel中定义了IChannel接口。IChannel接口包括了TcpChannel通道类型和Http通道类型

        TcpChannel类型放在名字空间System.Runtime.Remoting.Channel.Tcp中。Tcp通道提供了基于Socket的 传输工具,使用Tcp协议来跨越Remoting边界传输序列化的消息流。TcpChannel类型默认使用二进制格式序列化消息对象,因此它具有更高的 传输性能

        HttpChannel类型放在名字空间System.Runtime.Remoting.Channel.Http中。它提供了一种使用Http协议, 使其能在Internet上穿越防火墙传输序列化消息流。默认情况下,HttpChannel类型使用Soap格式序列化消息对象,因此它具有更好的互操 作性

        通常在局域网内,我们更多地使用TcpChannel;如果要穿越防火墙,则使用HttpChannel。

 远程对象的激活方式

           客户通过通道来创建远程对象,成为对象的激活。

           remoting远程激活

                       1,服务端激活(Wellknow又翻译为知名对象)       两种方式:    1,SingleTon模式

                                                                                                       2,SingleCall模式

                       2,客户端激活

服务端激活:

         SingleTon模式:此为有状态模式。如果设置为SingleTon激活方式,则Remoting将为所有客户端建立同一个对象实例。当对象处于活动 状态时,SingleTon实例会处理所有后来的客户端访问请求,而不管它们是同一个客户端,还是其他客户端。SingleTon实例将在方法调用中一直 维持其状态

         SingleCall模式:SingleCall是一种无状态模式。一旦设置为SingleCall模式,则当客户端调用远程对象的方法时,Remoting会为每一个客户端建立一个远程对象实例,至于对象实例的销毁则是由GC自动管理的。

         举例说明:一个方法(i=0,++i)

                  SingleTon模式,第一个客户端调用得到1,而第二个得到2,依次类推.....

                  SingleCall模式,多个客户端调用都得到1.

客户端激活:与WellKnown模式不同,Remoting在激活每个对象实例的时候,会给每个客户端激活的类型指派一个URI。客户端激活模式一旦获得客户端的请求,将为每一个客户端都建立一个实例引用。

二远程对象的定义:

          remoting传递对象的方式:引用方式

                                        必须继承:MarshalByRefObject(使用代理交换消息来跨越应用程序域边界进行通信的对象的基类)

       下面我们定义一个远程对象:

       创建一个类库项目:

       

代码如下:

public class ServerObject : MarshalByRefObject//如不继承将会报此错误:尝试创建未绑定类型的代理
    {
        public Car GetCarMessage(string carname, string carcolor, int carprice)
        {
            Car car = new Car();
            car.CarName = carname;
            car.Carcolor = carcolor;
            car.Carprice = carprice;
            return car;
        }
    }

 

  [Serializable]
    public class Car
    {
        public Car() { 
        
        }
        private string carname;//车名
        private string carcolor;//颜色
        private int carprice;//价格
        public string CarName
        {
            get { return carname; }
            set { carname = value; }
        }
        public string Carcolor
        {
            get { return carcolor; }
            set { carcolor = value; }
        }
        public int Carprice
        {
            get { return carprice; }
            set { carprice = value; }
        }
    }

 

OK,远程对象定义完成,编译生成ServeObject.dll

 

三,服务器端

         新建一个控制台应用程序
        

       注册通道:

                  注册Channel 

                 注意引用:System.Runtime.Remoting.dll      ServerObject.dll

                 using System.Runtime.Remoting;
                 using System.Runtime.Remoting.Channels;
                 using System.Runtime.Remoting.Channels.Tcp;//注册TcpChannel时引用

                 using System.Runtime.Remoting.Channels.Http;//注册HttpChannel时引用
                 using ServerObject;

                  注册远程对象

                            服务端激活(两种模式)

                            WellKnownObjectMode.SingleCall  每个传入的消息由新的对象实例提供服务

                            WellKnownObjectMode.Singleton  每个传入的消息由同一个对象实例提供服务

                             客户端激活(见代码)

                             

 

public class CarServer
    {
        [STAThread]
        public static void Main(string[] args)
        {
            TcpServerChannel channel = new TcpServerChannel(8088);//注册TcpChannel
//HttpServerChannel channel = new HttpServerChannel(8089);//注册HttpChannel bool ensureSecurity = false;//确保安全 ChannelServices.RegisterChannel(channel, ensureSecurity);
//服务端激活 RemotingConfiguration.RegisterWellKnownServiceType(typeof(ServerObject.ServerObject), "Hi", WellKnownObjectMode.SingleCall);//SingleCall模式
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(ServerObject.ServerObject), "Hi", WellKnownObjectMode.Singleton  );//Singleton  模式
//客户端激活
//RemotingConfiguration.ApplicationName = "Hi"; RemotingConfiguration.RegisterActivatedServiceType(typeof(ServerObject.ServerObject)); System.Console.WriteLine("正在运行....."); System.Console.ReadLine(); } }

    注销通道:

              如果要关闭Remoting的服务,则需要注销通道,也可以关闭对通道的监听

//获得当前已注册的通道;
            IChannel[] channels = ChannelServices.RegisteredChannels;

            //关闭指定名为MyTcp的通道;
            foreach (IChannel eachChannel in channels)
            {
                if (eachChannel.ChannelName == "MyTcp")
                {
                    TcpChannel tcpChannel = (TcpChannel)eachChannel;

                    //关闭监听;
                    tcpChannel.StopListening(null);

                    //注销通道;
                    ChannelServices.UnregisterChannel(tcpChannel);
                }
            }

四,客户端

              注册通道:(见代码注释);

            获得对象:(见代码注释);

                     

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using ServerObject;
namespace RemotingClientTest
{
  public  class CarClient
    {
        public static void Main(string[] args)
        {
            TcpChannel channel = new TcpChannel();
            //HttpChannel channel = new HttpChannel();
            ChannelServices.RegisterChannel(channel, false);
            // ChannelServices.RegisterChannel(new TcpClientChannel(), false);当然这样写也是一样的。TcpClientChannel和TcpChannel基本是一样的(个人理解)
            //获得远程对象
            //服务端激活
            ServerObject.ServerObject obj = (ServerObject.ServerObject)Activator.GetObject(typeof(ServerObject.ServerObject), "tcp://10.18.1.232:8088/Hi");//WellKnown激活模式   tcp通道
            //ServerObject.ServerObject obj = (ServerObject.ServerObject)Activator.GetObject(typeof(ServerObject.ServerObject), "Http://10.18.1.232:8088/Hi");//WellKnown激活模式   Http通道

            //客户端激活
            // RemotingConfiguration.RegisterActivatedClientType(typeof(ServerObject.ServerObject), "tcp://10.18.1.232:8088/Hi");
            //ServerObject.ServerObject serverObj = new ServerObject.ServerObject();
            //方法二:调用进程Activator的CreateInstance()方法(略)
            if (obj == null)
            {
                Console.WriteLine("could not locate server");
                return;
            }
            for (int i = 0; i < 5; i++)
            {
                Car car= obj.GetCarMessage("宝马","蓝色",1000000);
                Console.WriteLine(car.CarName + car.Carcolor + car.Carprice);
                Console.ReadKey();
            }

        }
    }
}

 

   五,运行效果

             服务端:

                   

              客户端:

                

          OK,初学者写的可能有很多不足,还请多多指教!

 

 

 

 

 

posted on 2012-04-24 15:00  Supe  阅读(1922)  评论(0编辑  收藏  举报