npm.io
1.0.3 • Published 9 months ago

express-longpoll

Licence
ISC
Version
1.0.3
Deps
3
Size
22 kB
Vulns
0
Weekly
0
Stars
33

Build Status npm version

Lightweight long polling module for express.js with TypeScript support.

Features

  • Simple API - Easy to set up and use
  • Promise-based - Modern async/await support
  • TypeScript - Full type definitions included
  • Production-ready - Used by 147+ projects
  • Express Router - Works with Express routers
  • Flexible - Publish to specific users or broadcast to all

Description

Sets up basic long poll with subscribe and publish functionality. Perfect for real-time updates without WebSockets.

Install

npm install express-longpoll

Quick Start

JavaScript
const express = require("express");
const app = express();
const longpoll = require("express-longpoll")(app);

// Create endpoint
await longpoll.create("/events");

// Publish data
await longpoll.publish("/events", { message: "Hello!" });
TypeScript
import express from "express";
import expressLongPoll from "express-longpoll";

const app = express();
const longpoll = expressLongPoll(app, { DEBUG: true });

await longpoll.create("/events", { maxListeners: 100 });
await longpoll.publish("/events", { message: "Hello!" });

Usage

Basic initalization

var express = require("express");
var app = express();
var longpoll = require("express-longpoll")(app);
// You can also enable debug flag for debug messages
var longpollWithDebug = require("express-longpoll")(app, { DEBUG: true });

Quick-start code

Server - server.js

var express = require("express");
var app = express();
var longpoll = require("express-longpoll")(app);

// Creates app.get("/poll") for the long poll
longpoll.create("/poll");

app.listen(8080, function () {
    console.log("Listening on port 8080");
});

var data = { text: "Some data" };

// Publishes data to all clients long polling /poll endpoint
// You need to call this AFTER you make a GET request to /poll
longpoll.publish("/poll", data);

// Publish every 5 seconds
setInterval(function () {
    longpoll.publish("/poll", data);
}, 5000);

Client - index.js (with jQuery)

var poll = function () {
    $.ajax({
        url: "localhost:8080/poll",
        success: function (data) {
            console.log(data); // { text: "Some data" } -> will be printed in your browser console every 5 seconds
            poll();
        },
        error: function () {
            poll();
        },
        timeout: 30000 // 30 seconds
    });
};

// Make sure to call it once first,
poll();
longpoll.create(url, [options])

Sets up an express endpoint using the URL provided.

var longpoll = require("express-longpoll")(app);

longpoll.create("/poll");
longpoll.create("/poll2", { maxListeners: 100 }); // set max listeners

Options:

  • maxListeners (number): Maximum number of listeners. Default: 0 (unlimited, disables EventEmitter warnings). Set to a specific number if you want to limit concurrent connections. Fixes Issue #12.
longpoll.create(url, middleware, [options])

Set up an express endpoint using the URL provided, and use middleware.

var longpoll = require("express-longpoll")(app);

longpoll.create("/poll", function (req, res, next) {
    // do something
    next();
});
longpoll.publish(url, data)

Publishes data to all listeners on the url provided.

var express = require("express");
var app = express();
var longpoll = require("express-longpoll")(app);

longpoll.create("/poll");

longpoll.publish("/poll", {});
longpoll.publish("/poll", { hello: "Hello World!" });
longpoll.publish("/poll", jsonData);
longpoll.publishToId(url, id, data)

Publish data to a specific request. See the basic example on how to use this effectively.

Works with Routers

var express = require("express");
var router = express.Router();
// with router
var longpoll = require("express-longpoll")(router);

longpoll.create("/routerpoll");

router.get("/", (req, res) => {
    longpoll.publish("/routerpoll", {
        text: "Some data"
    });
    res.send("Sent data!");
});

module.exports = router;

Can publish to any endpoint, from anywhere.

server.js - create here

var longpoll = require("express-longpoll")(app);
longpoll.create("/poll");

route.js - use here

var longpoll = require("express-longpoll")(router);
// Can publish to any endpoint
longpoll.publish("/poll");

Using Promises

longpoll
    .create("/poll")
    .then(() => {
        console.log("Created /poll");
    })
    .catch((err) => {
        console.log("Something went wrong!", err);
    });

longpoll
    .publish("/poll", data)
    .then(() => {
        console.log("Published to /poll:", data);
    })
    .catch((err) => {
        console.log("Something went wrong!", err);
    });

Sample clientside code to subscribe to the longpoll

Client using jQuery
var subscribe = function (url, cb) {
    $.ajax({
        method: "GET",
        url: url,
        success: function (data) {
            cb(data);
        },
        complete: function () {
            setTimeout(function () {
                subscribe(url, cb);
            }, 1000);
        },
        timeout: 30000
    });
};

subscribe("/poll", function (data) {
    console.log("Data:", data);
});

subscribe("/poll2", function (data) {
    console.log("Data:", data);
});

Live Demo

Check out the Collaborative Mouse Tracker demo in the examples/ folder - a stunning real-time application showcasing express-longpoll capabilities:

  • Real-time cursor tracking across multiple browser tabs
cd examples/collaborative-mouse-tracker
npm install
npm start
# Open http://localhost:3006 in multiple tabs

API Reference

longpoll.create(url, [middleware], [options])

Creates a long-poll endpoint.

Options:

  • maxListeners (number): Maximum number of listeners. Default: 0 (unlimited, disables EventEmitter warnings). Set to a specific number if you want to limit concurrent connections. Fixes Issue #12.

Returns: Promise<void>

longpoll.publish(url, data)

Publishes data to all listeners on the endpoint.

Returns: Promise<void>

longpoll.publishToId(url, id, data)

Publishes data to a specific listener by ID.

Returns: Promise<void>

Testing

express-longpoll has comprehensive test coverage:

npm test

Test Results:

  express-longpoll - Additional Tests
    Error Handling
      ✔ should reject when creating duplicate URL
      ✔ should reject when publishing to non-existent URL
      ✔ should reject when publishing to ID on non-existent URL
    maxListeners Option
      ✔ should set maxListeners when option is provided
      ✔ should handle multiple concurrent connections with maxListeners
    Middleware Support
      ✔ should support middleware function
      ✔ should support middleware with options
    publishToId
      ✔ should publish to specific user ID
    Router Support
      ✔ should work with Express Router
    Promise API
      ✔ should resolve promise on successful create
      ✔ should resolve promise on successful publish
      ✔ should support async/await syntax
    Debug Mode
      ✔ should enable debug logging when DEBUG is true
      ✔ should not log when DEBUG is false
    Data Types
      ✔ should handle object data
      ✔ should handle array data
      ✔ should handle string data
      ✔ should handle null data

  express-longpoll
    longpoll.create(url, data)
      ✔ should create a .get express endpoint
    longpoll.publish(url, data)
      ✔ should publish data to all requests listening on a url
      ✔ should publish data to all clients requests listening on a url

  21 passing (5s)

Best Practices

  • Set maxListeners to prevent memory leaks in production
  • Use DEBUG: true during development for helpful logs
  • Implement proper error handling with .catch()
  • Consider timeout values based on your use case (typically 30-60 seconds)

Changelog

See CHANGELOG.md for version history.

License

ISC

Keywords