| 
| 技术资料  > ASP技术 > 客户端相关 : 了解MSMQ,控制ASP进程 (一) |  
了解MSMQ,控制ASP进程 (一) March 25,2004 |  
     我们在使用 ASP  
    程序时常常会遇到这些情况:某个进程花费了过长的时间而导致在客户端过期、访问者已经放弃了对你的网站的访问而离开去了别的网站、或你的服务器上阻塞了大量的死队列时,系统出现  
    "Server is too busy" 错误信息。  
     
        
    当你在设计网站的过程中碰到这些问题时,一个有效的解决办法就是使用  
    Microsoft Message Queue (MSMQ) 来结束这些进程,让网站恢复正常!  
     
       到底 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 。  
     
       ( 1 )、 MSQMQueueInfo  
     
       MSMQQueueInfo 允许你新建,打开,删除队列中的消息 .  
    要和队列建立联系首先需要设置 PathName  
    ,这是一个命名队列的属性,它告诉 MSQM 是哪台机器上的队列。  
    < %  
    Dim objQueueInfo 
    Dim objQueue 
    Set objQueueInfo=Server.CreateObject("MSMQ.MSMQQueueInfo") 
    objQueue.PathName = ".MyQu" 
    Set objQueue = objQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE) 
    %> 
     
     
       上面的代码打开一个叫 MyQueue  
    的本地队列。如果队列在另外一台服务器上,代码应该是这样的:  
     
       objQueue.PathName = "SomeOtherComputerMyQu"  
     
       打开队列中有两个参数: Access 和 ShareMode 。 Access  
    表示将要对队列执行什么操作。一般有三个操作:  
     
       MQ_PEEK_ACCESS (32), MQ_RECEIVE_ACCESS (1), MQ_SEND_ACCESS (2) 。  
     
       MQ_PEEK_ACCESS  
    用来在特定的队列中查找消息。但对该消息不进行操作。  
     
       MQ_RECEIVE_ACCESS 用来在读取队列中的消息后删除它。  
     
       MQ_SEND_ACCESS 用来在队列中发送消息 , 但不接收消息。  
     
       需要注意的是在使用打开操作后返回了一个 MSMQQueue  
    对象。下面是一个典型的新建和删除操作例子:  
    < %  
    Dim objQueue 
    Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo") 
    objQueue.PathName = ".MyQu" 
    objQueue.Create 
    %>  
     
    < % 
    Dim objQueue 
    Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo") 
    objQueue.PathName = ".MyQu" 
    objQueue.Delete 
    %> 
     
     
       ( 2 )、 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 = ".MyQu" 
    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 Received: " & m_objMessage.Label 
    m_objQueue.EnableNotification m_objMSMQEvent, MQMSG_NEXT, 10000 
    End Sub 
     
    Private Sub m_objMSMQEvent_ArrivedError(ByVal Queue As Object, ByVal ErrorCode As Long,  
    ByVal Cursor As Long) 
    MsgBox "Error accorded: " & ErrorCode 
    End Sub 
     
     
       这段代码首先建立一个队列(如果它还不存在的话)。然后  
    m_objMSMQEvent 对象通过调用 EnableNotification 连接到 MSMQQueue  
    对象。一旦连接到 MSMQEvent 对象 , 接下来需做的仅仅是完成 Arrived 和  
    Arrived_Error ( 可选的 ) 事件。 Arrived  
    事件当一个新的消息到达队列时将被触发该事件返回两个指针 ,  
    一个是指向队列中应该从来开始读消息的位置,另外一个是当前的位置。如果发生错误,将触发  
    ArrivedError  
    事件当同步获取消息时,会一直等到消息可获取或则超时时程序才会不被挂起。代码如下:  
     
    Public Sub DisplayMessages() 
    Dim objQueueInfo As New MSMQQueueInfo 
    Dim objQueue As MSMQQueue 
    Dim objMessage As MSMQMessage 
    objQueueInfo.PathName = ".MyQu" 
    objQueueInfo.Label = "My Sample Queue" 
     
    On Error Resume Next 
    objQueueInfo.Create 
    On Error GoTo 0 
    Set objQueue = objQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE) 
    Do While True 
    Set objMessage = objQueue.Peek(, , 1000) 
    If objMessage Is Nothing Then Exit Do 
    MsgBox "Message: " & objMessage.Label 
    Loop 
    MsgBox "No more new messages." 
    objQueue.Close 
    Set objMessage = Nothing 
    Set objQueue = Nothing 
    Set objQueueInfo = Nothing 
    End Sub 
     
     
     
       ( 3 )、 MSMQMessage  
     
       MSMQMessage 类支持队列中消息的所有属性。 MSMQ  
    消息有两个方法和繁多的属性。其中两个最主要的属性是: Body 和  
    LabeL 。最主要的方法有 Send 。有两种方法来获取消息: opening ,  
    peeking 。当使用 opening 方式后,该消息将会被删除掉;当使用 peeking  
    方式后,该消息仍然保存在队列中直到它过期。它们的返回值都是指向该消息的指针。下例的代码将打开一个消息,并显示其  
    Body 和 Label  
    Private Sub LookForMessage() 
    Dim objQInfo As New MSMQQueueInfo 
    Dim objQReceive As MSMQQueue 
    Dim objMessage As MSMQMessage 
    objQInfo.PathName = ".test"  
    Set objQReceive = objQInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE) 
    Set objMessage = objQReceive.Receive(, , , 1000) 
    If Not objMessage Is Nothing Then 
    MsgBox objMessage.Label & " - " & objMessage.Body 
    Else 
    Msgbox "Nothing in the queue" 
    End If 
    objQReceive.Close 
    Set objQInfo = Nothing 
    Set objQReceive = Nothing 
    Set objMessage = Nothing 
    End Sub 
     
     
       这段代码打开一个队列并在该队列中查找消息,使用 Receive  
    方法,主要是设置一个 1000 微秒的超时 , 它告诉 MSMQ1000  
    微秒后停止查找设置一个非常段的超时的功能主要是用来检查是否存在消息而不是等候一个消息。也就是说如果你知识想看看是否有消息可以使用该方法。如果无消息,返回的指针为空  
    (If Not objMessage Is Nothing) 。下面是发送一个消息的代码:  
    < % 
    Dim objQInfo 
    Dim objQSend 
    Dim objMessage 
    Set objQInfo = Server.CreateObject("MSMQ.MSMQQueueInfo") 
    objQInfo.PathName = ".test"  
    Set objQSend = objQInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE) 
    Set objMessage = Server.CreateObject("MSMQ.MSMQMessage") 
    objMessage.Label = "This is the label." 
    objMessage.Body = "This is the body." 
    objMessage.Send objQSend 
    objQSend.Close 
    Set objQInfo = Nothing 
    Set objQSend = Nothing 
    Set objMessage = Nothing 
    %> 
     
     
       对于 MSMQ  
    的有关基本知识我们已做了举例介绍,下面将就它的具体运用进行的了解及探讨! |  
 
 |