简体   繁体   中英

Restify res.send () not called inside event listener callback

I am using restify 2.8.4, nodejs 0.10.36 and IBM MQ Light messaging.

It is a RPC pattern, whenever the receiver has the result ready, it will emit an event and below restify POST route will capture the event and data, and reply with res.send () .

Issue is, res.send () is not trigger. And I don't understand why res.send () isn't being triggered. There is only one res.send () in this POST route.

Tried res.write () and res.end () . Same thing. Not triggered.

Any advice is much appreciated.

route.js

server.post ('/user', function (req, res, next) {
  var body = req.body;

  var recvClient = createRecv ();

  var sendClient = createSend (body);

  recvClient.on ("receiver:got:it", function () {
    // receiver has confirmed received message
    // so sender client can be released 
    console.log ('stopping send client...'.info);
    sendClient.stop ();
  });

  recvClient.on ("receiver:replied", function (data) {
    // event callback was triggered
    console.log ('receiver replied captured...');

    res.send ();
    return next ();
  });

});

receiver.js

recvClient.on('started', function() {
    recvClient.subscribe(topicPattern, {qos: 1, autoConfirm: false, credit: 1});

    recvClient.on('message', function(data, delivery) {
      console.log('Recv: ' + util.inspect (data, false, null));

      delivery.message.confirmDelivery (function () {
        recvClient.emit ('receiver:got:it'); 
      });

      var user = new User (data);     
      user.create ()           
      .then (function (user) { 
        recvClient.emit ('receiver:replied', user);
    }, function (err) {      
        recvClient.emit ('receiver:replied', {err: err.message});
    })
      .finally (function (){   
        console.log ('stopping receiver client...');
        recvClient.stop ();    
      });

    });
  });

Output trace

body: {}  //stuff here
Recv: {}  // receiver received body stuff
stopping send client...
// do work

receiver replied captured...
stopping receiver client...

Update 1

If I replace event emitter with another send/receive message queue from the receiver, res.send () is called.

This approach is messier than event emitter. I still refuse to believe why event emitter won't work.

var rpcReceive = new RpcReceive ("user.create.replied", {qos:1, autoConfirm: false, credit: 1});

rpcReceive.receive (recvClient)
.then (function (user){
  res.send (user);
  return next ();
})
.then (undefined, function (err){
  return next (new restify.errors.BadRequestError (err.message));
});

The problem looks like in the structure of route.js. Actually, recvClient.on event should not be dependent on server.post('/user'). Correct structure should be like:

var recvClient = createRecv ();     // should be global object

server.post ('/user', function (req, res, next) {
  var body = req.body;

  //var recvClient = createRecv ();     //commented out this code as this is moved out of this API.

  //var sendClient = createSend (body); //commented out this code. May be this wont be required.

});

recvClient.on ("receiver:got:it", function () {
    // receiver has confirmed received message
    // so sender client can be released 
    console.log ('stopping send client...'.info);
    //sendClient.stop ();       //commented out this code. May be this wont be required.
});

recvClient.on ("receiver:replied", function (data) {
    // event callback was triggered
    console.log ('receiver replied captured...');

    //res.send ();              
    //return next ();       

    /*commented out these two lines. Instead of sending response like this, emit some event from here, which can be consumed on receiver.js. Use something like below code to send response to receiver.js */
    recvClient.emit('sending:response', "response");
});

And your receiver.js should have below logic (in addition to your code) to receive response from route.js.

recvClient.on('sending:response', function(response) {
    // do processing on response
});

Please try this and response back in case you find issue. I have worked on similar logic to emit and consume events while creating chat application. Please let me know in case you still face problem.

您可以尝试使用res.json({'status':200})吗?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM