运行WCF服务
这里通过自宿主方式self-host来运行wcf服务。
公开终结点Endpoint,终结点由ServiceEndpoint 类来实现。它有很多的成员。其中要用到的是所说的ABC。
Address,Binding,Contract,地址,绑定,契约。
(一)Address
其中的Address,由EndpointAddress 来实现,它有很多成员:
·Uri 用于获取终结点的地址
·Identity 获取用于验证终结点的标识
·Headers 用来创建终结点地址标头集合
除了这几个还有其它一些属性:
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/fxref_system.servicemodel
/html/8947f21b-7f57-fb56-512e-25554808d870.htm
地址是用来公开终结点地址的,这个地址的配置可以由编程式实现,或由xml配置文件配置实现。地址可以分为相对地址和绝对地址。下边说明一下两种实现方式:
(1)编程方式实现
Uri _baseAddress = new Uri("http://localhost:8731/FirstService");
ServiceHost host = new ServiceHost(typeof(CaculateService), _baseAddress);
EndpointAddress address = new EndpointAddress(_baseAddress);
host.Description.Endpoints[0].Address = address;
这里用一下Headers属性:
ServiceHost host = new ServiceHost(typeof(CaculateService));
AddressHeader header1 = AddressHeader.CreateAddressHeader
("header_xxx", "namespace_xxx", "value_xxx");
AddressHeader header2 = AddressHeader.CreateAddressHeader
("header_yyy", "namespace_yyy", "value_yyy");
AddressHeader[] headers=new AddressHeader[]{header1,header2};
EndpointAddress address = new EndpointAddress(_baseAddress,headers);
host.Description.Endpoints[0].Address = address;
下边我截取soap头部分内容,可以看到:
<header_xxx a:IsReferenceParameter="true" xmlns="namespace_xxx">
value_xxx
</header_xxx>
<header_yyy a:IsReferenceParameter="true" xmlns="namespace_yyy">
value_yyy
</header_yyy>
我们在soap头中添加了一些头信息。然后,在客户端:
foreach (AddressHeader header in client.Endpoint.Address.Headers)
{
Console.WriteLine(
header.Name + " " +
header.Namespace + " " +
header.GetValue<string>());
}
输出:
header_xxx namespace_xxx value_xxx
header_yyy namespace_yyy value_yyy
(2)Xml配置文件
现在在app.config文件中进行配置,配置基地址,同时配置元数据发布,及soap头两条信息:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="FirstService.CaculateServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="FirstService.CaculateServiceBehavior"
name="FirstService.CaculateService">
<endpoint
address=""
binding="wsHttpBinding"
contract="FirstService.ICaculateService">
<headers>
<header_xxx>self_xxx</header_xxx>
<header_yyy>self_yyy</header_yyy>
</headers>
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress=
"http://localhost:8731/FirstService/CaculateService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
在这里的配置与编程方式是一样的。如果不熟悉这种配置方式,可以通过WCF服务配置编辑器来进行。
位置:工具-》WCF服务配置编辑器
在客户端得到的结果为:
header_xxx self_xxx
header_yyy self_yyy
因为没有为两个头指定名字空间,所以为空。
地址指定了终结点的位置,让客户端可以找到终结点,而终结点公开了服务。
(二)Binding
绑定,提供了通信的细节:
·传输,传输协议用Http,还是Tcp,或是IPC等等
·消息编码格式,这里的编码格式是指:二进制,文本,MTOM
·安全
系统提供了一些绑定。这里列举几个:
绑定 |
配置元素 |
说明 |
BasicHttpBinding |
<basicHttpBinding> |
一个绑定,适用于与符合WS-BasicProfile的Web服务(例如,基于ASP.NETWeb服务(ASMX)的服务)进行的通信。此绑定将HTTP用作传输协议,并将文本/XML用作默认消息编码。 |
WSHttpBinding |
<wsHttpBinding> |
一个安全的、可互操作的绑定,适合于非双工服务协定。 |
WSDualHttpBinding |
<wsDualHttpBinding> |
一个安全且可互操作的绑定,适用于双工服务协定或通过SOAP媒介进行的通信。 |
NetTcpBinding |
<netTcpBinding> |
一个安全且经过优化的绑定,适用于WCF应用程序之间跨计算机的通信。 |
NetNamedPipeBinding |
<netNamedPipeBinding> |
一个安全、可靠且经过优化的绑定,适用于WCF应用程序之间计算机上的通信。 |
NetMsmqBinding |
<netMsmqBinding> |
一个排队绑定,适用于WCF应用程序之间的跨计算机的通信。 |
NetPeerTcpBinding |
<netPeerTcpBinding> |
一个启用安全的多计算机通信的绑定。 |
MsmqIntegrationBinding |
<msmqIntegrationBinding> |
一个适合于WCF应用程序和现有消息队列应用程序之间的跨计算机通信的绑定。 |
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/
wcf_con/html/2c243746-45ce-4588-995e-c17126a579a6.htm
这里说一下:BindingElement类型:用于为各种类型的通道生成通道工厂和通道侦听器以处理传出和传入消息的绑定元素。这是一个抽象基类,而绑定是由一组继承自抽象基类BindingElement的有序元素组成。
这里列举一下:
OneWayBindingElement
TransportBindingElement
CompositeDuplexBindingElement;
StreamUpgradeBindingElement
PrivacyNoticeBindingElement
UseManagedPresentationBindingElement
ReliableSessionBindingElement
SecurityBindingElement
MessageEncodingBindingElement
PeerResolverBindingElement
TransactionFlowBindingElement
ContextBindingElement
这里再说明一些:
(1)编码MessageEncodingBindingElement
BinaryMessageEncodingBindingElement |
用于指定编码消息时所采用的.NET二进制XML格式的绑定元素 |
MtomMessageEncodingBindingElement |
指定消息传输优化机制(MTOM)消息所使用的编码和版本管理的绑定元素 |
TextMessageEncodingBindingElement |
绑定元素,指定用于基于文本的SOAP消息的字符编码与消息版本管理 |
WebMessageEncodingBindingElement |
在WindowsCommunicationFoundation(WCF)绑定中使用纯文本XML与JavaScript对象表示法(JSON)消息编码以及“原始”二进制内容时,能够对其进行读写 |
(2)传输TransportBindingElement
(3)事务TransactionFlowBindingElement
(4)安全SecurityBindingElement
(5)可靠性 ReliableSessionBindingElement
下边提供一个列表。
绑定 |
传输 |
编码 |
互操作 |
BasicHttpBinding |
Http/Https |
Text,MTOM |
Yes |
NetTcpBinding |
Tcp |
binary |
No |
NetPeerTcpBinding |
P2p |
Binary |
No |
NetNamedPipeBinding |
IPC |
Binary |
No |
WSHttpBinding |
Http/Https |
Text,MTOM |
Yes |
WSFederationHttpBinding |
Http/Https |
Text,MTOM |
Yes |
WSDualHttpBinding |
Http |
Text,MTOM |
Yes |
NetMsmqBinding |
MSMQ |
Binary |
No |
MsmqIntegrationBinding |
MSMQ |
Binary |
Yes |
在例子中,用到的绑定是:wsHttpBinding
它支持Http/Https传输,且编码支持文本和MTOM
这里演示一下两种编码格式对soap对象是怎么样一种表现。
它默认的编码是文本,就是常见的那种,就一个soap,一个soap封套。而如果是MTOM呢,就会以一种soap封套加soap附件格式传输
在配置文件中可以这样设置:
第一部分,这是终结点的ABC,其中绑定要求绑定细节,即粗体部分
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="BindingSelf" contract="FirstService.ICaculateService">
第二部分,用于配置绑定细节
<bindings>
<wsHttpBinding>
<binding name="BindingSelf" messageEncoding="Mtom">
</binding>
</wsHttpBinding>
</bindings>
这里有个messageEncoding,因为用的是wsHttpBinding,而它支持两种编码,所以这里只有两个枚举值:mtom和text
我这里提供一段MTOM消息编码流:
--uuid:55e877da-b9b1-4091-9832-f1dd79ece1d4+id=2
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml"
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
省略……
</s:Envelope>
--uuid:55e877da-b9b1-4091-9832-f1dd79ece1d4+id=2--
这与Text编码不同。Text编码只一个封套。