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(),
// "http://localhost:8080/Service1.svc");
// host.Open();
//});
//ChannelFactory<IService1> factory = new ChannelFactory<IService1>(
// new WSHttpBinding(), "http://localhost:8080/Service1.svc");
//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("http://localhost:8080/Service1.svc");
//Binding binding = new WSHttpBinding();
//Service1Client o = new ConsoleApplication2.ServiceReference1.Service1Client(binding, address);
//Console.WriteLine("{0}", o.GetData(1));
//Console.Read();
}
}
}