下载项目的数据库
目录
简介
背景
为什么是WCF?
WCF历史简述
WCF基础
点对点概念
代码分析(它是怎么工作的)
核心转化引擎层
下载管理层
服务层
代码的使用(如何运行这个应用)
当前的应用是什么样的?
洩漏总结
在这个项目的开发中如何合作?
深入学习的外部资料
兴趣点
结语
历史
简介
由于缺少计算、存储和数据资源使得我们产生了这个想法。我们可以使用大量的不确定的资源,这些资源已经存在全球用户的电脑中。例如,我们可以使用PC机的计算资源,这些资源大多数时间是闲置的,另一方面,我们可以使用已经存储在电脑中的大量的数据。更进一步,我们可以让这些资源直接连接起来,使用它们的数据,而不是连到一个中央服务器来满足我们的需要。在我们研究集中式架构时,出现了一些问题,随着时间的推移,这些问题越来越棘手,问题的增长迫使我们转化更强大的硬件,基础设施等。随后,我们就得使用更高的带宽和更强大的服务器,甚至于是超极计算机,这将花费我们大量的资金。为解决这些问题一种新的称之为“分布式系统”的计算系统产生了。分布式系统是一个软件系统,它的组件是位于网络中的计算机,它们通过传递消息来通信和协作。
点对点(P2P)计算或者网络是一种分布式的应用架构,它把任务或者作业负载分散到各个结点中。每个结点有相同的权限、均等的参与到应用中。据说点对点的网络是由结点构成的。每个结点都是网络中的一台计算机,它们与其它的结点通信,分配它们的部分资源:例如处理能力、硬盘存储或者网络带宽,对于网络中的其它参与者是直接可用的,不需要服务器或者稳定的主机的中央协调【1】。
各个结点既是资源的提供者也是资源的消费者,这不同于传统的客户端-服务器模式,在传统模式中,资源的消费和供给常常是分开的。新兴的协作式P2P系统早已超出了结点做相同的事情并共享资源的那个时代,新兴的P2P系统正在寻找各种结点,这些结点可以带来独特的资源和处理能力,从而形成一个虚拟的社区,由此授权它自身参与到更大的任务中,这此任务远远超过了单一结点所能完成的任务,这将使得所有的结点都受益【2】。
你可以在Torrents项目中看到P2P实现的,P2P实现的还有一些著名的文件共享系统例如Emule项目。下面我将解释P2P文件共享系统。
我用了一年多去思考Torrents是如何工作的,Emule是如何工作的。直到在研究生的分布式系统的课上之前,我都没有抓住正确地机会去研究它;在这门课上,我的老师要求我们开发一个点对点地文件分享系统作为最后考试的一部分。那时候,我很激动,因为这个事情一直是我喜欢的领域,这个问题在我脑海里存在了很长时间。然后我开始研究它,结果很令人失望;同时越多的学习导致了更多的困惑。然后我决定找一段例子去得到一些基本的信息,然后扩展它们到相关的书籍里面。直到我能开始对BUT编码,我仍然很失落;因为我不能找到任何通过WCF来完成两个点之间文件共享的资料。我只能找到一些代码段,它们是针对点对点聊天的;这些根本不够。然后我开始在CodeProject论坛上面,询问我的问题围绕着“关于点对点系统的学习资料”,“一种可适用的代码例子”,“一个在代码项目上的好文章”和其他相关的关键句来搜寻。但是这一点帮助都没有,因为结果既不是有用的知道,也不是答案。你可以阅读我的问题在这里here 和这里here.
最终,我发现我需要通过自己来开始我的工作;没有一种横切的方法来达到我的目标。在这篇文章中,我将为所有有热情的程序员,采用直接的方式去告诉他们如何得到关于点对点系统和基于点的文件分享的方法的有用信息。我们回到真实地问题上来,准备好了吗?我们开始吧。
微软开发了COM(元件对象模型)用于在本地机器上,应用元件彼此之间的交互、交流;但是COM并没有提供对在分布式系统中的远程调用提供元件之间沟通的方法。然后,微软开发了DCOM(分布式元件对象模型)去弥补COM的补足。DCOM提供一种机会,在不同位置分发应用元件。并且,DCOM提供了一种架构,去保证安全、可靠性和位置独立的问题。.NET远程在.NET中被引入去创建分布式应用。“它依赖于DCOM作为倾向的技术去创建分布式引用。它解决的问题是困扰了分布式应用很多年的问题(比如,互操作的支持,可扩展的支持,生命周期管理的高效性,定制主机和简单地配置进程)。在默认的分布式计算中,.NET远程发布提供了简单、可扩展的程序模型,没有牺牲灵活性、可扩展性和健壮性。这来自于默认的可执行元件,包括渠道和协议;但是所有的这些都是补充,可以被其他更好的选项替代而不需要很多的代码修改”【Pro WCF4,实用的微软SOA实现】。COM+是一种结合COM和DCOM的方法。它提供了一种架构,允许应用程序采用它去接入服务和功能,而不需要开发团队去创建这些服务和功能。COM+最初被引入是为COM提供一种架构,但是.NET同样可以使用它的服务。
那么,为什么web服务会作为一个新的沟通方式呢?
想象一下,如果你开发了一个基于com+的应用程序,另外一个应用程序如何通过使用Java来进行编码呢?我们如何与运行于其他平台,操作系统,等等的另一个应用程序进行沟通呢?我们得出结论,互操作性有时候是企业花费高昂的成本,通过使用一个“桥应用程序”作为中间件来实现它的一个重要问题。web服务使这种互操作性变得更方便,更便宜。web服务并不是 创建分布式应用程序的另一种方式。相当于其他分布式技术,web服务的显著特点不是依赖于专有标准与协议,而是依赖于开放的web标准(诸如:soap,http,以及XML)。这些开放的标准被广泛地认可和整个行业所接受。web服务已经改变了如何创建分布式应用程序。互联网已经创建了一个松散的耦合和互操作性的分布式技术。具体而言,之前的web服务,大部分的分布式技术依赖于面向对象的范例,但是web创造了一个自主和独立平台的分布式组件需要。[预WCF4,实用的微软SOA实现]
WCF囊括了分布式技术的众多最佳部分。它包括了ASMX的有效性,.NET远程处理的能力、可扩展性和灵活性,MSMQ创建队列应用的强大能力和WSE的互操作性。下面的图片很清晰的展示了WCF和它的应用(更多信息,请参阅Pro WCF4 手册)。
图片来源于"Pro WCF 4"手册。
WCF基础
因为使用WCF需要了解它的基本概念,这部分将讲述它的一些基础知识。一些开发人员用WCF项目取代了网络服务,他们以为自己知晓WCF,但我要说的是,不是这样的,因为在学习细节之前,WCF远比你们所想像的要深刻。现在我们开始:
终端结点:终端结点是服务向外部暴露自己的一种方式。每个终端结点都包含了路径的信息,这个路径决定了通过何种方式可以该问服务。终端结点是地址、绑定和契约的组合。
地址:指出了在哪可以发送消息,或者服务在哪是健在的和可用的。
绑定:描述了如何发送消息。
契约:描述了消息应当包含哪些消息。
在一些场景,我们要使用一些公共的地址、绑定和契约集。这时我们就得有默认的或者标准的地址、绑定和契约集。
下面列出了一系列标准终端结点(Standard Endpoints):
(译者注:此处英文原文应该是错行了,首先,英文原文在最后一点上不应该有Adresses,否则无法解释,其次,点击进入相应类的msdn说明,可以发现原网站上的英文原文错行了)
mexEndpoint用来表现服务元数据的标准终端结点类。
AnnouncementEndpoint: 服务用来发送声明消息的标准终端结点类。
DiscoveryEndpoint: 服务用来发送发现消息的标准终端结点类。
UdpDiscoveryEndpoint: 在UDP多播绑定上,预配置好的用以进行发现操作的标准终端结点类。
UdpAnnouncementEndpoint: 让服务通过UDP绑定发送声明消息的标准终端结点类。
DynamicEndpoint: 在运行时,使用WS-Discovery动态地寻找终端地址的标准终端结点类。
ServiceMetadataEndpoint: 用以元数据交换的标准终端结点类。
WebHttpEndpoint: 带有WebHttpBinding绑定并自动添加了WebHttpBehavior行为的标准终端结点类。
WebScriptEndpoint: 带有WebHttpBinding绑定并自动添加了WebScriptEnablingBehavior行为的标准终端结点类。
WebServiceEndpoint: 带有WebHttpBinding绑定的标准终端结点类。
WorkflowControlEndpoint: 允许对于workflow实例调用控制操作的标准终端结点类。
WorkflowHostingEndpoint: 支持工作流创建及书签式恢复的标准终端结点类。
地址(Addresses) :如果需要使用WCF服务并能够向其发送消息,那么地址是必要的。WCF中的地址由几部分组成,包括: 端口号(Port)、机器名(Machine Name)、传输模式(Transport Scheme)、路径(Path)。 端口号是可选域,传输模式是消息传输的协议。于是,服务地址的格式如下所示:
scheme://<machinename>[:port]/path1/path2
地址的简单范例如下:
<endpoint address="http://localhost:8080/QuickReturns/Exchange" bindingsSectionName="BasicHttpBinding" contract="IExchange" />
当有多个终端结点与一个WCF服务相关联,你可以定义一个主地址(primary address),并且把那些终端结点定义在相对地址上。主地址也叫做基地址。你可以如下定义基地址:
<host> <baseAddresses> <add baseAddress="http://localhost:8080/QuickReturns"/> <add baseAddress="net.pipe://localhost/QuickReturns"/> </baseAddresses> </host>
而终端结点的相对地址就会像这样:
<endpoint name="BasicHttpBinding" address="Exchange" bindingsSectionName="BasicHttpBinding" contract="IExchange" /> <endpoint name="NetNamedPipeBinding" address="Exchange" bindingsSectionName="NetNamedPipeBinding" contract="IExchange" />
绑定(Binding): 绑定定义了你与一个服务联系的方法。根据这一定义,有如下一些预定义的绑定。
Contracts: Contracts可以用来获取不同平台上的协作,同时也是用来把服务表现在外界的一系列转换。 每个Contract具有不同的特点。ServiceContract类是服务的外在表现形式,DataContract用来引入持久性数据 (服务的域和属性),MessageContract使得我们可以在考虑时间需求、服务功能、安全性等等情况下,定制SOAP消息。OperationContract是MessageContract的组成部分,用来表现访问及使用服务的方法。
namespace GettingStartedLib { [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")] public interface ICalculator { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Multiply(double n1, double n2); [OperationContract] double Divide(double n1, double n2); } } [ServiceContract] public class Calculator { [OperationContract] public double Add(double a, double b) { … }; [OperationContract] private double Subtract(double a, double b) { … }; }
Channel是用来在客户端和服务端之间,根据选择的消息模式传输数据的。Channel由工厂类创建,因而可以通过特定的或者一系列channels与服务端联系。在下图中,你可以看到消息栈的结构和其中channel的位置。
我们可以这样认为,Binding类是控制Channel栈的处理器。当你选择了一个预定的binding,意味着你选择了一个特定的Channel。
ServiceHost是一个允许你以编程方式制做一个服务主机的类,你可以用它做很多事,如设置行为,地址,绑定和契约。要使用 ServiceHost 和 ChannelFactory,你需要使用 System.ServiceModel 命称空间。
using System; using System.ServiceModel; using QuickReturns.StockTrading.ExchangeService; using QuickReturns.StockTrading.ExchangeService.Contracts; namespace QuickReturns.StockTrading.ExchangeService.Hosts { class Program { static void Main(string[] args) { Uri address = new Uri ("http://localhost:8080/QuickReturns/Exchange"); ServiceHost host = new ServiceHost(typeof(TradeService); host.Open(); Console.WriteLine("Service started: Press Return to exit"); Console.ReadLine(); } } }
ChannelFactory 是一个使客户端能够获得已设置在服务器端的服务的类。客户端只要知道服务公开的契约,就可以获取一个接口作为其类属参数。然后,当你使用一个通道时,你将能够获得对服务的访问和调用它的方法。这是当你用 Visual Studio 创建并添加一个 WebService 作为一个 WebReference 到你的项目中时真实的后台处理。你可以在下面的示例代码中看到,我们通过 ServerHost 调用我们先前创建并启动的服务中的一个方法:
internal class ExchangeServiceSimpleClient { private static void Main(string[] args) { EndpointAddress address = new EndpointAddress ("http://localhost:8080/QuickReturns/Exchange"); BasicHttpBinding binding = new BasicHttpBinding(); IChannelFactory<ITradeService> channelFactory = new ChannelFactory<ITradeService>(binding); ITradeService proxy = channelFactory.CreateChannel(address); Quote msftQuote = new Quote(); msftQuote.Ticker = "MSFT"; msftQuote.Bid = 30.25M; msftQuote.Ask = 32.00M; msftQuote.Publisher = "PracticalWCF"; Quote ibmQuote = new Quote(); ibmQuote.Ticker = "IBM"; ibmQuote.Bid = 80.50M; ibmQuote.Ask = 81.00M; ibmQuote.Publisher = "PracticalWCF"; proxy.PublishQuote(msftQuote); proxy.PublishQuote(ibmQuote); } }
客户端应用配置文件:
<configuration> <system.serviceModel> <client> <endpoint address="http://localhost:8080/QuickReturns/Exchange" binding="basicHttpBinding" contract="QuickReturns.StockTrading.ExchangeServiceClient. ITradeService"> </endpoint> </client> </system.serviceModel> </configuration>
这两个类很重要,因为它们是一个计算机网络中所有节点之间的连接的基础。在我们建立一个文件共享系统的代码中我们将完全依仗这些类,所以花越多成本来理解这两个类如何工作的,我们就能越多理解如何能在网络节点之间共享文件。你可以阅读我提到的书的第3章来深度理解他们。
你需要知道关于WCF的丰富细节。所以我强烈建议详细学习WCF,否则阅读代码只会徒劳无功。我试着举出一些WCF的重要基础,但你需要至少开发一个从客户机向服务器(运行着一个服务)发出远程调用的项目。在深入研究WCF之前,我有一些严重的问题。最终,我得出的结论是,我需要从头学习WCF,和忘了以前我曾通过 Visual Studio 用它来创建过一些 Web 服务,因为那些印象没有好处。至于其他的,让我们先谈谈点对点对等结构和概念。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务