WCF分布式开发必备知识(2):.Net Remoting

.Net Remoting技术,我们可以将其看作是一种分布式处理方式。作为应用程序之间通信的一种机制,.Net Remoting与MSMQ消息队列不同,它不支持离线脱机消息,另外只适合.Net平台间程序的通信.从微软的产品角度来看,可以说Remoting就是分布式组件DCOM的一种升级,它改善了很多功能,并极好的融合到.Net平台下。.NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架。这也正是我们使用Remoting的原因。为什么呢?在Windows操作系统中,是将应用程序分离为单独的进程。这个进程形成了应用程序代码和数据周围的一道边界。如果不采用进程间通信IPC(Internet Process Connection)机制,则在一个进程中执行的代码就不能访问另一进程。这是一种操作系统对应用程序的保护机制。然而在某些情况下,我们需要跨过应用程序域,与另外的应用程序域进行通信,即穿越边界(参考MSDN)。

现在来介绍一下其中涉及到的几个比较重要的概念:

1.通道(channel),

  在.Net Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的。首先,客户端通过Remoting,访问通道以获得服务端对象,再通过代理解析为客户端对象。这就提供一种可能性,即以服务的方式来发布服务器对象。远程对象代码可以运行在服务器上(如服务器激活的对象和客户端激活的对象),然后客户端再通过Remoting连接服务器,获得该服务对象并通过序列化在客户端运行。

通道(channel)有4种严格说,很多资料上说有2-3种.应该有4种.HttpChanel和TcpChanel.

(1)HttpChannel。在将远程对象驻留在 ASP.NET 中时,可以使用此通道。此通道使用 HTTP 协议在客户端和服务器之间发送消息。可以使用HTTP协议中的加密机制.需要主机名字和端口号.
  (2)TcpChannel。在将远程对象驻留在  操作系统服务或其他可执行文件中时,此通道使用 TCP 套接字在客户端和服务器之间发送消息。同样需要提供主机名字和端口号.不提供任何内置的安全功能。

(3)IPCChanel,进程间通道,只使用同一个系统内,进程之见的通信.不需要需要主机名字和端口号.
  (4)自定义通道 。自定义的传输通道可以使用任何基本的传输协议UDP/SMTP/IPX/消息排队等机制进行通信.用户可以根据需要自定义方式协议,因此.Net Remoting相对其他机制更加的灵活。不提供任何内置的安全功能。

2.远程对象(Obeject)

  在Remoting中要传递的对象,设计者除了需要了解通道的类型和端口号之外,无需再了解数据包的格式。但必须注意的是,客户端在获取服务器端对象时,并不是获得实际的服务端对象,而是通过代理获得它的引用。远程对象要继承自MarshalByRefObject类,这个可以使远程对象在remoting应用通信中使用,支持对象的跨域边界访问.

3.激活方式

(1)服务器端激活,又叫做知名WellKnown方式,是因为服务器应用程序在激活对象实例之前会在一个众所周知的统一资源标识符(URI)上来发布这个类型。然后该服务器进程会为此类型配置一个WellKnown对象,并根据指定的端口或地址来发布对象。服务器端激活又分为SingleTon模式和SingleCall模式两种。SingleTon模式:此为有状态模式。如果设置为SingleTon激活方式,则Remoting将为所有客户端建立同一个对象实例。SingleCall模式:SingleCall是一种无状态模式。一旦设置为SingleCall模式,则当客户端调用远程对象的方法时, Remoting会为每一个客户端建立一个远程对象实例,至于对象实例的销毁则是由GC自动管理的。

  (2)客户端激活。与WellKnown模式不同, Remoting在激活每个对象实例的时候,会给每个客户端激活的类型指派一个URI。客户端激活模式一旦获得客户端的请求,将为每一个客户端都建立一个实例引用。SingleCall模式和客户端激活模式是有区别的:首先,对象实例创建的时间不一样。客户端激活方式是客户一旦发出调用的请求,就实例化;而SingleCall则是要等到调用对象方法时再创建。其次,SingleCall模式激活的对象是无状态的,对象生命期的管理是由GC管理的,而客户端激活的对象则有状态,其生命周期可自定义。其三,两种激活模式在服务器端和客户端实现的方法不一样。尤其是在客户端,SingleCall模式是由 GetObject()来激活,它调用对象默认的构造函数。而客户端激活模式,则通过CreateInstance()来激活,它可以传递参数,所以可以调用自定义的构造函数来创建实例。(详细参考MSDN)
     (4)代理Proxy,客户端访问的不能直接访问远程对象,它是通过代理来访问代理上的方法.代理对象又分为透明代理和真实代理,区别是,在透明代理上,客户通过Invoke调用的是远程对象上真实代理的方法.然后把消息再传递给通道.

好了,介绍到此我们也基本了解.Net Remoting相关的知识,下面我们来学习的是具体的编程实现部分.程序大体分为3个部分远程对象/服务器/可户端.现在我们来分别实现.服务器端要添加引用System.Runtime.Remoting的程序集.

1.远程对象(RemoteOject),也就是我们远程要访问的对象.首先定义一个Class,继承MarshalByRefObject,可以使用在remoting应用中,支持对象的跨域边界访问.具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    //创建远程对象,继承MarshalByRefObject,可以使用在remoting应用中,支持对象的跨域边界访问
    public class MyRemoteObject : MarshalByRefObject//访问远程对象需要通过代理
    {
        //实现加法功能的方法,这个远程对象可以实现封装业务逻辑或者数据访问等操作
        public int AddForTcpTest(int a, int b)
        {
            return a + b;
        }

        //实现减法功能,测试HTTP通道
        public int MinusForHttpTest(int a, int b)
        {
            return a - b;
        }
        //实现乘法功能,测试Ipc通道
        public int MultipleForIpcTest(int a, int b)
        {
            return a * b;
        }
    }
}

2服务器端,注册通道,以便进程间通信,我们这里注册了三种通道,分别是HttpChanel/TcpChanel/IPCChanel.具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Remoting.Channels.Tcp;
using System.Text;
using System.Threading.Tasks;
using Model;

namespace NetRemoting
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建三种通道
            //创建Tcp通道,使用端口10001
            TcpChannel chanTcp = new TcpChannel(10001);
            //创建Http通道,使用端口10002
            HttpChannel chanHttp = new HttpChannel(10002);
            //创建Ipc通道,Ipc只适合同系统内进程的通信,所以不需要设置端口和主机名
            IpcChannel chanIpc = new IpcChannel("YXLTestIpc");

            //注册通道
            //注册TCP通道
            ChannelServices.RegisterChannel(chanTcp);
            //注册Http通道
            ChannelServices.RegisterChannel(chanHttp);
            //注册Ipc通道
            ChannelServices.RegisterChannel(chanIpc);
            ////////////////////////////////////////打印通道/////////////////////////////////////////////////
            // 打印TCP通道的名称.
            Console.WriteLine("The name of the TCPChannel is {0}.",
                chanTcp.ChannelName);
            // 打印TCP通道的优先级.
            Console.WriteLine("The priority of the TCPChannel is {0}.",
                chanTcp.ChannelPriority);

            // 打印Http通道的名称.
            Console.WriteLine("The name of the HttpChannel is {0}.",
                chanHttp.ChannelName);
            // 打印Http通道的优先级.
            Console.WriteLine("The priority of the HttpChannel is {0}.",
                chanHttp.ChannelPriority);

            // 打印IPC通道的名称.
            Console.WriteLine("The name of the IpcChannel is {0}.",
                chanIpc.ChannelName);
            // 打印IPC通道的优先级.
            Console.WriteLine("The priority of the IpcChannel is {0}.",
                chanIpc.ChannelPriority);
            ///////////////////////////////////////////注册对象/////////////////////////////////////////////////
             //注册对象MyRemoteObject到Net Remoting运行库
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyRemoteObject), "RemoteObject.MyRemoteObject",
                WellKnownObjectMode.Singleton);
            ///////////////////For Debug/////////////////////////////////////////////////////////////////////////
            Console.WriteLine("Press any key to exit!");
            System.Console.ReadLine();
        }
    }

}

创建Tcp通道,使用端口10001, 创建Http通道,使用端口10002,创建IPC通道,使用端口10003,IPC只适合同系统内进程的通信,所以不需要设置端口和主机名.然后调用ChannelServices类的静态方法RegisterChannel进行注册.最后一步注册对象MyRemoteObject到Net Remoting运行库,同时要先配置远程通信基础框架.第2个参数是对象的URI,“RemoteObject.MyRemoteObject”,客户端URL一定要和这个匹配,不然会出现查找不到代理对象的异常.WellKnownObjectMode.Singleton);远程对象激活方式是单件激活模式,每次调用共享一个对象,SingleCall激活模式会在每次调用的时候产生一个新对象.

3客户端是控制台程序(实际项目类型可以替换,这里只是为了作为例子选择控制台类型).配置文件进行的设置如下:

<configuration>

  <appSettings>
         <add key="ServiceURLTcp" value="tcp://localhost:10001/RemoteObject.MyRemoteObject"/>
         <add key="ServiceURLHttp" value="http://localhost:10002/RemoteObject.MyRemoteObject"/>
         <add key="ServiceURLIpc" value="ipc://YXLTestIpc/RemoteObject.MyRemoteObject"/>

  </appSettings>
   <system.runtime.remoting>

  </system.runtime.remoting>
</configuration>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;

namespace NetRemotingClient
{

    class Program
    {
         [STAThread]
        static void Main(string[] args)
         {
             MyRemoteObject proxyObjectTcp =
                 (MyRemoteObject)Activator.GetObject(typeof(MyRemoteObject), ConfigurationManager.AppSettings["ServiceURLTcp"]);
                 //通过代理访问对象的方法,输出结果
             Console.WriteLine("This call object by TcpChannel,100+200 = {0}", proxyObjectTcp.AddForTcpTest(100, 200));
             MyRemoteObject proxyObjectHttp =
                (MyRemoteObject)Activator.GetObject(typeof(MyRemoteObject), ConfigurationManager.AppSettings["ServiceURLHttp"]);
             //通过代理访问对象的方法,输出结果
             Console.WriteLine("This call object by HttpChannel,100-200 = {0}", proxyObjectHttp.MinusForHttpTest(100, 200));
             MyRemoteObject proxyObjectIpc =
                (MyRemoteObject)Activator.GetObject(typeof(MyRemoteObject), ConfigurationManager.AppSettings["ServiceURLIpc"]);
             //通过代理访问对象的方法,输出结果
             Console.WriteLine("This call object by TcpChannel,100*200 = {0}", proxyObjectIpc.MultipleForIpcTest(100, 200));
             Console.ReadKey();
         }
    }
}
时间: 2024-10-17 22:23:32

WCF分布式开发必备知识(2):.Net Remoting的相关文章

WCF分布式开发必备知识(1):MSMQ消息队列

本章我们来了解下MSMQ的基本概念和开发过程.MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间的任一位置.它的实现原理是:消息的发送者要把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中,本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理.其中两个重要的概念

WCF分布式开发步步为赢(7):WCF数据契约与序列化

本节继续学习WCF分布式开发步步为赢(7):WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤.那么序列化是什么?为什么会有序列化机制?或者说它是为了解决什么问题?作用是什么?现有的.NET 序列化机制和WCF序列化机制有什么不同?我们在本节文章里都会详细介绍.本节结构:[0]数据契约[1]序列化基本概念[2].NET 序列化机制[3]WCF序列化机制[4]代码实现与分析[5]总结. 下面我们正式进入今天的学习阶

WCF分布式开发步步为赢(1):WCF分布式框架基础概念

众所周知,系统间的低耦合一直是大型企业应用系统集成追寻的目标,SOA面向服务架构的出现为我们的如何利用现有企业系统资源进行企业ERP系统设计和实现提供了重要的参考原则.SOA如此炙手可热,各大厂商都推出了自己的中间件产品,比如Oracle Fusion和 SAP NetWeaver,IBM.BEA等企业也推出了自己基于SOA的解决方案.基于J2EE平台的SOA架构设计中的一个重要概念就是EJB企业服务总线,作用是实现各个系统的数据交互.而.NET平台上,WCF就是微软为各个系统的数据交互提供通讯

WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. 作为面向服务应用的开发平台,WCF也提供了对事物编程模型的支持..NET 2.0提供的System.Transactions类来开发事务应用程序.同样WCF也支持事务特性,WCF事务机制是什么,它与微软已有的技术如Microsoft 分布式事务协调器 (MSDTC)有何关系?与Enterpise

WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ

之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ消息队列的基本概念.安装.部署.开发.调试等相关问题.今天我们来学习WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ.在WCF框架下使用MSMQ消息队列服务编程.  这里我会给出一个使用WCF MSMQ实现离线请求的DEMO示例程序. 全文结构是:[1]MSMQ基本概念[2]W

WCF分布式开发步步为赢(4):WCF服务可靠性传输配置与编程开发

今天继续WCF分布式开发步步为赢系列的第4节:WCF服务可靠性传输配置与编程开发.这个章节,我们要介绍什么是WCF服务的可靠性传输,随便介绍网络协议的概念,Web Service为什么不支持可靠性传出,具体的WCF绑定协议和可靠性的关系,实现可靠性传输有什么方式,以及配置和开发的详细实现代码分析部分.[1]可靠性传输[2]配置方式实现可靠性传输[3]编程方式实现可靠性传输[4]编程实现必备有序传递[5]结果分析和总结. 下面进入正式的内容: [1]可靠性传输: [1.0]网络协议基础知识: 这里

WCF分布式开发步步为赢(6):WCF服务契约继承与分解设计

上一节我们学习了WCF分布式开发步步为赢(5)服务契约与操作重载部分.今天我们来继续学习WCF服务契约继承和服务分解设计相关的知识点.WCF服务契约继承有何优势和缺点?实际项目里契约设计有什么原则和依据?面向对象的设计经验有何值得借鉴的地方?这里我们会一一给出详细的介绍.本文首先介绍的是WCF服务中契约继承的一些概念.例子代码分析,其次来讲解服务契约的设计问题.首先介绍的也是进行服务设计的必要性,服务设计的原则,示例代码分析.最后是全文的总结部分.结构如下:[1]OO面向对象设计原则,[2]服务

WCF分布式开发步步为赢(15):错误契约(FaultContract)与异常处理(ExceptionHandle)

今天学习WCF分布式开发步步为赢系列的15节:错误契约(FaultContract)与异常处理(ExceptionHandle).本节内容作为WCF分布式开发的一个重要知识点,无论在学习还是项目中都应该有所了解.此前也和多位学习爱好者讨论过WCF异常处理的相关知识.这里就系统整理一下,共大家参考.同时也是对<WCF分布式开发步步为赢>系列文章的完善和补充.   本节主要涉及的知识点就是:[1].NET异常处理[2]WCF异常处理[3]错误契约[4]WCF异常处理扩展[5]示例代码分析,最后是[

移动端webapp开发必备知识

移动端webapp开发必备知识 移动设备的用户越来越多,每天android手机的激活量都已经超过130万台,所以我们面向移动终端的WebAPP也开始跟进了.本文主要介绍webapp的开发与调试的相关知识和经验,以及给出几种可选的解决方案. 一.基本概念 (1) CSS pixels与device pixels CSS pixels: 浏览器使用的抽象单位, 主要用来在网页上绘制内容. device pixels: 显示屏幕的的最小物理单位,每个dp包含自己的颜色.亮度. 等值的 CSS pixe