WCF的中的Endpoint结构,一个Endpoint就类似于xml web service中的一个asmx文件,它包括三个组成部分1)Address 2) Binding 3) Contract,此三者被称为组成Endpoint的"ABC".
A解决了Endpoint在哪的问题,也就是"Where is the endpoint?"
B 解决的是如何与Endpoint通讯的问题,也就是"How to communicate with endpoint?"
C解决了Endpoint提供什么功能的问题,也就是"What functionalities do the endpoint provide?"
选择正确的Binding
Binding是可以自定义实现的,可WCF框架已经为我们实现了足够多的Binding,供我们来选择,如下表所示:
Binding名称 | Configuration Element | 描述 |
BasicHttpBinding | basicHttpBinding | 一个指定用符合基本网络服务规范通讯的binding,它用http进行传输,数据格式为text/xml |
WSHttpBinding | wsHttpBinding | 一个安全的通用的binding,但它不能在deplex中使用 |
WSDualHttpBinding | wsDualHttpBinding | 一个安全的通用的binding,但能在deplex中使用 |
WSFederationHttpBinding | wsFederationHttpBinding | 一个安全的通用的支持WSF的binding,能对用户进行验证和授权 |
NetTcpBinding | netTcpBinding | 在wcf应用程序中最适合跨机器进行安全通讯的binding |
NetNamedPipeBinding | netNamedPipeBinding | 在wcf应用程序中最适合本机进行安全通讯的binding |
NetMsmqBinding | netMsmqBinding | 在wcf应用程序中最适合跨机器进行安全通讯的binding,并且支持排队 |
NetPeerTcpBinding | netPeerTcpBinding | 一个支持安全的,多机交互的binding |
MsmqIntegrationBinding | msmqIntegrationBinding | 一个用于wcf与现有msmq程序进行安全通讯的binding |
下面的表格分别删除了上表中的Binding在互操作性(Interoperability), 安全性(Security), 是否支持会话(Session), 是否支持事务(Transactions)和是否为全双工(Duplex)上不同。
Bingding | Interoperability | Security | Session | Transactions | Duplex |
BasicHttpBinding | Basic Profile 1.1 | (None), Transport, Message | None, (None) | None | n/a |
WSHttpBinding | WS | Transport, (Message), Mixed | (None), Transport, Reliable Session | (None), Yes | n/a |
WSDualHttpBinding | WS | (Message) | (Reliable Session) | (None), Yes | Yes |
WSFederationHttpBinding | WS-Federation | (Message) | (None), Reliable Session | (None), Yes | No |
NetTcpBinding | .NET | (Transport), Message | Reliable Session, (Transport) | (None), Yes | Yes |
NetNamedPipeBinding | .NET | (Transport) | None, (Transport) | (None), Yes | Yes |
NetMsmqBinding | .NET | Message, (Transport), Both | (None) | (None), Yes | No |
NetPeerTcpBinding | Peer | (Transport) | (None) | (None) | Yes |
MsmqIntegrationBinding | MSMQ | (Transport) | (None) | (None), Yes | n/a |
例外,《Programming WCF Services》有一幅图也能说明各自的特征:
下面的图给出了我们选择Binding的方式
第一个简单的例子:
接口:
using System;
using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Threading;namespace WcfService1
{ // 注意: 如果更改此处的接口名称 "IService1",也必须更新 Web.config 中对 "IService1" 的引用。 [ServiceContract] public interface IService1 {[OperationContract]
string GetData(int value);[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);[OperationContract]
myNumber Getnum(myNumber mynum);
[OperationContract]
void Test(); } // 使用下面示例中说明的数据约定将复合类型添加到服务操作。 [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello ";[DataMember]
public bool BoolValue { get { return boolValue; } set { boolValue = value; } }[DataMember]
public string StringValue { get { return stringValue; } set { stringValue = value; } } } [DataContract] public struct myNumber { [DataMember] public double Num1;[DataMember]
public double Num2;public myNumber(double num1, double num2)
{ this.Num1 = num1; this.Num2 = num2; } } }
类:
using System;
using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Threading;namespace WcfService1
{ // 注意: 如果更改此处的类名“Service1”,也必须更新 Web.config 和关联的 .svc 文件中对“Service1”的引用。 public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); }public CompositeType GetDataUsingDataContract(CompositeType composite)
{ if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; }public myNumber Getnum(myNumber mynum)
{ if (mynum.Num1 > mynum.Num2) mynum.Num2 += mynum.Num2;if (mynum.Num1 < mynum.Num2)
mynum.Num1 += mynum.Num1;return mynum;
}
public void Test()
{ Thread.Sleep(1000); Console.WriteLine("Test Execute:{0}", DateTime.Now); } } }
调用:
using System;
using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using ConsoleApplication2.ServiceReference1; using System.ServiceModel.Channels;namespace ConsoleApplication2
{ class Program { static void Main(string[] args) { //方法三 //AppDomain.CreateDomain("Server").DoCallBack(delegate //{ // ServiceHost host = new ServiceHost(typeof(ConsoleApplication2.ServiceReference1.Service1Client)); // host.AddServiceEndpoint(typeof(Service1Client), new BasicHttpBinding(), // ""); // host.Open(); //});//ChannelFactory<IService1> factory = new ChannelFactory<IService1>(
// new WSHttpBinding(), ""); //IService1 o = factory.CreateChannel();//Console.WriteLine("Start:{0}", DateTime.Now);
//o.Test(); //Console.WriteLine("End:{0}", DateTime.Now); //方法二 Service1Client o = new Service1Client();Console.WriteLine("Start:{0}", DateTime.Now);
//o.Test(); Console.WriteLine("End:{0}", DateTime.Now); Console.WriteLine("{0}", o.GetData(1)); Console.ReadLine(); o.Close(); //方法一 //EndpointAddress address = new EndpointAddress(""); //Binding binding = new WSHttpBinding(); //Service1Client o = new ConsoleApplication2.ServiceReference1.Service1Client(binding, address); //Console.WriteLine("{0}", o.GetData(1)); //Console.Read();
}
} }