Snippets

litmis Node.js Async DataQueue Event Emitter

Created by Aaron Bartell last modified

| | | - | - | - | - IBM i Hosting | Cybersource Toolkit for i | RPG-XML Suite | Payment Terminal Toolkit for i | UPS Toolkit for i

Node.js Async DataQueue Event Emitter

Had somebody ask me how to do asynchronous and repeated calls to a data queue that was being fed by RPG. This micro tutorial explains how that can be accomplished.

First edit /QOpenSys/QIBM/ProdData/OPS/Node4/os400/xstoolkit/lib/idataq.js and modify receiveFromDataQueue to have a wait parameter and apply it to the fifth program call parameter. I don't know why IBM didn't include this parm.

iDataQueue.prototype.receiveFromDataQueue = function(name, lib, length, wait, cb){ 
        var pgm = new xt.iPgm("QRCVDTAQ", {"lib":"QSYS"});                      
        pgm.addParam(name, "10A");                                              
        pgm.addParam(lib == ""?"*CURLIB":lib, "10A");                           
        pgm.addParam(length, "5p0");                                            
        pgm.addParam("", length + 1 + "A");                                     
        pgm.addParam(wait, "5p0"); 

Here's the Node.js code. Notice the use of event emitters and recursive re-entry. This approach allows another part of the program to process the entry data (i.e. send to browser) so immediate subsequent listening of the data queue can take place.

app.js

var xt = require("/QOpenSys/QIBM/ProdData/OPS/Node4/os400/xstoolkit/lib/itoolkit");
var dq = require('/QOpenSys/QIBM/ProdData/OPS/Node4/os400/xstoolkit/lib/idataq');
const EventEmitter = require('events');
const util = require('util');

var conn = new xt.iConn("*LOCAL");
var dtq = new dq.iDataQueue(conn);


function MyEmitter() {
  EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter);

const myEmitter = new MyEmitter();
myEmitter.on('event', (x) => {
  console.log('an event occurred! Received:' + x);
});

var recDtaQ = function(){
  dtq.receiveFromDataQueue("MYDQ", "MYLIB", 10, -1, function(data){
      if(data != 'end'){
        recDtaQ();
      }
      myEmitter.emit('event', data);
  }); 
}

recDtaQ(); 

Here is the RPG portion. It was created so data queue entry data could be passed on the command line call.

app.rpgle

         // CRTDTAQ DTAQ(MYLIB/MYDQ) MAXLEN(10)
         // CRTBNDRPG PGM(MYLIB/APP) SRCSTMF('/home/aaron/nodejs_dataqueue/app.rpgle')

        ctl-opt main(main) dftactgrp(*no);

        dcl-pr snddtaq extpgm('QSNDDTAQ');
         dtqname   char(10)    const;
         dtqlib    char(10)    const;
         dtqlength packed(05)  const;
         dtqdata   char(32766) const options(*varsize);
        end-pr;

        dcl-proc main;
          dcl-pi *N extpgm; 
             input_value char(10) const;
          end-pi;
          snddtaq('MYDQ': 'MYLIB': 10: input_value);
        end-proc;

Run

Populate the data queue by calling the RPG program and provide an end if you want the Node.js to end.

CALL MYLIB/APP '1111111111'
CALL MYLIB/APP '2222222222'
CALL MYLIB/APP '3333333333'
CALL MYLIB/APP 'end       '

Now go into PASE (ssh or CALL QP2TERM) and invoke the Node.js app.

$ cd /home/aaron/nodejs_dataqueue
$ node app.js         
an event occurred! Received:1111111111
an event occurred! Received:2222222222
an event occurred! Received:3333333333
an event occurred! Received:end
$

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.