可变排队通信
此示例演示如何通过消息队列 (MSMQ) 传输来执行可变排队通信。此示例使用 NetMsmqBinding。此例中的服务是自承载控制台应用程序,通过它可以观察服务接收排队消息。
提示
本主题的末尾介绍了此示例的设置过程和生成说明。
在排队通信中,客户端使用队列与服务进行通信。更确切地说,客户端向队列发送消息。服务从队列接收消息。因此不必同时运行服务和客户端便可使用队列进行通信。
发送没有保证的消息时,MSMQ 仅尽量传递消息,这不同于“一次性”保证。具有“一次性”保证时,MSMQ 可确保消息被送达,如果无法送达消息,则会向您发出通知。
在某些情况下,当及时送达比丢失消息更重要时,您可能想要通过某个队列发送没有保证的可变消息。队列管理器崩溃时可变消息不存在。因此,如果队列管理器崩溃,用于存储可变消息的非事务性队列可以存在,但消息本身则无法存在,因为消息未存储在磁盘中。
提示
不能使用 MSMQ 在某个事务范围内发送没有保证的可变消息。还必须创建非事务性队列以发送可变消息。
此示例中的服务协定是定义最适合与队列一起使用的单向服务的 IStockTicker
。
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IStockTicker
{
[OperationContract(IsOneWay = true)]
void StockTick(string symbol, float price);
}
服务操作显示股票代号符号和价格,如下面的示例代码所示:
public class StockTickerService : IStockTicker
{
public void StockTick(string symbol, float price)
{
Console.WriteLine("Stock Tick {0}:{1} ", symbol, price);
}
…
}
服务是自承载服务。使用 MSMQ 传输时,必须提前创建所使用的队列。可以手动或通过代码完成此操作。在此示例中,该服务包含代码,以检查队列是否存在并在必要时创建队列。从配置文件中读取队列名称。Service Model Metadata Utility Tool (Svcutil.exe) 使用该基址来生成服务的代理。
// Host the service within this EXE console application.
public static void Main()
{
// Get MSMQ queue name from app settings in configuration.
string queueName = ConfigurationManager.AppSettings["queueName"];
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName);
// Create a ServiceHost for the StockTickerService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(StockTickerService)))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHost to shutdown the service.
serviceHost.Close();
}
}
MSMQ 队列名是在配置文件的 appSettings 节中指定的。服务终结点是在配置文件的 system.serviceModel 节中定义的,它指定了 netMsmqBinding 绑定。
提示
队列名称使用圆点 (.)来表示本地计算机,并在使用 System.Messaging 创建队列时在其路径中使用反斜杠分隔符。Windows Communication Foundation (WCF) 终结点地址指定一个 net.msmq: 方案,使用“localhost”来表示本地计算机,并在其路径中使用正斜杠。
消息的保证和持久性或可变性也在配置中指定。
<appSettings>
<!-- use appSetting to configure MSMQ queue name -->
<add key="queueName" value=".\private$\ServiceModelSamplesVolatile" />
</appSettings>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.StockTickerService"
behaviorConfiguration="CalculatorServiceBehavior">
...
<!-- Define NetMsmqEndpoint -->
<endpoint address="net.msmq://localhost/private/ServiceModelSamplesVolatile"
binding="netMsmqBinding"
bindingConfiguration="volatileBinding"
contract="Microsoft.ServiceModel.Samples.IStockTicker" />
...
</service>
</services>
<bindings>
<netMsmqBinding>
<binding name="volatileBinding"
durable="false"
exactlyOnce="false"/>
</netMsmqBinding>
</bindings>
...
</system.serviceModel>
由于该示例通过使用非事务性队列来发送排队消息,因此无法将经过事务处理的消息发送到队列。
// Create a client.
Random r = new Random(137);
StockTickerClient client = new StockTickerClient();
float price = 43.23F;
for (int i = 0; i < 10; i++)
{
float increment = 0.01f * (r.Next(10));
client.StockTick("zzz" + i, price + increment);
}
//Closing the client gracefully cleans up resources.
client.Close();
运行示例时,客户端和服务活动将显示在服务和客户端控制台窗口中。您可以看到服务从客户端接收消息。在每个控制台窗口中按 Enter 可以关闭服务和客户端。请注意:由于正在使用队列,因此不必同时启动和运行客户端和服务。可以先运行客户端,再将其关闭,然后启动服务,这样服务仍然会收到客户端的消息。
The service is ready.
Press <ENTER> to terminate service.
Stock Tick zzz0:43.25
Stock Tick zzz1:43.23
Stock Tick zzz2:43.28
Stock Tick zzz3:43.3
Stock Tick zzz4:43.23
Stock Tick zzz5:43.25
Stock Tick zzz6:43.25
Stock Tick zzz7:43.24
Stock Tick zzz8:43.32
Stock Tick zzz9:43.3
设置、生成和运行示例
若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。
若要用单机配置或跨计算机配置来运行示例,请按照运行 Windows Communication Foundation 示例中的说明进行操作。
默认情况下使用 NetMsmqBinding 启用传输安全。MSMQ 传输安全有两个相关的属性,即 MsmqAuthenticationMode 和 MsmqProtectionLevel。默认情况下,身份验证模式设置为 Windows,保护级别设置为 Sign。为了使 MSMQ 提供身份验证和签名功能,MSMQ 必须是域的一部分,并且必须安装 MSMQ 的 Active Directory 集成选项。如果在不满足这些条件的计算机上运行此示例,将会收到错误。
在加入到工作组或在没有 Active Directory 集成的计算机上运行示例
如果计算机不是域成员或尚未安装 Active Directory 集成,请将身份验证模式和保护级别设置为 None 以关闭传输安全性,如下面的示例配置代码所示:
<system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.StockTickerService" behaviorConfiguration="StockTickerServiceBehavior"> <host> <baseAddresses> <add baseAddress="https://localhost:8000/ServiceModelSamples/service"/> </baseAddresses> </host> <!-- Define NetMsmqEndpoint --> <endpoint address="net.msmq://localhost/private/ServiceModelSamplesVolatile" binding="netMsmqBinding" bindingConfiguration="volatileBinding" contract="Microsoft.ServiceModel.Samples.IStockTicker" /> <!-- the mex endpoint is explosed at https://localhost:8000/ServiceModelSamples/service/mex --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <netMsmqBinding> <binding name="volatileBinding" durable="false" exactlyOnce="false"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="StockTickerServiceBehavior"> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
确保在运行示例前更改服务器和客户端上的配置。
提示
将 security mode 设置为 None 等效于将 MsmqAuthenticationMode、MsmqProtectionLevel 和 Message 安全设置为 None。
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.