WCF开发之邦定(Binding)

这部分的前期理论知识比较多,所以我们先从Demo入手,然后再来看理论东西。我们这部分只关注WCF关于邦定的技术,对于其他涉及到的技术不做探讨,由于Binding这部分东西要和其他很多相关技术共同使用,而且涉及到很多WCF中的高级操作,在其他的文章中会逐步提到,这里我们只关心邦定就可以了。

Demo1:二进制邦定通过http

IHelloIndigoService 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary2
{
    [ServiceContract(Namespace
="http://cnblogs.com/charlesliu")]
    
public interface IHelloIndigoService
    {
        [OperationContract]
        
string HelloIndigo(string inputString);
    }
}

 

HelloIndigoService 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary2
{
    
public class HelloIndigoService : IHelloIndigoService
    {
        
public string HelloIndigo(string inputString)
        {
            
return inputString;
        }
    }
}

 

App.config 代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.web>
    
<compilation debug="true" />
  
</system.web>
  
<!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. 
-->
  
<system.serviceModel>
    
<client />
    
<services>
      
<service behaviorConfiguration="WcfServiceLibrary2.Service1Behavior"
        name
="WcfServiceLibrary2.HelloIndigoService">
        
<endpoint address="" binding="customBinding" contract="WcfServiceLibrary2.IHelloIndigoService" bindingConfiguration="binaryOverHttp">
          
<identity>
            
<dns value="localhost" />
          
</identity>
        
</endpoint>
        
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        
<host>
          
<baseAddresses>
            
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
          
</baseAddresses>
        
</host>
      
</service>
    
</services>
    <bindings>
      
<customBinding>
        
<binding name="binaryOverHttp">
          
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004"/>
          
<reliableSession ordered="true"/>
          
<binaryMessageEncoding />
          
<httpTransport />
        
</binding>
      
</customBinding>
    
</bindings>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="WcfServiceLibrary2.Service1Behavior">
          
<!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment 
-->
          
<serviceMetadata httpGetEnabled="True"/>
          
<!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information 
-->
          
<serviceDebug includeExceptionDetailInFaults="False" />
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>

上面这个Demo和以前的Demo的代码没有什么区别,唯一的不同是在config文件里,加亮的位置体现出了自定义邦定的方法。

 

Demo2:(Stream流的binding)

IMediaManagerService代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary3
{
    [ServiceContract]
    
public interface IMediaManagerService
    {
        [OperationContract]
        
string[] GetMediaList();
    }
}

 

IMediaStreaming代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;

namespace WcfServiceLibrary3
{
    [ServiceContract]
    
public interface IMediaStreaming
    {
        [OperationContract]
        Stream GetMediaStream(
string media);
    }
}

 

MediaMangerService 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;

namespace WcfServiceLibrary3
{
    
public class MediaMangerService : IMediaStreaming, IMediaManagerService
    {
        
public string[] GetMediaList()
        {
            
string[] mediaList = new string[1];
            mediaList[
0= "WebCast20071101_Video.wmv";

            
return mediaList;
        }

        
public Stream GetMediaStream(string media)
        {
            
string mediaFile = String.Format("{0}\\{1}", System.Configuration.ConfigurationSettings.AppSettings["mediaPath"], media);

            FileInfo fi 
= new FileInfo(mediaFile);

            
if (!fi.Exists)
                
throw new FileNotFoundException("File does not exist: {0}. Check host configuration for 'mediaPath' setting.", media);

            TraceStream traceStream 
= null;
            FileStream fs 
= null;
            
try
            {
                fs 
= new FileStream(mediaFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                traceStream 
= new TraceStream(fs);
            }
            
catch
            {
                
if (fs != null)
                    fs.Close();
            }

            
return traceStream;
        }
    }
}

 

TraceStream代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace WcfServiceLibrary3
{
    
public class TraceStream : Stream
    {
        System.IO.Stream m_in 
= null;
        System.IO.Stream m_out 
= null;

        
public override bool CanRead
        {
            
get
            {
                Trace.WriteLine(
"TraceStream", String.Format("get_CanRead: {0}", m_in.CanRead));
                
return m_in.CanRead;
            }
        }

        
public override bool CanSeek
        {
            
get
            {
                Trace.WriteLine(
"TraceStream", String.Format("get_CanSeek: {0}", m_in.CanSeek));
                
return m_in.CanSeek;
            }
        }

        
public override bool CanWrite
        {
            
get
            {
                Trace.WriteLine(
"TraceStream", String.Format("get_CanWrite: {0}", m_in.CanWrite));
                
return m_in.CanWrite;
            }
        }

        
public override long Length
        {
            
get
            {
                Trace.WriteLine(
"TraceStream", String.Format("get_Length: {0}", m_in.Length));
                
return m_in.Length;
            }
        }

        
public override void SetLength(
            
long val
            )
        {
            Trace.WriteLine(
"TraceStream", String.Format("SetLength({0})", val));
            m_in.SetLength(val);
        }

        
public override long Position
        {
            
get
            {
                Trace.WriteLine(
"TraceStream", String.Format("get_Position: {0}", m_in.Position));
                
return m_in.Position;
            }
            
set
            {
                Trace.WriteLine(
"TraceStream", String.Format("set_Position: {0}", m_in.Position));
                m_in.Position 
= value;
            }
        }

        
public TraceStream(System.IO.Stream stream)
        {
            Trace.WriteLine(
"TraceStream", String.Format("TraceStream created."));
            m_in 
= stream;
        }

        
public override IAsyncResult BeginRead(
            
byte[] buffer,
            
int offset,
            
int count,
            AsyncCallback callback,
            
object state
            )
        {
            Trace.WriteLine(
"TraceStream", String.Format("BeginRead(): offset({0}), count({1})", offset, count));
            
return m_in.BeginRead(buffer, offset, count, callback, state);
        }

        
public override IAsyncResult BeginWrite(
            
byte[] buffer,
            
int offset,
            
int count,
            AsyncCallback callback,
            
object state
            )
        {
            Trace.WriteLine(
"TraceStream", String.Format("BeginWrite(): offset({0}), count({1})", offset, count));
            
return m_in.BeginWrite(buffer, offset, count, callback, state);
        }

        
public override void Close()
        {
            Trace.WriteLine(
"TraceStream", String.Format("Close()"));
            m_in.Close();
        }

        
public override int EndRead(
            IAsyncResult asyncResult
            )
        {
            Trace.WriteLine(
"TraceStream""EndRead()");
            
return m_in.EndRead(asyncResult);
        }

        
public override void EndWrite(
            IAsyncResult asyncResult
            )
        {
            Trace.WriteLine(
"TraceStream""EndWrite()");
            m_in.EndWrite(asyncResult);
        }


        
public override void Flush()
        {
            Trace.WriteLine(
"TraceStream""Flush()");
            m_in.Flush();
        }


        
public override long Seek(
            
long offset,
            SeekOrigin origin
            )
        {
            Trace.WriteLine(
"TraceStream", String.Format("Seek(): offset({0}), origin({1})", offset, origin));
            
return m_in.Seek(offset, origin);
        }


        
public override int Read(byte[] buffer,
                   
int offset, int count)
        {
            Trace.WriteLine(
"TraceStream", String.Format("Read(): offset({0}), count({1})", offset, count));
            
return m_in.Read(buffer, offset, count);
        }

        
public override void Write(
            
byte[] buffer,
            
int offset,
            
int count
            )
        {
            Trace.WriteLine(
"TraceStream", String.Format("Write(): offset({0}), count({1})", offset, count));
            m_in.Write(buffer, offset, count);

        }

    }
}

 

App.config 代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.web>
    
<compilation debug="true" />
  
</system.web>
  <appSettings>
    
<add key="mediaPath" value="D:\omps-liucha-01.Bak\WCF\5\WebCast20071101_Demo\Streaming_WithTrace" />
  
</appSettings>
  
<!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. 
-->
  
<system.serviceModel>
    
<services>
      
<service behaviorConfiguration="WcfServiceLibrary3.Service1Behavior"
        name
="WcfServiceLibrary3.MediaMangerService">
        
<endpoint address="MediaManager" binding="basicHttpBinding" contract="WcfServiceLibrary3.IMediaManagerService" />
        
<!--<endpoint address="MediaStream" contract="WcfServiceLibrary3.IMediaStreaming" binding="basicHttpBinding" bindingConfiguration="basicHttpStreaming"/>-->
        
<endpoint address="MediaStream" contract="WcfServiceLibrary3.IMediaStreaming" binding="netTcpBinding" bindingConfiguration="netTcpStreaming"/>
        
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        
<host>
          
<baseAddresses>
            
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary3/Service1/" />
            
<add baseAddress="net.tcp://localhost:9000"/>
          
</baseAddresses>
        
</host>
      
</service>
    
</services>
    
<bindings>
      
<netTcpBinding>
        
<binding name="netTcpStreaming" transferMode="StreamedRequest" maxReceivedMessageSize="40000000" maxBufferSize="4096" sendTimeout="00:00:15" >
        
</binding>
      
</netTcpBinding>
      
<basicHttpBinding>
        
<binding name="basicHttpStreaming" messageEncoding="Mtom" maxReceivedMessageSize="40000000" transferMode="Streamed">
        
</binding>
      
</basicHttpBinding>
    
</bindings>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="WcfServiceLibrary3.Service1Behavior">
          
<!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment 
-->
          
<serviceMetadata httpGetEnabled="True"/>
          
<!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information 
-->
          
<serviceDebug includeExceptionDetailInFaults="False" />
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>

上面这个Demo主要演示了流的邦定,大家可以重点关注一下Config文件里的highlight内容。

 

Demo3:WSDual 用于回调callback

MyService 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WcfServiceLibrary4
{
    [ServiceContract(Namespace 
= "http://cnblogs.cn/charlesliu", CallbackContract = typeof(IHelloIndidoServiceCallback))]
    
public interface IMyService
    {
        [OperationContract(IsOneWay 
= true)]
        
void HelloIndigo(string message);

        [OperationContract]
        
void HelloIndigo2(string message);
    }

    
public interface IHelloIndidoServiceCallback
    {
        [OperationContract(IsOneWay 
= true)]
        
void HelloIndigoCallback(string message);

        [OperationContract]
        
void HelloIndigoCallback2(string message);
    }

    [ServiceBehavior(ConcurrencyMode
=ConcurrencyMode.Reentrant)]
    
public class MyService : IMyService
    {
        
public void HelloIndigo(string message)
        {
            IHelloIndidoServiceCallback callback 
= OperationContext.Current.GetCallbackChannel<IHelloIndidoServiceCallback>();
            callback.HelloIndigoCallback(message);
        }

        
public void HelloIndigo2(string message)
        {
            IHelloIndidoServiceCallback callback 
= OperationContext.Current.GetCallbackChannel<IHelloIndidoServiceCallback>();
            callback.HelloIndigoCallback2(message);
        }
    }
}

 

config 代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.web>
    
<compilation debug="true" />
  
</system.web>
  
<!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. 
-->
  
<system.serviceModel>
    
<services>
      
<service name="WcfServiceLibrary4.MyService" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior">
        
<host>
          
<baseAddresses>
            
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/Service1/" />
          
</baseAddresses>
        
</host>
        
<!-- Service Endpoints -->
        
<!-- Unless fully qualified, address is relative to base address supplied above -->
        
<endpoint address ="" binding="wsDualHttpBinding" contract="WcfServiceLibrary4.IMyService">
          
<!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          
-->
          
<identity>
            
<dns value="localhost"/>
          
</identity>
        
</endpoint>
        
<!-- Metadata Endpoints -->
        
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      
</service>
    
</services>
    <bindings>
      
<wsDualHttpBinding>
        
<binding name="wsDualUsername" maxReceivedMessageSize="100000" transactionFlow="true">
          
<readerQuotas maxArrayLength="100000" maxStringContentLength="100000"/>
          
<security>
            
<message clientCredentialType="UserName"/>
          
</security>
        
</binding>
      
</wsDualHttpBinding>
    
</bindings>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="WcfServiceLibrary4.Service1Behavior">
          
<!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment 
-->
          
<serviceMetadata httpGetEnabled="True"/>
          
<!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information 
-->
          
<serviceDebug includeExceptionDetailInFaults="False" />
          
<serviceCredentials>
            
<serviceCertificate findValue="RPKey" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
          
</serviceCredentials>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>

 

client 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ServiceModel;
using ConsoleApplication1.MyServiceReference;

namespace ConsoleApplication1
{
    
class Program : IMyServiceCallback
    {
        
static void Main(string[] args)
        {
            Console.WriteLine(
"Client running on thread {0}", Thread.CurrentThread.GetHashCode());
            Console.WriteLine();

            Program p 
= new Program();
            InstanceContext context 
= new InstanceContext(p);
            
using (MyServiceReference.MyServiceClient proxy = new ConsoleApplication1.MyServiceReference.MyServiceClient(context))
            {
                WSDualHttpBinding b 
= proxy.Endpoint.Binding as WSDualHttpBinding;
                b.ClientBaseAddress 
= new Uri("http://localhost:8100");

                
//Enter valid windows credentials here
                Console.WriteLine();
                Console.Write(
"Enter username:");
                
string username = Console.ReadLine();
                Console.Write(
"Enter password:");
                Console.ForegroundColor 
= ConsoleColor.Black;
                
string password = Console.ReadLine();
                Console.ForegroundColor 
= ConsoleColor.White;

                proxy.ClientCredentials.UserName.UserName 
= username;
                proxy.ClientCredentials.UserName.Password 
= password;

                Console.WriteLine();
                Console.WriteLine(
"Calling HelloIndigo() - one-way");
                proxy.HelloIndigo(
"Hello from client.");
                Console.WriteLine(
"Returned from HelloIndigo()");


                Console.WriteLine(
"Calling HelloIndigo2() - not one-way");
                proxy.HelloIndigo2(
"Hello from client.");
                Console.WriteLine(
"Returned from HelloIndigo2()");

                Console.ReadLine();
            }
        }

        
public void HelloIndigoCallback(string message)
        {
            Console.WriteLine(
"HelloIndigoCallback on thread {0} - one-way", Thread.CurrentThread.GetHashCode());
        }

        
public void HelloIndigoCallback2(string message)
        {
            Console.WriteLine(
"HelloIndigoCallback2 on thread {0} - not one-way", Thread.CurrentThread.GetHashCode());

        }
    }
}

对于WSDual邦定,有几点值得注意。CallbackContract的类名称在客户端会变,比如本例中的IHelloIndidoServiceCallback就变成了IMyServiceCallback。要想成功运行本例还要添加X509的证书,可以从http://www.dasblonde.net/downloads/code/CertificatesSetup.zip下载。WSDual的作用就是实现回调,客户端发送一个调用服务的方法的请求,服务器通过回调客户的方法,实际上也就是服务端调用了客户端的方法。同时这个Demo也展示了如何配置证书认证的配置方法。

 

Demo4:自定义邦定custombinding有配置文件实现

其实Demo1就是用自定义邦定来实现的,对一邦定使用时非常灵活,所以主要是掌握它的方法。

Service 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary5
{
    [ServiceContract]
    
public interface IMyService
    {
        [OperationContract]
        
string Hello(string message);
    }

    
public class MyService : IMyService
    {
        
public string Hello(string message)
        {
            
return message + " Charles";
        }
    }
}

 

Config 代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.web>
    
<compilation debug="true" />
  
</system.web>
  
<!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. 
-->
  
<system.serviceModel>
    
<services>
      
<service name="WcfServiceLibrary5.MyService" behaviorConfiguration="WcfServiceLibrary5.Service1Behavior">
        
<host>
          
<baseAddresses>
            
<add baseAddress = "http://localhost:8001" />
          
</baseAddresses>
        
</host>
        
<!-- Service Endpoints -->
        
<!-- Unless fully qualified, address is relative to base address supplied above -->
        
<endpoint address ="" binding="customBinding" contract="WcfServiceLibrary5.IMyService" bindingConfiguration="customHttp">
          
<!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          
-->
          
<identity>
            
<dns value="localhost"/>
          
</identity>
        
</endpoint>
        
<!-- Metadata Endpoints -->
        
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
        
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      
</service>
    
</services>
    
    
<bindings>
      
<customBinding>
        
<binding name="customHttp">
          
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004"/>
          
<reliableSession ordered="true"/>
          
<textMessageEncoding messageVersion="Soap12WSAddressing10" writeEncoding="utf-8"/>
          
<httpTransport />
        
</binding>
      
</customBinding>
    
</bindings>

    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="WcfServiceLibrary5.Service1Behavior">
          
<!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment 
-->
          
<serviceMetadata httpGetEnabled="True"/>
          
<!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information 
-->
          
<serviceDebug includeExceptionDetailInFaults="False" />
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>

注意:<httpTransport />不是<httpsTransport />,搞了半天终于发现是这个问题。

 

Demo5:代码方式实现的邦定

Service 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Helloindigo
{
    [ServiceContract(Namespace
="http://cnbolgs.com/charles")]
    
public interface IHelloIndigoService
    {
        [OperationContract]
        
string HelloIndigo(string messsage);
    }

    
public class HelloIndigoService : IHelloIndigoService
    {
        
public string HelloIndigo(string messsage)
        {
            
return messsage + " Charles";
        }
    }
}

 

Host 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Helloindigo;

namespace Host
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
using (ServiceHost host = new ServiceHost(typeof(HelloIndigoService), new Uri("http://localhost:8000")))
            {
                BindingElementCollection elements 
= new BindingElementCollection();
                elements.Add(
new TransactionFlowBindingElement(TransactionProtocol.WSAtomicTransactionOctober2004));
                elements.Add(
new ReliableSessionBindingElement(true));
                elements.Add(
new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8));
                elements.Add(
new HttpTransportBindingElement());

                CustomBinding binding 
= new CustomBinding(elements);

                host.AddServiceEndpoint(
typeof(IHelloIndigoService), binding, "HelloIndigoService");
                host.Open();

                Console.WriteLine();
                Console.WriteLine(
"Press <ENTER> to terminate the host application");
                Console.Read();
            }
        }
    }
}

 

 

Client 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Client
{
    
class Program
    {
        
static void Main(string[] args)
        {
            BindingElementCollection elements 
= new BindingElementCollection();
            elements.Add(
new TransactionFlowBindingElement(TransactionProtocol.WSAtomicTransactionOctober2004));
            elements.Add(
new ReliableSessionBindingElement(true));
            elements.Add(
new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8));
            elements.Add(
new HttpTransportBindingElement());

            CustomBinding binding 
= new CustomBinding(elements);

            ChannelFactory
<IHelloIndigoService> factory = new ChannelFactory<IHelloIndigoService>(binding, "http://localhost:8000/HelloIndigoService");
            IHelloIndigoService proxy 
= null;

            
try
            {
                proxy 
= factory.CreateChannel();

                
string s = proxy.HelloIndigo("Hello");
                Console.WriteLine(s);
                Console.Read();

            }
            
catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            
finally
            {
                ICommunicationObject obj 
= proxy as ICommunicationObject;
                
if (obj != null)
                {
                    obj.Close();
                }
            }
        }
    }

    [ServiceContract(Namespace 
= "http://cnbolgs.com/charles")]
    
public interface IHelloIndigoService
    {
        [OperationContract]
        
string HelloIndigo(string messsage);
    }
}

这个Demo使用纯代码的方式实现邦定,但是相比之下用config的方式更简单更高效。

 

好,看了这么多的Demo大家对Binding应该有所了解了,下面把WCF Binding这部分总结讲解一下:

 

什么是绑定(Binding)?
• 绑定表示通讯信道(communication channel)的配置
• 绑定定义了客户端与服务端之间通讯的协议
– 传输协议
– 消息编码
– 安全性,可靠性消息与事务

1 Message Transmission Optimization Mechanism (MTOM)
2 Transmission Control Protocol (TCP)
3 Microsoft Message Queuing (MSMQ)

 

传输协议
• HTTP
• TCP
• 命名管道(Named Pipes)
• MSMQ
• 提供自定义协议的支持:UDP 或者 SMTP, 等等

消息编码
• Text
• MTOM
• Binary
• 能够提供自定义消息编码格式

其它的绑定协议
• 安全
–相互认证证书 (用于不同公司之间或是不同部门之间,提供一种相互的认证手段)
• X.509
–消息保护
• 可靠的消息
• 事务支持
• 能够使用自定义绑定协议进行扩展

 

信道(Channels)
• 信道栈在通讯的每个端点之间发送或者接收消息
– 客户端代理是从客户端绑定配置构建出来的信道
– ServiceHost根据服务绑定的配置,为每个端点暴露出信道的监听器
• 信道栈由绑定的元素组成

绑定元素
• 绑定(Binding)由绑定元素组成
• 每个绑定元素对于信道(channel)栈的某些部分进行配置
• 与端点(endpoint)相关
• 能够通过声明或在代码中对每个端点进行配置

 

选择绑定
• 标准绑定:
–预定义的绑定元素
– 为在HTTP, TCP, 命名管道或者MSMQ通讯上提供缺省设置
– 能够修改配置
• 自定义绑定:
– 完全自定义的绑定元素的集合
– 当标准绑定无法满足需求时使用

 

标准绑定
• BasicHttpBinding
• WSHttpBinding
• WSDualHttpBinding
• WSFederationHttpBinding
• NetNamedPipeBinding
• NetTcpBinding
• NetPeerTcpBinding
• NetMsmqBinding
• MsmqIntegrationBinding

 Web Service绑定
• BasicHttpBinding与SOAP 1.1兼容
• WSHttpBinding与带有WS*的SOAP 1.2兼容
• WSDualHttpBinding适用于在支持WS*的HTTP协议上的回调(无法进行互操作)
• WSFederationHttpBinding适用于联合安全与单点登陆(SSO)的场景

跨进程/主机绑定
• NetNamedPipeBinding用于进程内或者同主机的调用
• NetTcpBinding用于同主机或者跨主机的调用
• NetPeerTcpBinding用于同主机或者跨主机点对点消息

消息绑定
• NetMsmqBinding用于在MSMQ上可靠的,事务的并且持久的消息
• MsmqIntegrationBinding用于早期技术的MSMQ互操作

自定义标准绑定

 

代码
<system.serviceModel>
<services>
<service name="HelloIndigo.HelloIndigoService" >
<endpoint binding="netTcpBinding" bindingConfiguration="netTcp" contract="HelloIndigo.IHelloIndigoService" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcp" maxReceivedMessageSize="5000000">
<security mode="Message">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>

 

创建自定义绑定

代码
<system.serviceModel>
<services>
<service name="HelloIndigo.HelloIndigoService" >
<endpoint binding="customBinding"
bindingConfiguration
="custom"
contract
="HelloIndigo.IHelloIndigoService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="custom">
<security authenticationMode="SspiNegotiated">
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding />
<httpTransport maxReceivedMessageSize="5000000" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>

 

(完)

posted @ 2010-03-19 13:49  烟鬼  阅读(1454)  评论(0编辑  收藏  举报