Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

-1

366
Vistas
Node.js: Long-polling with EventEmitter and Express 4.x | Catching request close

I'm long-polling node.js route with JQuery's ajax request (xhr). This sends a GET request to my Express server and listens for message bus events. I'm setting a timeout on that GET request (as my proxy would kill long requests). So after the timeout, an abort event should be sent by the client to the server.

I want to catch that abort/close/finish event and remove the relevant message bus listener/subscriber.

But I struggle. I tried req.on("close"..) and the on-finished npm module, but that didn't work for me. I'm also not much more clever after reading the http documentation of node: https://nodejs.org/api/http.html.

Any ideas how to tackle this beast? Or better ways to remove listeners to prevent memory leaks?

Server side essentials:

// server.js
var express = require("express");
var EventEmitter = require("events").EventEmitter;
var messageBus = new EventEmitter();
messageBus.setMaxListeners(20);

var REST_PORT = (process.env.PORT || 5000);
var app = express();

app.get("/events", (req, res) => {
    var listener = function(res) {
        messageBus.once("message", function(data) {
            res.status(200).json(data);
        });
    };
    req.on("abort", function() { //I tried also "aborted", "close", "closed", "finish", "finished"..no luck
        messageBus.removeListener("message", listener);
    });

    listener(res);
    console.log("Total listeners to 'message' events:", messageBus.listeners("message").length);
});

// other messageBus.emit logic ..

app.listen(REST_PORT, () => {
    console.log("Application ready on port " + REST_PORT);
});

Client side essentials:

//client.js
$.ajax({
    method: "GET",
    async: true,
    url: "/events",
    success: function(data) {
        callback(data);
    },
    complete: function(request, status, err) {
        if (status == "timeout" || status == "success") {
            console.log("LOG: Normal long-polling timeout or successful poll, continuing.");
            longPoll();
        } else {
            console.warn("WARN: Server probably offline, retrying in 2 sec.");
            setTimeout(function() {
                longPoll();
            }, 2000);
        }
    },
    timeout: 30000
});

Thank you!

about 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

If this helps someone, I finally decided to implement the long-polling differently and killing the client request at the server side after certain timeout. This works for me nicely and after reflection, is probably better mechanism than trusting the client to close the requests correctly.

setTimeout(() => {
    if (!responded) {
        messageBus.removeListener("message", listener);
        res.status(204).end();
    }
}, 30000);
about 4 years ago · Santiago Trujillo Denunciar

0

I recommend aborting your custom long-polling system altogether and using one of the existing messaging/socket-type systems. There are many that are fully formed. socket.io is the most popular still and works well, but some alternatives like these might be better https://www.reddit.com/r/node/comments/4ktqae/socketio_alternatives/

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda