WCF分布式开发必备知识(1):MSMQ消息队列

简介:
  学习WCF是不是就不需要学习.Net Remoting、ASMX、WSE和MSMQ了?
     这个问题一直是很多开发者关注的问题.按照微软的说法,WCF是微软分布式应用程序开发的集大成者,学习WCF编程,就不需要了解其他的技术.这个说法有一定的道理.WCF的出现确实解决了很多问题,它整合了.Net平台下所有的和分布式系统有关的技术,例如.Net Remoting、ASMX、WSE和MSMQ。以通信(Communiation)范围而论,它可以跨进程、跨机器、跨子网、企业网乃至于 Internet;可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)。开发人员可以构建跨平台、安全、可靠和支持事务处理的企业级互联应用解决方案。既然WCF如此强大,开发者再不用去分别了解.Net Remoting,ASMX等各种技术了。
     可事实并非如此,首先,技术的更新换代没有那么迅速,我们接触的工作平台和技术文章不会因为WCF的出现而全部更新,其次作为一个开发人员,在实际开发过程要学习或者解决技术问题,必须知道其相关的概念,扎实的基础知识毕不可少.
     在本节我们就来了解一下MSMQ的基本概念和开发过程.我们先来了解一下什么是MSMQ:
     MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理.
       其中两个重要的概念。一个是消息Message ,一个是队列Queue。
     消息Message是由通信的双方所需要传递的信息,它可以是各式各样的媒体,如文本、声音、图象等等。消息最终的理解方式,为消息传递的双方事先商定,这样做的好处是,一是相当于对数据进行了简单的加密,二则采用自己定义的格式可以节省通信的传递量。消息可以含有发送和接收者的标识,只有指定的用户才能看到回执。时间戳,便于接收方对某些与时间相关的应用进行处理。截止时间,指定时间内消息还未到达则作废。
队列的类型主要包括一下几种:
“公共队列”在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。 
“专用队列”不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。 
“管理队列”包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。 
“响应队列”包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。
     消息队列Queue是发送和接收消息的公用存储空间,它可以存在于内存中或者是物理文件中。消息可以以两种方式发送,即快递方式(express)和可恢复模式(recoverable),它们的区别在于,快递方式为了消息放置于内存中,可恢复模式放于物理磁盘上(详细参见MSDN).
 
     了解到消息队列MSMQ相关的基本概念以后,我们知道它的
优点:稳定、消息优先级、脱机能力以及安全性,有保障的消息传递和执行许多业务处理的可靠的防故障机制。
缺点:MSMQ不适合于Client需要Server端实时交互情况.大量请求时候,响应延迟.
     优点决定了它的松耦合的特性,消息队列同样是实现SOA面向对象的架构的方式之一.现在我们就来看看简单的MSMQ编程.
     要在.net平台上进行MSMQ的开发,需要配置开发环境,安装消息队列,具体的安装过程可以baidu,直接在安装光盘里查找安装windows组件,选择消息队列安装即可.
安装结束后,可以在我的电脑--管理--消息队列
这个证明你已经安装成功.下面就可以来使用Visual Stdudio进行开发了. 注意对特定类型队列的操作代码,一定要安装成功相应的队列类型。
首先,创建一个控制台项目(当然你也可以创建Web或者Winform应用程序).添加项目引用 System.Messaging,因为消息队列相关的类库全部封装在System.Messaging.dll程序集里了.下面我们就来写自己的代码.
  static   void  Main( string [] args)
        {
            
// Create a public Queue
             if  ( ! MessageQueue.Exists( @" .\FrankMSMQ " ))
            {
                
using  (MessageQueue mq  =  MessageQueue.Create( @" .\FrankMSMQ " ))
                {
                    mq.Label 
=   " FrankPublicQueue " ;
                    Console.WriteLine(
" FrankPublicQueue is Created: " );
                    Console.WriteLine(
" Path is {0}: " , mq.Path);
                    Console.WriteLine(
" FrankPublicQueue' name is {0}: " , mq.QueueName);
                    
// Console.Read();
                    mq.Send( " MSMQ Message " " Frank.Xu " );
                }
            }
// Create a private Queue
             if  ( ! MessageQueue.Exists( @" .\Private$\FrankMSMQ " ))
            {
                
using  (MessageQueue mq  =  MessageQueue.Create( @" .\Private$\FrankMSMQ " ))
                {
                    mq.Label 
=   " FrankPrivateQueue " ;
                    Console.WriteLine(
" FrankPrivateQueue is Created: " );
                    Console.WriteLine(
" Path is {0}: " , mq.Path);
                    Console.WriteLine(
" FrankPrivateQueue' name is {0}: " , mq.QueueName);
                    
// Console.Read();
                    mq.Send( " MSMQ Private Message " " Frank.Xu " );
                }
            }

            
// Get all public queues and send new messages
             foreach  (MessageQueue mq  in  MessageQueue.GetPublicQueues())
            {
                mq.Send(
" Sending MSMQ public message "   +  DateTime.Now.ToLongDateString(), " Frank.Xu " );
                
// string mName = mq.MachineName;
                Console.WriteLine( " Public Message is sent to {0}: " , mq.Path);
            }
            
// find private queues and send new messages
             if  (MessageQueue.Exists( @" .\Private$\FrankMSMQ " ))
            {
                MessageQueue mq 
=   new  MessageQueue( @" .\Private$\FrankMSMQ " );
                mq.Send(
" Sending MSMQ private message "   +  DateTime.Now.ToLongDateString(),  " Frank.Xu " );
                Console.WriteLine(
" Private Message is sent to {0}: " , mq.Path);
            }
            Console.Read();
        }
      比较重要的类就是 MessageQueue,这行代码创建消息队列 MessageQueue mq = MessageQueue.Create(@".\FrankMSMQ"),参数是存放消息队列的位置.这个基本就完成了创建和发送消息的主程序.下面我们来建立一个客户端,来访问消息队列,获取消息,同样建立一个控制台应用程序,添加引用和代码:
using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Messaging;
namespace  MSMQClient
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            
// Get public queue message
             if  (MessageQueue.Exists( @" .\FrankMSMQ " )) // 判断是否存在消息队列
            {

                
using (MessageQueue mq  =   new  MessageQueue( @" .\FrankMSMQ " )) // 创建消息队列对象
                {
                    mq.Formatter 
=   new  XmlMessageFormatter( new   string [] {  " System.String "  }); // 设置消息队列的格式化器
                    
// mq.Send("Sample Message", ":Label");
                    Message msg  =  mq.Receive(); // 从队列接受消息
                    Console.WriteLine( " Received MSMQ Message is :{0} " , msg.Body); // 输出消息
                    
// BinaryMessageFormatter
                    
// ActiveXMessageFormatter
                }
                    
// Console.Read();
            }
            
// Get private queue message
             if  (MessageQueue.Exists( @" .\Private$\FrankMSMQ " )) // 判断私有消息是否存在
            {

                
using  (MessageQueue mq  =   new  MessageQueue( @" .\Private$\FrankMSMQ " ))
                {
                    mq.Formatter 
=   new  XmlMessageFormatter( new   string [] {  " System.String "  }); // 设置消息队列格式化器
                    
// mq.Send("Sample Message", ":Label");
                    Message msg  =  mq.Receive(); // 接收消息
                    Console.WriteLine( " Received MSMQ Private Message is: {0} " , msg.Body); // 输出消息
                }
                    
            }
            Console.Read();
        }
    }
}
      消息接收同样需要实例化一个消息队列对象,  using(MessageQueue mq = new MessageQueue(@".\FrankMSMQ"))负责创建消息队列对象.其次 mq.Formatter = new XmlMessageFormatter(new string[] { "System.String" })这行代码负责设置消息队列的格式化器,因为消息的传递过程中存在格式化的问题.我们接收消息的时候必须指定消息队列的格式化属性Formatter,队列才能接受消息.XmlMessageFormatter的作用是进行消息的XML串行化. BinaryMessageFormatter则把消息格式化为二进制数据进行传输.ActiveXMessageFormatter把消息同样进行二进制格式化,区别是可以使用COM读取队列中的消息.
     当然消息队列还可以发送复杂的对象,前提是这个对象要可串行化,具体的格式取决与队列的格式化器设置.此外消息队列还支持事务队列来确保消息只发送一次和发送的顺序.
     最近在研究SOA,所以系统系统学习一下WCF及其相关的技术,以上就是这个消息队列的基本的概念和简单的编程实现.下一节是关于.Net Remoting的基础知识和开发的文章.~
我准备把WCF相关的几个知识点都系统整理一下,包括代码的实现.发出来一起与大家交流学习~
(程序代码下载 MSMQ_Codes)
 



 本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/320386,如需转载请自行联系原作者



相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
2月前
|
消息中间件 C# 数据安全/隐私保护
手写MSMQ微软消息队列收发工具类
【10月更文挑战第16天】本示例展示了如何使用C#语言编写MSMQ(微软消息队列)的收发工具类,包括发送和接收消息的方法。通过检查队列是否存在并创建、使用`MessageQueue`类发送和接收消息。示例还提供了简单的调用方式,并提醒用户注意权限管理和异常处理。
|
C++
WCF框架-分布式联调
WCF框架-分布式联调
104 0
|
消息中间件 C#
【c#】队列(Queue)和MSMQ(消息队列)的基础使用
原文:【c#】队列(Queue)和MSMQ(消息队列)的基础使用       首先我们知道队列是先进先出的机制,所以在处理并发是个不错的选择。然后就写两个队列的简单应用。 Queue 命名空间     命名空间:System.Collections,不在这里做过多的理论解释,这个东西非常的好理解。
1510 0
|
XML 监控 安全
Adhesive框架系列文章--WCF 分布式服务模块使用和实现
Adhesive框架中的WCF分布式服务模块基于原来写的WCF扩展修改而来,主要的修改如下: 1)原先使用数据库的元数据配置,现在统一改为配置服务,主要是为了统一,不用再去开发一个WCF的配置后台 2)原先直接存储到Mongodb中的各种日志,现在统一使用Monodb数据服务,也是进行了一个统一 3)和信息中心模块中的网站请求状态(统计每一个请求的情况)一样,这里也提供了WCF客户端和服务端的执行状态   这个模块主要实现如下功能: 1)集中化的配置:地址、绑定、契约、端点等等信息都无需在配置文件中配置,直接在统一的配置服务中进行配置。
973 0
|
消息中间件 数据安全/隐私保护
MSMQ(2)——.net下的消息队列管理空间
System.Messaging 名字空间下包含了用于连接到、监视和管理网络上的消息队列,并发送、接收或查看消息的类。 其中一个主要的类是MessageQueue 它提供对消息队列上的消息进行访问。
773 0
|
消息中间件 测试技术 Windows
WCF 消息队列通信
MSMQ, microsoft Message Queue,微软消息队列。通过它,应用程序开发人员可以通过发送和接收消息,来与应用程序进行快速可靠的通信。   在WCF中,提供了MSMQ通信绑定:NetMsmqBinding和MsmqIntegrationBinding 这里做个简单的演示。
701 0