在WCF中使用消息队列

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

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. 测试

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

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

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

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

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

时间: 2024-11-08 10:53:01

在WCF中使用消息队列的相关文章

UCOS中的消息队列并不是真正意义上的队列

UCOS中的消息队列并不是真正意义上的队列,它只是发送了想要发送数据的指针,这个时候,如果发送多个同一个变量的不同数据,那么数据就相当于被覆盖了. 解决办法: 定义一个缓存数组buffer[i]; 更改变量i的数值,就可以实现一个变相的FIFO,因为每次发送的变量的指针是不同的. i++; i %= bufsize; buffer[ ( i + bufsize - 1 ) % bufsize ]; //此处是取的上一个数据,当前数据直接取buffer[i]即可.

跟我一起学WCF(1)——MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能,并提供了与消息队列(MSMQ).COM+.Asp.net Web服务..NET Remoting等微软现有的分布式系统技术.利用WCF平台,开发人员可以很方便地构建面向服务的应用程序(SOA).可以认为,WCF是对之前现有的分布式技术(指的是MSMQ..NET Remoting和Web 服务等技术

Linux中的消息队列

消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先进先出.消息队列与命名管道有一样的不足,就是每个消息的最大长度是有上限的( MSGMAX),每个消息队列的总的字节数是有上限的( MSGMNB),系统上消息队列的总数也有一个上限( MSGMNI). 消息队列是用链表实现的. 1.创建新消息队列或取得已存在消息队列 原型: int msgget(key_t key, int msgflg); 参数:key:可以认为是一个端口号,也可以由函数ftok生成.msgflg:IPC_C

C#中使用消息队列服务

C#中使用Windows消息队列服务 http://www.cnblogs.com/xinhaijulan/archive/2010/08/22/1805768.html http://h2appy.blog.51cto.com/609721/184323 http://www.cnblogs.com/isdavid/archive/2012/08/16/2642867.html http://www.cnblogs.com/beniao/archive/2008/06/26/1229934.h

如何应用.NET中的消息队列服务

建立一个队列是应用MSMQ的第一步.您可以通过Windows计算机管理控制台中的消息队列选项完成这一操作,或者自己编程建立一个队列.列表A中的C#代码建立了一个新的私有MSMQ消息队列(如果不存在队列),并同时创建一条消息. 代码应用MessageQueue类的Exists方法来确定是否存在一个名为TechRepublic的私有队列.如存在,它用现有队列示例这个MessageQueue对象;否则,就建立一个新队列. 新的Message对象用来向队列发送一条消息.它的Label属性指定在MSMQ控

在C#中使用消息队列RabbitMQ

参考文章:http://www.cnblogs.com/qy1141/p/4054135.html 开发环境&工具: VS2017 RabbitMq Erlang运行环境 先安装Erlang运行环境然后再安装RabbitMq 安装和配置就不说了 默认安装路径:C:\Program Files\RabbitMQ Server,在rabbitmq_server-3.6.11\sbin文件夹下有bat文件 默认配置文件路径: C:\Users\wangshibang\AppData\Roaming\R

ZWave 中的消息队列机制

文章主题   在我们的日常编程中,对消息队列的需求非常常见,使用一个简洁.高效的消息队列编程模型,对于代码逻辑的清晰性,对于事件处理的高效率来说,是非常重要的.这篇文章就来看看 ZWave 中是通过什么机制为我们提供了一个便捷的消息队列处理机制. 内容导航   消息队列是什么 我自己写的消息队列 ZWave 消息队列的结构 ZWave 消息队列的使用(初始化.存储消息.取出消息) 消息队列是什么   消息队列最主要特点是:存储消息,先进先出. 比如在典型的生产者-消费者编程模型中,先创建一个消息

Python中queue消息队列模块

from queue import Queue from queue import PriorityQueue print("Queue类实现了一个基本的先进先出(FIFO)容器,使用put()将元素添加到序列尾端,get()从队列尾部移除元素.\n") q = Queue() for i in range(3): q.put(i) while not q.empty(): print(q.get()) print("与标准FIFO实现Queue不同的是,LifoQueue使

跟我一起学WCF(11)——WCF中队列服务详解

一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端和服务之间的离线工作,客户端将消息发送到一个队列中,再由服务对它们进行处理.下面让我们具体看看WCF中的队列服务. 二.WCF队列服务的优势 在介绍WCF队列服务之前,首先需要了解微软消息队列(MSMQ).MSMQ是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布在同一台机器