.NET简谈组件程序设计之(详解NetRemoting结构)51CTO博客 - 凯发娱乐

.NET简谈组件程序设计之(详解NetRemoting结构)51CTO博客

2019年04月02日12时16分11秒 | 作者: 涵亮 | 标签: 程序,处理,接口 | 浏览: 916

在自己的上一篇文章中仅仅简略的介绍了一下.NETRemoting的一般概念和底子的运用。这篇文章我想经过自己的学习和了解将对.NETRemoting的全体的一个结构进行浅显的解说,其间最重要的便是信道(管道)处理模型思维,这儿边蕴含了许多的规划原理。[王清培版权一切,转载请给出署名]
.NETRemoting长途处理架构是一个半成品,是.NET给咱们的扩展结构,要想用于商业项目有必要进行一些安全、功用方面的操控。要想进行必定深度的扩展那就要有必要了解它的全体结构,各个点之间的联系才干很好的操控它。 网上解说.NETRemoting的文章许多,可是浅显易懂的没有几篇,都是大约解说了一下全体模型或许从MSDN上COPY过来,未能对各模型之间的接口做详细解说。了解.NETRemoting的朋友都知道,它的完成底子上都是经过接口与接口之间的串联构成处理管道,这也让咱们想起来了规划形式中首要提及的面向目标规划思维“面向接口编程”。 自己在学习.NETRemoting的时分仍是比较苦楚的,由于中文材料缺少只能经过查找网上零零散散的知识点再经过拼命的了解、换位考虑、进步笼统层次,才总算参透为什么那么多接口之间的联系,在这儿小弟会逐个解说那些比如IClientChannelSink、IClientChannelSinkProvider、IMessageSink等等接口到底是什么意思,供给程序与信道接纳器之间又是啥联系,在信道处理模型中是怎样使用多态来规划的。
.NETRemoting处理管道 在.NETRemoting中它的全体处理模型有点像ASP.NET中的HTTP处理管道模型,音讯从最上面的进口进入然后一个一个的传递到各个处理模块中,这样就构成了一个笼统的处理管道。 图1(客户端信道处理):   这是客户端信道处理模型的大约结构。任何客户端对跨长途处理都是经过署理进行的,署理分为两部分一种是通明署理,一种是实在署理; 通明署理是经过实在署理动态生成的,通明署理的一切成员都是客户端行将调用的长途目标的一个虚拟镜像。为什么要说是虚拟的,是由于通明署理仅仅便利客户端调用的,当咱们NEW一个长途目标时,体系将为咱们动态的生成一个承继自你NEW的那个目标的代码,然后动态生成内存通明署理目标。 通明署理包含了对实在署理的调用,实在的暗地主脑是RealProxy目标,它包含了对信道处理结构的引证。在上面的图1中为什么实在署理是用IMessageSink接口来发动整个信道处理模型的。这儿也是最尴尬了解的进口点,下面咱们将自己的笼统才干提高一个层次才干知道体系为什么要这样规划。[王清培版权一切,转载请给出署名]
图2(服务器端信道处理): .NETRemoting饶人的名词解释 不管是服务器端仍是客户端都是经过信道处理模型来对两边的音讯进行一系列的处理。客户端的信道处理和服务器端的信道处理有点差异,这些差异是来自它们的更高层次的笼统。这句话或许底子欠好了解,从我上面的两幅图中我想读者多多少少能了解点意思来,在信道处理管道中都是经过每个信道接纳器供给程序来创立有处理能的信道接纳器。 咱们先来处理一些会给咱们了解带来困扰的英文单词: Channel:在体系中它表明信道,也便是处理管道。 IChannel:表明一个笼统的处理办理,用来标识一个管道的信息,如管道称号,管道等级之类的。 Sink:接纳器,也便是管道中的音讯处理环节,体系通常用这个单词来组合,也会让初学者简单参数混杂(看过这篇文章后你就不会在混杂了)。 Provider:一般表明为供给程序,在.NETRemoting里边的供给程序这是某些环境的一个进口点,比如在体系中序列化环节,体系经过SoapClientFormatterSinkProvider供给程序来创立SoapClientFormatterSink信道接纳器,这儿的供给程序是表明行将进入处理进程,这个处理进程表明某一个处理环节,在这个处理环节中或许包含许多用来接纳要处理的信息,一切叫做信息接纳器,也便是sink结束的接口。 IClientChannelSinkProvider:客户端信道接纳器供给程序,也便是图1中表明的每个对音讯的处理环节部分。该接口有一个NEXT特点用来衔接下一个供给程序,这样就串联起一个笼统的处理管道。咱们要记住供给程序这是创立处理环节的进口点,实在用来处理音讯的是sink结束的接口,这儿也便是IClientChannelSInk目标。 IClientChannelSink:客户端音讯接纳器,用于在管道处理中对音讯的传递进行个性化修正,咱们能够在这个里边进行一些音讯传递的紧缩、编码等等。 IServerChannelSinkProvider:服务器端信道接纳器供给程序,和客户端是相同的功用,都是用来创立信息接纳器用的,只不过这儿是服务器端的信息处理。 IServerChannelSink:服务器端音讯接纳器,用来在服务器端进行音讯的处理,能够对传输过来的音讯进行解紧缩、反编码等等,与客户端功用是对应的。 IMessageSink:入门的朋友或许会对这个接口参数误解,这是啥接口啊?我不是有了Sink类型的接口了吗?为什么还要音讯接口?其实这儿也很好了解,为什么需求各式各样的接口,这便是我上面所说的“将自己的笼统才干提高一个高度”才干了解。假如对接口编程不是很熟悉的朋友或许是不太好了解。每种接口表明某种笼统,我打个比如,假如有一个目标它既完成了IMan接口,又完成了IDog接口,它在与人沟通的时分咱们知道它是完成了人类接口的目标,所以咱们知道它并且能与它进行沟通,假如它与狗沟通的话那么狗狗也是知道它的由于它也完成了狗的接口。从这儿讲,完成多个接口的目标具有很深的笼统层次,在某些场合它被视为一种类型,在别的一些场合它又被视为另一种类型。下面咱们讲到详细的接口完成时,就了解我所说的意思了。 .NETRemoting信道接纳器 上面的名词解释的差不多了,咱们来动动手吧; 依照上面的客户端信道模型图,咱们先来完成一个IClientChannelSinkProvider接口,咱们将使用这个接口来创立一个能处理音讯的IClientChannelSink接口。 using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Ipc;

namespace MyClassLibrary.CustomProvider
{
        public class ClientCustomProvider : IClientChannelSinkProvider
        {
IClientChannelSinkProvider 成员#region IClientChannelSinkProvider 成员
                /// <summary>
                /// 创立该供给程序的信道接纳器,一切的信道接纳器供给程序均要完成CreateSink办法,确保一切的信道接纳器能串联起来。
                /// </summary>
                /// <param name="channel">上下文发送接口</param>
                /// <param name="url">目标的终结点</param>
                /// <param name="remoteChannelData">信道数据</param>
                /// <returns>IClientChannelSink客户端信道接纳器接口</returns>
                public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData)
                {
                        return new ClientCustomSink(Next.CreateSink(channel, url, remoteChannelData));
                }
                /// <summary>
                /// 获取下一个信道接纳器供给程序。经过这儿的NEXT特点将一切的信道接纳器衔接起来。
                /// </summary>
                public IClientChannelSinkProvider Next { get; set; }

                #endregion
        }
} 这儿是咱们创立客户端接纳器供给程序的代码,在这儿咱们创立个一个ClientCustomSink信道接纳器目标,可是在结构函数中咱们用NEXT特点又创立了一个信道接纳器作为参数传入到目标,这样做的意图便是能确保每一个音讯接纳器处理完成后能接着传递给下一个信息接纳器处理。 using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Ipc;

namespace MyClassLibrary.CustomProvider
{
        public class ClientCustomSink : BaseChannelSinkWithProperties, IClientChannelSink
        {
                IClientChannelSink nextchannelsink;
                public ClientCustomSink(IClientChannelSink nextchannel)
                {
                        nextchannelsink = nextchannel;
                }
IClientChannelSink 成员#region IClientChannelSink 成员

                public void AsyncProce***equest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, System.IO.Stream stream)
                {
                        nextchannelsink.AsyncProce***equest(sinkStack, msg, headers, stream);
                }

                public void AsyncProce***esponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, System.IO.Stream stream)
                {
                        nextchannelsink.AsyncProce***esponse(sinkStack, state, headers, stream);
                }

                public System.IO.Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
                {
                        msg.Properties.Add("自界说音讯", "自界说音讯值");
                        return nextchannelsink.GetRequestStream(msg, headers);
                }

                public IClientChannelSink NextChannelSink
                {
                        get { return nextchannelsink; }
                }

                public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, System.IO.Stream requestStream, out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
                {
                        nextchannelsink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);
                }
                public IDictionary NextProperise
                {
                        get { return nextchannelsink.Properties; }
                }
                #endregion
        }
} 有一这儿的代码太长我就不加注释了。这个目标首要完成了IClientChannelSink接口,也便是信道接纳器接口,在这个接口面明前比Provider供给程序多了许多东西。这儿才是实在处理的当地,体系为了代码的整齐性将供给程序与信息接纳器分脱离,其实也能够将这两个接口进行兼并。在结构函数里边咱们用一个私有的IClientChannelSink保存了下一个Sink。该目标还完成了BaseChannelSinkWithProperties笼统类,这个类是用来获取下一个信道接纳器的内部特点用的。假如咱们没有完成这个笼统类就要自己完成NextProperise特点。[王清培版权一切,转载请给出署名]
其实在IClientChannelSink里边比较重要的便是GetRequestStream和ProcessMessage两个办法,一个是用来获取即行将发送的Stream流,一个是进行发送的办法。为了便于咱们的了解,请看图3: 我上面的处理流程不必定便是GetRequestStream是第一步,可是它是ProcessMessage办法的上一步,所以我用1、2表明。当GetRequestStream到了最终一个Sink时,体系将进行最终的调用,也便是进行长途发送了。
在GetRequestStream中咱们加入了一些自己界说的数据,咱们在经过服务器端的IServerChannelSink获取这音讯。 using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Ipc;

namespace MyClassLibrary.CustomProvider
{
        public class ServerCustomSink : BaseChannelSinkWithProperties, IServerChannelSink
        {
                private IServerChannelSink iserverchannelsink;
                public ServerCustomSink(IServerChannelSink serverchannel)
                {
                        iserverchannelsink = serverchannel;
                }
IServerChannelSink 成员#region IServerChannelSink 成员

                public void AsyncProce***esponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, System.IO.Stream stream)
                {
                        if (iserverchannelsink != null)
                                iserverchannelsink.AsyncProce***esponse(sinkStack, state, msg, headers, stream);
                        throw new NotImplementedException();
                }

                public System.IO.Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers)
                {
                        if (iserverchannelsink != null)
                                iserverchannelsink.GetResponseStream(sinkStack, state, msg, headers);
                        throw new NotImplementedException();
                }

                public IServerChannelSink NextChannelSink
                {
                        get { return iserverchannelsink; }
                }

                public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders,
                        System.IO.Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
                {
                        sinkStack.Push(this, "ok");
                        return NextChannelSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
                }

                #endregion

        }
} 图4: 总结: .NETRemoting是一个十分老练的CLR长途处理结构,其完成的原理也很杂乱,底子上每一部分都能够扩展,它的内部完成都是经过面向接口来的,接口的粒度也十分小。从IXXXChannelSinkProvider和IXXXChannelSink两种接口就能够看出来,里边的空间很大。 本篇文章仅仅自己在学习.NETRemoting进程中的一点小小的感悟献给那些还没有搞清楚Remoting的底子结构的朋友。谢谢  
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表凯发娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章