您的位置:首页 > 其它

在WCF中使用消息队列

2016-08-09 11:24 323 查看
在一些大型的解决方案中,假设我们的服务没有办法一直在线,或者因为这样那样的原因宕机了,有没有什么办法让客户端的影响最小化呢?答案是可以通过消息队列的方式,哪怕服务是没有在线的,客户端依然可以继续操作。

1. 首先来学习一些消息队列的基础知识

消息队列默认是没有安装的,可以通过下面的方式进行安装





2. 通过一个小程序来演示一下如何发送和接受消息





static void SendMessage() {
Message msg = new Message("这是我的一个消息");

string queueName = @".\Private$\SampleQueue";
MessageQueue mq = null;

if (!MessageQueue.Exists(queueName))
mq = MessageQueue.Create(queueName);
else
mq = new MessageQueue(queueName);

mq.Formatter = new XmlMessageFormatter(new[] { "System.String" });

mq.Send(msg, "测试消息");

Console.WriteLine("消息发送成功");
}

然后,我们就可以看到这个消息了(通过mmc控制台)

[注意]xp和vista或者win 7都属于桌面操作系统,它们只支持私有队列。如果是服务器操作系统的话,则还支持公共队列。

















下面看看如何读取队列中的消息

static void ReadMessage() {
string queueName = @".\Private$\SampleQueue";
MessageQueue mq = new MessageQueue(queueName);
mq.Formatter = new XmlMessageFormatter(new[] { "System.String" });
Message msg = mq.Receive();
Console.WriteLine(msg.Label);
Console.WriteLine(msg.Body.ToString());

}





上面是一个很简单的例子,演示了如何发送和接收消息。

下面用一个例子来讲解WCF中如何利用消息队列来实现异步的服务。

1. 创建契约

using System;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace Contracts
{
[ServiceContract]
public interface IMSMQService
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(OrderEntry entry);
}

[DataContract]
public class OrderEntry {
[DataMember]
public int OrderID { get; set; }
[DataMember]
public DateTime OrderDate { get; set; }
[DataMember]
public int Quantity { get; set; }
[DataMember]
public int UnitPrice { get; set; }

public override string ToString()
{
return string.Format(
"ID:{0}\tDate:{1}\tQuantity:{2}\tUnitPrice:{3}\t",
OrderID,
OrderDate,
Quantity,
UnitPrice);
}
}

}

2. 实现服务

using System;

namespace Services
{
public class MSMQOrderService:Contracts.IMSMQService
{
#region IMSMQService 成员

public void PlaceOrder(Contracts.OrderEntry entry)
{
Console.WriteLine("收到订单:{0}", entry);
}

#endregion
}
}


3. 创建宿主

using System;
using System.ServiceModel;

namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host =
new ServiceHost(
typeof(Services.MSMQOrderService),
new Uri("net.msmq://localhost/Private/SampleQueue")
))
{

NetMsmqBinding binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
binding.ExactlyOnce = false;
binding.Durable = true;

host.AddServiceEndpoint(
typeof(Contracts.IMSMQService).FullName,
binding,
"");

host.Open();
Console.WriteLine("服务器已经准备好");
Console.Read();

}

}
}
}


4. 创建客户端

using System;
using System.ServiceModel;

namespace Client
{
class Program
{
static void Main(string[] args)
{
NetMsmqBinding binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
binding.ExactlyOnce = false;
binding.Durable = true;

ChannelFactory<Contracts.IMSMQService> channel =
new ChannelFactory<Contracts.IMSMQService>(
binding, new EndpointAddress("net.msmq://localhost/Private/SampleQueue"));

Contracts.IMSMQService client =
channel.CreateChannel();

client.PlaceOrder(
new Contracts.OrderEntry()
{
OrderID = 1,
OrderDate = DateTime.Now,
UnitPrice = 10,
Quantity = 10
});

Console.WriteLine("发送了一个订单");
Console.Read();

}
}
}


5. 测试









很好,我们看到消息发送到了服务器端。但,如果仅仅是这样,那么使用消息队列有什么优势呢?

我们现在不启动服务端,而仅仅启动客户端。看看是否可以发出订单





我们发现,虽然服务没有开启来,但是却依然可以发出订单。那么这个订单到哪里去了呢。原来是被存放到了队列中。如下图所示









然后,我们再去开服务宿主程序。





宿主程序会自动读取消息队列中的消息,并自动进行处理。此时再次去查看队列的话,就会发现已经没有消息了



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: