dearn44
dearn44

Reputation: 3432

'Can't set headers after they are sent' error coming from zeromq

My nodejs app uses zeromq to communicate with the back-end. It generally works well but in the case where I restart the back-end while the app is running it will crash reporting the message below:

events.js:163
      throw er; // Unhandled 'error' event
      ^

Error: Can't set headers after they are sent.
    at ServerResponse.setHeader (_http_outgoing.js:371:11)
    at ServerResponse.header (/home/gl/Documents/client/node_modules/express/lib/response.js:592:10)
    at ServerResponse.send (/home/gl/Documents/client/node_modules/express/lib/response.js:144:12)
    at ServerResponse.json (/home/gl/Documents/client/node_modules/express/lib/response.js:233:15)
    at exports.Socket.<anonymous> (/home/gl/Documents/client/app/routes.js:13:12)
    at emitMany (events.js:127:13)
    at exports.Socket.emit (events.js:204:7)
    at exports.Socket.Socket._emitMessage (/home/gl/Documents/client/node_modules/zeromq/lib/index.js:640:15)
    at exports.Socket.Socket._flushRead (/home/gl/Documents/client/node_modules/zeromq/lib/index.js:651:10)
    at exports.Socket.Socket._flushReads (/home/gl/Documents/client/node_modules/zeromq/lib/index.js:687:15)

routes.js looks like this:

module.exports = function(app) {    
    var zmq = require('zeromq')
    , sock = zmq.socket('dealer');
    var response = null;

    sock.on('message', function(data) {
        response.json({data: data.toString()});
    });

    app.get('/data', function(req, res) {
        response = res;
        sock.send(['', 'low']);     
    });
};

This way once a message comes from the back-end it will be sent using the current response object. That's the simplest way I found to capture responses from zeromq and send back the response to my application.

What is causing that error to popup, and if it is due to the design of my code, is there a better way to integrate zeromq with my application so I send and receive messages asynchronously for the various functions of my application?

Upvotes: 0

Views: 75

Answers (1)

Quentin
Quentin

Reputation: 944442

You have two servers.

  • ZeroMQ
  • Express (or some other HTTP server … at least the use of app.get('/data', function(req, res) { gives that impression)

… they are both running from within the same Node.js application.


When the browser makes an HTTP request, it expects to get an HTTP response.

You are not sending an HTTP response when you get a request from the browser, you are sending it when you get a message over ZeroMQ.

As a result of this, you are trying to respond to the same HTTP request multiple times… which is impossible.


You need to rethink the architecture of your application.

Possibly you should be using something like Socket.IO so that you can push a message from the server to the browser whenever the server is ready to do so (instead of whenever an HTTP request asks for one).

Upvotes: 1

Related Questions