2 Replies Latest reply on Jun 24, 2004 12:21 AM by 155274

    QA MonitorStart Problem

    25204
      I am attempting to monitor Advanced Queuing messages in a VB 6 program using Oracle 8.1.7. I created a VB Class module called CallBackclient with a Method called NotifyMe:

      Public Sub NotifyMe(ByVal Ctx As Variant, ByVal Msgid As Variant)
      Dim OraMsg As OraAQMsg
      Dim OraObj As OraObject

      On Error GoTo NotifyMeErr

      Set OraMsg = Ctx.AQMsg(1, "MESSAGE_TYPE", "schema")
      Set OraObj = Nothing
      Set OraObj = OraMsg.Value
      MsgBox "Message Data = " & OraObj("msgdata").Value
      Set OraMsg = Nothing
      Exit Sub
      NotifyMeErr:
      MsgBox "NotifyMe Error"
      End Sub

      In the program's main form I have the following:

      Public OraSession As Object
      Public OraDatabase As OraDatabase
      Public OraAq As OraAq
      Public OraMsg As OraAQMsg

      Set OraSession = CreateObject("OracleInProcServer.XOraSession")
      Set OraDatabase = OraSession.DbOpenDatabase("database", "user" & "/" & "password", 0&)
      Set OraAq = OraDatabase.CreateAQ("queuename")
      Set OraMsg = OraAq.AQMsg(1, "MESSAGE_TYPE", "schema")

      OraAq.MonitorStart CB_Client, OraAq.AQMsg

      When I execute the program, I get this error:

      Run-time Error -2147213295 (80042011):
      Method 'MonitorStart' of object '_IOraAQ' failed.

      Any suggestions/help in solving this problem would be much appreciated.
        • 1. Re: QA MonitorStart Problem
          82532
          Is the NotifyMe an automation interface on an automation object? In other words, the program that implements it has defined a COM interface (is a COM automation server)?

          Been a while since I used this with VB.

          Mark
          • 2. Re: QA MonitorStart Problem
            155274
            I got this to work by creating the CallBackClient as an VB ActiveX DLL.

            The following code starts and stops the Monitor via two command buttons. You will need to add a reference to the ActiveX DLL containing the CallBackClient to a Standard EXE. Add the following code to the Standard EXE.

            Option Explicit

            Public CB_Client As CallbackClient
            Public DB As OraDatabase
            Public SS As Object
            Public Q As OraAQ
            Public DBEventsHdlr As DBEventCls
            Public gOraSession As Object
            Public gOraSubscriptions As OraSubscriptions
            Public gOraDatabase As OraDatabase
            Public gOraQueue As OraAQ

            Private Sub Command1_Click()
            Dim S As String

            'First instantiate the CallbackClient. The queue monitor
            'will invoke the NotifyMe on this class module.
            Set CB_Client = New CallbackClient

            'Create the OraSession Object
            Set SS = CreateObject("OracleInProcServer.XOraSession")

            'Create the OraDatabase Object by opening a connection to Oracle.
            Set DB = SS.DbOpenDatabase("database", _
            "user/password", _
            ORADB_ENLIST_FOR_CALLBACK)

            Set Q = DB.CreateAQ("schema.queue_name")

            'Notify by calling cbclient::NotifyMe when there are messages

            ' for consumer '"BROKER_AGENT"

            Q.Consumer = "consumer_name"

            'Note that cbclient is a dispatch interface that

            ' supports the NotifyMe method.

            S = "consumer_name"

            'Notify the client only when there are messages for "BROKER_AGENT"

            Q.MonitorStart CB_Client, Q, S, ORAAQ_CONSUMER

            'other processing is performed here...

            Command2.Enabled = True
            Command1.Enabled = False
            End Sub

            Private Sub Command2_Click()
            Q.MonitorStop
            Set Q = Nothing
            Set DB = Nothing
            Set SS = Nothing
            Set CB_Client = Nothing
            Command1.Enabled = True
            Command2.Enabled = False
            End Sub

            Add the following code to the ActiveX DLL in a class module called CallbackClient.

            Option Explicit

            Public Sub NotifyMe(ByVal Ctx As Variant, ByVal Payload As Variant)
            Dim OraMsg As OraAQMsg
            Dim OraObj As OraObject
            Dim OraQ As OraAq

            Set OraQ = Ctx

            On Error GoTo ErrHandler

            Set OraMsg = OraQ.AQMsg (ORATYPE_OBJECT, "MESSAGE_TYPE", "schema")
            OraQ.Dequeue
            Set OraObj = OraMsg.Value
            MsgBox "SUBJECT Data = " & "|" & OraObj.Item(1).Value & "|" & OraObj("SUBJECT").Value & "|" & vbCrLf & _
            "TEXT Data = " & "|" & OraObj.Item(2).Value & "|" & OraObj("TEXT").Value & "|", vbOKOnly, "NotifyMe"
            ' Set OraObj = Payload
            ' MsgBox "SUBJECT Data = " & "|" & OraObj.Item(1).Value & "|" & OraObj("SUBJECT").Value & "|" & vbCrLf & _
            ' "TEXT Data = " & "|" & OraObj.Item(2).Value & "|" & OraObj("TEXT").Value & "|", vbOKOnly, "NotifyMe"

            ExitSub:
            Set OraQ = Nothing
            Set OraObj = Nothing
            Set OraMsg = Nothing
            Exit Sub
            ErrHandler:
            'MsgBox "NotifyMe Error"
            GoTo ExitSub
            End Sub

            In Oracle you will need to execute the following procedures:
            dbms_aqadm.create_queue_table()
            dbms_aqadm.create_queue()
            dbms_aqadm.start_queue()
            DBMS_AQADM.ADD_SUBSCRIBER() for multiple consumer queue
            dbms_aq.enqueue() adds a message

            After setting up everything this code will dequeue one message.

            After getting this to work how do I restart the monitor after exiting NotifyMe()?