Initalizing a message queue handler

kirnekirne Member Posts: 6
edited 2003-10-09 in Navision Attain
Hi!

I am trying to reproduce the Commerce portal feature of starting a message queue handler/poller. I am quite new to Attain so I am not that confident with the code yet.
Anyway, I am able to start the cphandler and get the eventhandler function recognized/displayed in my codeunit. But I simply cannot keep it running. as soon as the onRun method has finished, the codeunit "stops", ie it will not keep polling the queue.
This goes for any kind of eventhandler I try to instantiate... Attain just kills them off.
I might mention that it of course works excellent when run from a form, but I wish to use the NAS.
I tried to find out how NAS starts up the cphandler and see if there is a timer involved, but gave up after digging thru the code an hour or two.

Could someone please give me a pointer on this one... is there anyone who tried something similar (and succeded)?
/ Kirne

Comments

  • Scott_FrappierScott_Frappier Member Posts: 90
    If I remember correctly, the NAS enters CU1 and attaches itself to the NASHandler() function. It then continually loops within this specific function.

    If you look at the function, there is a codeunit call named 'MsgDispatcher'. Because there is an infinite loop occuring, this codeunit is called every couple of seconds (or whatever the polling rate of the NAS is). It therefore is always checking the Message Queue.

    Start with Codeunit 1 (Application Mgmt.) and take a look at the NASHandler function. From there, some key codeunits are:
    RequestHandler Codeunit Request Handler
    MsgDispatcher Codeunit Synchronization
    MailHandler Codeunit Mail Handler

    Hopefully this will kind of point you in the right direction.
    Scott Frappier
    Vice President, Deployment Operations

    Symbiant Technologies, Inc.
    http://www.symbiantsolutions.com
  • kirnekirne Member Posts: 6
    Well, I have been messing around in codeunit 1 and the NASHandler function. As far as I can see, there is no loop. instead, it is run once and depending on the inparameters you specify in the NAS MMC (comma separated), the switch statements kicks off different codeunits.
    In my case I have added my own codeunit which creates an automation (CPHandler) which then polls the message queue.
    This is the only com object I have managed to keep alive like this, although I have my own objects which also support this kind of hosted server functionality. So really, my question is: is there any one who has been able to reproduce the behaviour of CPHandler with their own com objects?
    / Kirne
  • PrebenRasmussenPrebenRasmussen Member Posts: 137
    All you need now is to make your codeunit "SingleInstance".

    Place the cursor under OnRun and choose Properties (SHIFT+F4).

    To 'kill' it again, close the company or the client/NAS.
  • kirnekirne Member Posts: 6
    Well.. That just doesn't work! It only works if I am using the CPHandler, NOT if I am using my own COM objects (which do work if I use them in other environments).
    / Kirne
  • LG_HellströmLG_Hellström Member Posts: 13
    Single Instance CU

    **
    Globals:
    Name DataType Subtype Length
    NCC2 Automation 'Navision Communication Component version 2'.CommunicationComponent
    MSMQBus Automation 'Navision MS-Message Queue Bus Adapter'.MSMQBusAdapter
    NCC2InMsg Automation 'Navision Communication Component version 2'.InMessage
    NCC2OutMsg Automation 'Navision Communication Component version 2'.OutMessage
    DOM3 Automation 'Microsoft XML, v3.0'.DOMDocument30
    InStr InStream
    OutStr OutStream
    Str Text 30
    var Variant

    ***
    Documentation()
    
    OnRun()
    IF ISCLEAR(DOM3) THEN
      CREATE(DOM3);
    IF ISCLEAR(NCC2) THEN
      CREATE(NCC2);
    IF ISCLEAR(MSMQBus) THEN
      CREATE(MSMQBus);
    NCC2.AddBusAdapter(MSMQBus,1);
    
    MSMQBus.OpenReceiveQueue('.\ncc2_queue',0,2);
    
    SendHelloWorld()
    MSMQBus.OpenWriteQueue('.\ncc2_queue',0,2);
    NCC2OutMsg := NCC2.CreateoutMessage('Message queue://');
    OutStr := NCC2OutMsg.GetStream();
    OutStr.WRITETEXT('TXT');
    OutStr.WRITETEXT('Hello World');
    NCC2OutMsg.Send(0);
    
    SendXML()
    DOM3.load('c:\Add.xml');
    MSMQBus.OpenWriteQueue('.\ncc2_queue',0,2);
    NCC2OutMsg := NCC2.CreateoutMessage('Message queue://');
    OutStr := NCC2OutMsg.GetStream();
    OutStr.WRITETEXT('XML');
    DOM3.save(OutStr);
    NCC2OutMsg.Send(0);
    
    NCC2::MessageReceived(VAR InMessage : Automation "''.IDISPATCH")
    NCC2InMsg := InMessage;
    InStr := NCC2InMsg.GetStream();
    InStr.READTEXT(Str,3);
    CASE Str OF
      'TXT': BEGIN
        InStr.READTEXT(Str,MAXSTRLEN(Str));
        MESSAGE(Str);
      END;
      'XML': BEGIN
        IF DOM3.load(InStr) THEN
          MESSAGE(COPYSTR(DOM3.documentElement().baseName(),1,100));
        DOM3.save('c:\Add2.xml');
      END;
    ELSE
      MESSAGE('Unknown Message')
    END;
    MESSAGE('Src: %1',NCC2InMsg.Source());
    NCC2InMsg.CommitMessage();
    

    Using two buttons on a Form calling SendHelloWorld() and SendXML() you may see it work.

    Have fun.
    Did I commit today?
Sign In or Register to comment.