在windows平台上,MSMQ是首选的消息传递中间件,它是一种高速、异步、可靠的通信机制,当我们在Internet上的两个应用需要交换信息时,使用这样的中间件可能是必须的。

   WCF完全面向SOA,大大简化了以往风格迥异的多种分布式解决方案。下面以一个例子:【使用SOA架构,底层使用MSMQ作为消息传递基础设施。】

   首先定义服务端和客户端赖以沟通的Contract,通常将这些Contact定义在一个单独的dll中,如此可被服务端和客户端引用。我们假设一个简单的Contract,即一个接口ICalculate:

   [ServiceContract]
   
public
interface
ICalculate
    {      
        [OperationContract(IsOneWay
= true
)]
       
void
DealOrder( string
orderID);
    }
   例子中,我们将ICalculate定义在WcfLib.dll中。
  
   服务端需要实现ICalculate接口:
    public
class
Calculator : ICalculate
    {    
       
public
void
DealOrder( string
orderID)
        {
            Program.FileLogger.Log(orderID);
        }
    
}
   接下来,服务端就可以以MSMQ的方式发布该服务了,这个可以在配置文件App.Config中进行配置:
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
configuration
>
 
<
system.serviceModel
>
   
<
services
>
     
<
service name
=
"
WcfTest.Calculator
"
>
       
<
endpointaddress
=
"
net.msmq://localhost/private/WcfTest
"
                      binding
=
"
netMsmqBinding
"
bindingConfiguration
=
"
msmq
"
                      contract
=
"
WcfLib.ICalculate
"
/>
     
</
service
>
   
</
services
>
   
<
bindings
>
     
<
netMsmqBinding
>
       
<
binding name
=
"
msmq
"
>
         
<security mode="None"/>
       
</
binding
>
     
</
netMsmqBinding
>
   
</
bindings
>
   
 
</
system.serviceModel
>
</
configuration
>
   配置中红色部分标志了WCF的“ABC”,
address表明了将使用本地的名为WcfTest的专用队列。请注意,
binding配置后有一个
bindingConfiguration,说明这个binding需要更高级的配置,相应的配置段在
bindings Segment中,由于示例中使用的消息队列没有使用域模式,所以security mode 设为None,该配置会将MsmqAuthenticationMode属性设置为MsmqAuthenticationMode.None。另外,配置中显示的WcfTest专用队列需要被设置为“事务性”,在创建队列的时候可以选择此属性。
   配置完成后,我们可以启动该服务了:
  ServiceHost serviceHost
=
new
ServiceHost( typeof
(Calculator));  
  serviceHost.Open();
  
   再来看客户端,非常简单,首先在App.Config中设置“ABC”(与服务端一致):
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
configuration
>
 
<
system.serviceModel
>
   
<
client
>
     
<
endpoint name
=
"
CalculatorClient
"
                address
=
"
net.msmq://localhost/private/WcfTest
"
                binding
=
"
netMsmqBinding
"
bindingConfiguration
=
"
msmq
"
                contract
=
"
WcfLib.ICalculate
"
>
     
</
endpoint
>
   
</
client
>
  
   
<
bindings
>
     
<
netMsmqBinding
>
       
<
binding name
=
"
msmq
"
>
         
<security mode="None"/>
       
</
binding
>
     
</
netMsmqBinding
>
   
</
bindings
>
   
 
</
system.serviceModel
>
</
configuration
>
   在添加了对WcfLib.dll的引用后,接下来就可以调用服务了:
ChannelFactory
<
WcfLib.ICalculate
>
channelFactory
=
new
ChannelFactory
<
ICalculate
>
(
"
CalculatorClient
"
);
ICalculate calculate
=
channelFactory.CreateChannel();
calculate.DealOrder( this
.textBox1.Text);
   使用MSMQ作为消息传递基础设施后,有这样一个好处,当Internet不可用或者服务端没有启动时,客户端仍然可以调用DealOrder方法将消息发送,当然,消息会暂存在队列中,等网络恢复或服务端启动后,这些队列中的消息将会被处理。