日期:2011-12-15  浏览次数:20963 次

            在ASP中使用MSMQ
当ASP程序因为某个进程花费了过长的时间而导致在客户端过期时,
当访问者已经放弃了对你的网站的访问而离开去了别的网站时。
或则你的服务器上阻塞了大量的死队列时,错误"Server is too busy"
发生了。
当你在设计网站的过程中碰到这些问题时,一个解决办法就是使用
Microsoft Message Queue (MSMQ)来结束这些进程。

Microsoft Message Queue 的基本介绍:
MSMQ (代号又叫"Falcon") 是运行在Windows NT的服务,它提供运用程序之间
的异步通讯。你可以在NT4 Option Pack中找到它。
MSMQ的基本概念非常的简单:它可以被看成是运用程序之间的email.
一个消息被打包到一个特定类型的容器中,并把这个消息保存到一个用与特别
作用的队列中直到收信者接受该消息为止。
这些队列能够确保MSMQ的传送,而不管当前网络连接的状况如何。
象所有的电子邮件一样,MSMQ消息有一个发送者和一个接收者,其中的接收者
应该能够访问队列。一个单一队列中的一个单独消息,它拥有
多个接受者例如respinder。而消息的发送者通常是Web Server(IIS) 。

MSMQ也能够和其他消息系统进行通讯。例如:
Sun Solaris, HP-UNIX,OS/2, VMS, AS/400平台
象其他的BackOffice服务一样,MSMQ有一个COM API ( mqoa.dll ) 提供给开发者开发
程序。其中最常用的三个类为: MSMQQueueInfo, MSMQQueue, MSMQMessage.

MSQMQueueInfo
MSMQQueueInfo允许你新建,打开,删除队列中的消息.要和队列建立联系首先需要设置
PathName,这是一个命名队列的属性,它告诉MSQM是哪台机器上的队列。
    <%
     Dim objQueueInfo
     Dim objQueue
     Set objQueueInfo=Server.CreateObject("MSMQ.MSMQQueueInfo")
     objQueue.PathName = ".\MyQueue"
     Set objQueue = objQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    %>
上面的代码打开一个叫MyQueue的本地队列.如果队列在另外一台服务器上,代码应该是这样的
    objQueue.PathName = "SomeOtherComputer\MyQueue"
打开队列中有两个参数:Access和ShareMode. Access表示将要对队列执行什么操作。
一般有三个操作:
MQ_PEEK_ACCESS (32), MQ_RECEIVE_ACCESS (1), MQ_SEND_ACCESS (2).
MQ_PEEK_ACCESS用来在特定的队列中查找消息。但对该消息不进行操作。
MQ_RECEIVE_ACCESS 用来在读取队列中的消息后删除它。
MQ_SEND_ACCESS is 用来在队列中发送消息,但不接收消息.
注意的是使用打开操作后返回了一个MSMQQueue对象.
下面是一个典型的新建和删除操作:
    <%
     Dim objQueue
     Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo")
     objQueue.PathName = ".\MyQueue"
     objQueue.Create
    %>

    <%
     Dim objQueue
     Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo")
     objQueue.PathName = ".\MyQueue"
     objQueue.Delete
    %>

MSMQQueue
MSMQQueue类用来描述一个在MSMQ服务中打开的队列。该类提供了一个用来
在指针队列中的消息进行循环的功能。你不能够打开一个使用了MSMQQueue类的队列
要这么干只能够使用MSQMQueueInfo,见上
虽然许多ASP运用程序通常使用MSMQ来发消息,但是很多时候也需要ASP来显示这个消息的具体内容。
获取消息的方式有两种:同步方式,异步方式,但是ASP只能够使用同步方式。
这是因为ASP不能够在服务端申明一个WithEvents变量。
下面先举一个异步方式使用MSMQ的例子(仅VB中)
  Option Explicit
  Dim m_objQueueInfo As New MSMQQueueInfo
  Dim m_objQueue As MSMQQueue
  Dim WithEvents m_objMSMQEvent As MSMQEvent

  Private Sub Form_Load()
    m_objQueueInfo.PathName = ".\MyQueue"
    m_objQueueInfo.Label = "My Sample Queue"
    On Error Resume Next
    m_objQueueInfo.Create
    On Error GoTo 0
    Set m_objQueue = m_objQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

    Set m_objMSMQEvent = New MSMQEvent
    m_objQueue.EnableNotification m_objMSMQEvent, MQMSG_CURRENT, 1000
  End Sub

  Private Sub m_objMSMQEvent_Arrived(ByVal Queue As Object, ByVal Cursor As Long)
    Dim m_objMessage As MSMQMessage
    Set m_objMessage = Queue.PeekCurrent
    MsgBox "Message R