WCF开发之邦定(Binding)

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

Demo1:二进制邦定通过http

ExpandedBlockStart.gif 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);
    }
}

 

ExpandedBlockStart.gif 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;
        }
    }
}

 

ExpandedBlockStart.gif 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)

ExpandedBlockStart.gif 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();
    }
}

 

ExpandedBlockStart.gif 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);
    }
}

 

ExpandedBlockStart.gif 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;
        }
    }
}

 

ExpandedBlockStart.gif 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);

        }

    }
}

 

ExpandedBlockStart.gif 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

ExpandedBlockStart.gif 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);
        }
    }
}

 

ExpandedBlockStart.gif 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 >

 

ExpandedBlockStart.gif 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就是用自定义邦定来实现的,对一邦定使用时非常灵活,所以主要是掌握它的方法。

ExpandedBlockStart.gif 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 " ;
        }
    }
}

 

ExpandedBlockStart.gif 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:代码方式实现的邦定

ExpandedBlockStart.gif 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 " ;
        }
    }
}

 

ExpandedBlockStart.gif 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();
            }
        }
    }
}

 

 

ExpandedBlockStart.gif 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互操作

自定义标准绑定

 

ExpandedBlockStart.gif 代码
< 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 >

 

创建自定义绑定

ExpandedBlockStart.gif 代码
< 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 >

 

(完)

转载于:https://www.cnblogs.com/CharlesLiu/archive/2010/03/19/1686177.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值