首页 > 代码库 > 【转】《WCF服务编程 第一章 WCF基础》第一回
【转】《WCF服务编程 第一章 WCF基础》第一回
原文地址:http://www.cnblogs.com/PirateCaptain/articles/1960954.html
什么是WCF?WCF全名Windows Communication Foundation,中文叫Windows通信基础,MS的名字起的多么的朴实合适,是Windows平台下开发和部署服务的软件开发包。WCF为服务提供了运行时环境(多次看到运行时,这玩意究竟干了什么这么重要呢?),使得开发者能够以CLR类型的方式使用服务(CLR类型是什么呢?能干吗?这个问题得去.NET框架程序设计里去找答案)。WCF的大部分功能都在System.ServiceModel这个.NET命名空间里,至少需要.NET3.0的支持。操作系统至少XPsp2以上。
我粗浅的理解是这样的:
什么是服务?WINDOWS操作系统里有很多服务(Services),基本是本地计算机使用的,服务其实吧就跟生活中一样,是一个抽象的概念,是面向组件的上一层概念,好多国内公司做软件服务外包,说的再通俗点,就是我给你钱,你给我做我指定的事情,怎么做我不管,我只从你这边拿到我想要的东西。WCF里的服务可以是跨网跨域的,不跨就没啥意义了,否则怎么叫分布式呢?再往前追溯就是Dcom,再上去就是Cobra,往后就是Indigo,其实是早期MS对WCF的称呼代号。
服务是公开的一组功能的集合。客户端与服务通过消息的发送和接受进行交互,WCF中的所有消息均为SOAP消息(xml之类的东东,上Google好好了解下)。WCF的消息与传输协议无关,而WEB服务(WS)则与传输协议有关(限于HTTP)。WCF服务通常通过公开元数据的方式描述可用的功能以及服务可能采用的通信方式,元数据的发布可以预先定义,它与具体的技术无关(如WSDL),非WCF客户端也可以将元数据作为本地类型导入到本地环境中,然后以本地CLR类与接口的方式进行调用,怎么理解这句话,其实吧,说白了就是导入服务上的类型到本地类型,然后调用本地类型,因为你的VS2008不可能直接使用网络上的元数据,你的编程测试都是本地的(代理类相关的东西)。
WCF不允许客户端直接与服务交互,那么客户端只能总是使用Proxy代理将调用转发给服务(这就像公司里的技术和客户之间会有销售做协调工作一样,具有很多的好处),WCF的编程模型要求即使是本地调用,仍然使用远程编程模型的实例化方式,并使用代理。
地址 WCF的每一个服务都具有一个唯一的地址。地址包含服务位置和传输协议,或者是用于服务通信的传输样式。以下是一些实例,其实和网址类似:
http://localhost:8080 http://localost:81/Service net.tcp://localhost:8082 net.msmq://localhost 等等.WCF1.0支持的传输样式有 HTTP,TCP,Peer network,IPC,MSMQ等。
TCP地址:采用net.tcp协议进行传输,通常包括端口号,默认808。2个TCP可以共享一个端口号(但是后面的服务要求不是同一个)。
HTTP地址:采用http协议,也可以用https进行安全传输,默认端口80,也可以共享端口号。
IPC地址:采用net.pipe进行传输,这就是说它将使用Windows的命名管道机制。在WCF中,使用命名管道的服务只能接受来自同一台机器的调用,因此使用时要指明本地机器名或者localhost为管道提供一个唯一的标识符,每台机器只能打开一个命名管道,因此2个命名管道地址也不能共享一个管道名。
MSMQ:协议时net.msmq,即微软消息队列,必须为msmq指定队列名。如果是私有队列,还需要指定队列类型,共有的队列类型可以省略
Peer network:对等网地址,协议net.p2p。(GOOGLE上好好了解,掌握)
下面开始介绍WCF的另外一些概念
契约:WCF的所有服务都会公开为契约,契约和平台无关,有4种,服务契约ServiceContract,数据契约DataContract,错误契约FaultContract,和消息契约MessageContract。
服务契约示例,
[ServiceContract (NameSpace="tempUrl")] //默认http://tempurl.org
[ServiceContract (Name="tempName")] //定义别名
托管方式有 IIS托管(要求.NET4.0),自托管(最简单的就是自己做个Winform).重点看看托管的高级特性。
宿主类型ServiceHost实现的接口ICommunicationObject定义了一些高级特性,好好看看。
using System;namespace System.ServiceModel{ // 摘要: // 为系统中所有面向通信的对象(包括通道、通道管理器、工厂、侦听器以及调度程序和服务主机)定义基本状态机的协定。 public interface ICommunicationObject { // 摘要: // 获取面向通信的对象的当前状态。 // // 返回结果: // 对象的 System.ServiceModel.CommunicationState 的值。 CommunicationState State { get; } // 摘要: // 当通信对象完成从正在关闭状态转换到已关闭状态时发生。 event EventHandler Closed; // // 摘要: // 当通信对象首次进入正在关闭状态时发生。 event EventHandler Closing; // // 摘要: // 当通信对象首次进入出错状态时发生。 event EventHandler Faulted; // // 摘要: // 当通信对象完成从正在打开状态转换到已打开状态时发生。 event EventHandler Opened; // // 摘要: // 当通信对象首次进入正在打开状态时发生。 event EventHandler Opening; // 摘要: // 使通信对象立即从其当前状态转换到关闭状态。 void Abort(); // // 摘要: // 开始一个异步操作以关闭通信对象。 // // 参数: // callback: // 接收异步关闭操作完成通知的 System.AsyncCallback 委托。 // // state: // 一个由应用程序指定的对象,它包含与异步关闭操作相关联的状态信息。 // // 返回结果: // 引用异步关闭操作的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationObjectFaultedException: // 对处于 System.ServiceModel.CommunicationState.Faulted 状态的对象调用了 System.ServiceModel.ICommunicationObject.BeginClose()。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject 能够正常关闭之前所经过的默认超时。 IAsyncResult BeginClose(AsyncCallback callback, object state); // // 摘要: // 开始一个异步操作以在指定超时内关闭通信对象。 // // 参数: // timeout: // System.Timespan,指定在超时前必须完成发送操作的时间。 // // callback: // 接收异步关闭操作完成通知的 System.AsyncCallback 委托。 // // state: // 一个由应用程序指定的对象,它包含与异步关闭操作相关联的状态信息。 // // 返回结果: // 引用异步关闭操作的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationObjectFaultedException: // 对处于 System.ServiceModel.CommunicationState.Faulted 状态的对象调用了 System.ServiceModel.ICommunicationObject.BeginClose()。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject 能够正常关闭之前所经过的指定超时。 IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state); // // 摘要: // 开始一个异步操作以打开通信对象。 // // 参数: // callback: // 接收异步打开操作完成通知的 System.AsyncCallback 委托。 // // state: // 一个由应用程序指定的对象,它包含与异步打开操作相关联的状态信息。 // // 返回结果: // 引用异步打开操作的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationException: // System.ServiceModel.ICommunicationObject 无法打开并且已进入 System.ServiceModel.CommunicationState.Faulted // 状态。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject(已经进入 System.ServiceModel.CommunicationState.Faulted // 状态)能够进入 System.ServiceModel.CommunicationState.Opened 状态之前所经过的默认打开超时。 IAsyncResult BeginOpen(AsyncCallback callback, object state); // // 摘要: // 开始一个异步操作以在指定时间间隔内打开通信对象。 // // 参数: // timeout: // System.Timespan,指定在超时前必须完成发送操作的时间。 // // callback: // 接收异步打开操作完成通知的 System.AsyncCallback 委托。 // // state: // 一个由应用程序指定的对象,它包含与异步打开操作相关联的状态信息。 // // 返回结果: // 引用异步打开操作的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationException: // System.ServiceModel.ICommunicationObject 无法打开并且已进入 System.ServiceModel.CommunicationState.Faulted // 状态。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject(已经进入 System.ServiceModel.CommunicationState.Faulted // 状态)能够进入 System.ServiceModel.CommunicationState.Opened 状态之前所经过的指定超时。 IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state); // // 摘要: // 使通信对象从其当前状态转换到关闭状态。 // // 异常: // System.ServiceModel.CommunicationObjectFaultedException: // 对处于 System.ServiceModel.CommunicationState.Faulted 状态的对象调用了 System.ServiceModel.ICommunicationObject.Close()。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject 能够正常关闭之前所经过的默认关闭超时。 void Close(); // // 摘要: // 使通信对象从其当前状态转换到关闭状态。 // // 参数: // timeout: // System.Timespan,指定在超时前必须完成发送操作的时间。 // // 异常: // System.ServiceModel.CommunicationObjectFaultedException: // 对处于 System.ServiceModel.CommunicationState.Faulted 状态的对象调用了 System.ServiceModel.ICommunicationObject.Close()。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject 能够正常关闭之前所经过的超时。 void Close(TimeSpan timeout); // // 摘要: // 完成一个异步操作以关闭通信对象。 // // 参数: // result: // 通过调用 System.ServiceModel.ICommunicationObject.BeginClose() 方法返回的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationObjectFaultedException: // 对处于 System.ServiceModel.CommunicationState.Faulted 状态的对象调用了 System.ServiceModel.ICommunicationObject.BeginClose()。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject 能够正常关闭之前所经过的超时。 void EndClose(IAsyncResult result); // // 摘要: // 完成一个异步操作以打开通信对象。 // // 参数: // result: // 通过调用 System.ServiceModel.ICommunicationObject.BeginOpen() 方法返回的 System.IAsyncResult。 // // 异常: // System.ServiceModel.CommunicationException: // System.ServiceModel.ICommunicationObject 无法打开并且已进入 System.ServiceModel.CommunicationState.Faulted // 状态。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject(已经进入 System.ServiceModel.CommunicationState.Faulted // 状态)能够进入 System.ServiceModel.CommunicationState.Opened 状态之前所经过的超时。 void EndOpen(IAsyncResult result); // // 摘要: // 使通信对象从已创建状态转换到已打开状态。 // // 异常: // System.ServiceModel.CommunicationException: // System.ServiceModel.ICommunicationObject 无法打开并且已进入 System.ServiceModel.CommunicationState.Faulted // 状态。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject(已经进入 System.ServiceModel.CommunicationState.Faulted // 状态)能够进入 System.ServiceModel.CommunicationState.Opened 状态之前所经过的默认打开超时。 void Open(); // // 摘要: // 使通信对象在指定时间间隔内从已创建状态转换到已打开状态。 // // 参数: // timeout: // System.Timespan,指定在超时前必须完成发送操作的时间。 // // 异常: // System.ServiceModel.CommunicationException: // System.ServiceModel.ICommunicationObject 无法打开并且已进入 System.ServiceModel.CommunicationState.Faulted // 状态。 // // System.TimeoutException: // 在 System.ServiceModel.ICommunicationObject(已经进入 System.ServiceModel.CommunicationState.Faulted // 状态)能够进入 System.ServiceModel.CommunicationState.Opened 状态之前所经过的指定超时。 void Open(TimeSpan timeout); }}
WAS托管:Windows激活服务(WAS)是一个系统服务,只适用于WINDOWS vista,是IIS7的一部分。
绑定 Binding
参考代码
<bindings>
<wsHttpBinding>
<binding name="WoDebinding" >
<security mode="None"></security>
</binding>
</wsHttpBinding>
</bindings>
一个绑定封装了诸如传输协议,消息编码,通信模式,可靠性,安全性,事务传播以及互操作性等相关选项的集合,使得他们保持一致。
绑定中的格式与编码
终结点
说白了就是提供服务的每一个对外接口。
<endpoint
name="endpoint1"
address=""
binding="wsHttpBinding"
contract="StreamTranlate.IService1"
bindingConfiguration="WoDebinding" /> <!--注意啊,binding值不能乱写,只有固定的几个值,具体看上图-->
对于编程来说有意义的事情来了,编程方式配置终结点.
【转】《WCF服务编程 第一章 WCF基础》第一回