npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

msrp-node-lib

v0.2.0

Published

A complete MSRP (Message Session Relay Protocol) library for Node.js applications, supporting RFC 4975 message relay protocol with SDP integration

Downloads

87

Readme

MSRP Node.js Library

CI/CD Pipeline Test Coverage npm version npm downloads Node.js Version License: MIT PRs Welcome

A complete MSRP (Message Session Relay Protocol) library for Node.js applications, supporting RFC 4975 message relay protocol with SDP integration.

🚀 Features

  • Complete RFC 4975 Implementation - Full MSRP protocol support
  • SDP Integration - Session description handling
  • Multi-Process Testing - Advanced test infrastructure with real network communication

Installation

npm install msrp-node-lib

Quick Start

const msrp = require("msrp-node-lib")({
  host: "127.0.0.1", // IP to bind server to
  port: 2855,
  sessionName: "user-a",
  acceptTypes: "text/plain",
  setup: "active",
  // advertiseHost: 'public.ip.address' // Optional: IP to advertise in SDP
});

// Start the MSRP server
msrp.Server.start((err) => {
  if (err) {
    console.error("Error starting MSRP service:", err);
    return;
  }
  console.log("MSRP Service started");

  // Create a session
  const session = msrp.SessionController.createSession();

  // Handle connection
  session.on("socketSet", (session) => {
    console.log("Connected! Ready to send messages");
    session.sendMessage("Hello World!");
  });

  // Handle incoming messages
  session.on("message", (message) => {
    console.log("Received:", message.body);
  });
});

Configuration

The MSRP library accepts a configuration object with the following options:

Required Configuration

| Option | Type | Description | | ------------- | ------ | ----------------------------------------------------- | | host | String | IP address or hostname for the MSRP server to bind to | | port | Number | Port number for the MSRP server | | sessionName | String | Session name to use in SDP | | acceptTypes | String | MIME types accepted (e.g., 'text/plain') | | setup | String | Connection setup role: 'active' or 'passive' |

Optional Configuration

| Option | Type | Default | Description | | --------------------------------- | ------- | ------------ | --------------------------------------------------------- | | advertiseHost | String | host value | IP address/hostname to advertise in SDP and message paths | | traceMsrp | Boolean | false | Enable MSRP protocol tracing | | requestReports | Boolean | true | Request delivery reports for sent messages | | forceSetup | Boolean | false | Force use of specified setup attribute | | enableHeartbeats | Boolean | true | Enable heartbeat mechanism | | heartbeatsInterval | Number | 5000 | Heartbeat interval (ms) | | heartbeatsTimeout | Number | 10000 | Heartbeat timeout (ms) | | useInboundMessageForSocketSetup | Boolean | false | Use inbound messages for socket setup | | reuseOutboundPortOnReInvites | Boolean | true | Reuse outbound port for re-invites |

Timeout Configuration

| Option | Type | Default | Description | | ------------------------ | ------ | ------- | --------------------------------------- | | idleSocketTimeout | Number | 0 | Socket idle timeout (ms, 0 = disabled) | | socketConnectTimeout | Number | 0 | Connection timeout (ms, 0 = disabled) | | socketReconnectTimeout | Number | 0 | Reconnection timeout (ms, 0 = disabled) | | danglingSocketTimeout | Number | 20000 | Dangling socket cleanup timeout (ms) |

Port Range Configuration

| Option | Type | Default | Description | | --------------------- | ------ | ------- | ------------------------------------- | | outboundBasePort | Number | 49152 | Starting port for dynamic connections | | outboundHighestPort | Number | 65535 | Highest port for dynamic connections |

Host Configuration

The library supports separate binding and advertising addresses:

  • host - The IP address the server binds to (where it listens)
  • advertiseHost - The IP address advertised in SDP and MSRP message paths (where clients should connect)

Common Scenarios:

// Scenario 1: Simple local setup
const msrp = require("msrp-node-lib")({
  host: "127.0.0.1",
  port: 2855,
  // advertiseHost defaults to '127.0.0.1'
});

// Scenario 2: Behind NAT/firewall
const msrp = require("msrp-node-lib")({
  host: "192.168.1.100", // Internal IP to bind to
  advertiseHost: "203.0.113.10", // Public IP to advertise
  port: 2855,
});

// Scenario 3: Listen on all interfaces
const msrp = require("msrp-node-lib")({
  host: "0.0.0.0", // Bind to all interfaces
  advertiseHost: "192.168.1.100", // Specific IP to advertise
  port: 2855,
});

// Scenario 4: Auto-detect advertise address
const msrp = require("msrp-node-lib")({
  host: "0.0.0.0", // Bind to all interfaces
  // advertiseHost not set - library will auto-detect reachable IP
  port: 2855,
});

Note: When host is set to '0.0.0.0' and advertiseHost is not specified, the library will automatically determine the best network interface IP address to advertise instead of using '0.0.0.0'.

Custom Logger

You can provide a custom logger instead of using console:

const winston = require("winston");

const msrp = require("msrp-node-lib")(
  {
    host: "127.0.0.1",
    port: 2855,
    sessionName: "user-a",
    acceptTypes: "text/plain",
    setup: "active",
  },
  winston.createLogger({
    level: "debug",
    format: winston.format.simple(),
    transports: [new winston.transports.Console()],
  })
);

Events

All events are emitted by sessions and forwarded through the SessionController. You can listen to events on individual sessions or the SessionController itself.

Event Categories

Session Events

  • update - Session state updated
  • end - Session ended

Message Events

  • message - Incoming MSRP message received
  • messageSent - Outgoing message sent successfully
  • response - MSRP response received (for sent messages)
  • responseSent - MSRP response sent (for received messages)
  • report - Delivery report received
  • reportSent - Delivery report sent

Connection Events

  • socketSet - Socket connection established (ready to send messages)
  • socketClose - Socket connection closed
  • socketError - Socket error occurred

Timeout Events

  • socketConnectTimeout - Socket connection timeout
  • idleSocketTimeout - Socket idle timeout
  • socketReconnectTimeout - Socket reconnection timeout

Heartbeat Events

  • heartbeatFailure - Heartbeat mechanism failed
  • heartbeatTimeout - Heartbeat response timeout

Event Parameters

| Event | Parameters | Description | | ------------------------ | -------------------------------------- | ----------------------------- | | message | (message, session, encodedMessage) | Incoming MSRP message | | messageSent | (message, session, encodedMessage) | Outgoing message sent | | response | (response, session, encodedResponse) | MSRP response received | | responseSent | (response, session, encodedResponse) | MSRP response sent | | report | (report, session, encodedReport) | Delivery report received | | reportSent | (report, session, encodedReport) | Delivery report sent | | update | (session) | Session state updated | | end | (session) | Session ended | | socketSet | (session) | Socket connection established | | socketClose | (hadError, session) | Socket connection closed | | socketError | (session) | Socket error occurred | | socketConnectTimeout | (session) | Socket connection timeout | | idleSocketTimeout | (session) | Socket idle timeout | | socketReconnectTimeout | (session) | Socket reconnection timeout | | heartbeatFailure | (session) | Heartbeat mechanism failed | | heartbeatTimeout | (session) | Heartbeat response timeout |

Usage Examples

Basic Session Usage

const msrp = require("msrp-node-lib")({
  host: "127.0.0.1",
  port: 2855,
  sessionName: "user-a",
  acceptTypes: "text/plain",
  setup: "active",
});

// Start the server
msrp.Server.start((err) => {
  if (err) {
    console.error("Failed to start MSRP server:", err);
    return;
  }

  // Create a session
  const session = msrp.SessionController.createSession();

  // Set up event handlers
  session.on("socketSet", (session) => {
    console.log("Connected! Session ID:", session.sid);
    session.sendMessage("Hello World!");
  });

  session.on("message", (message, session) => {
    console.log("Received:", message.body);
    console.log("Content-Type:", message.contentType);
  });

  session.on("messageSent", (message, session) => {
    console.log("Message sent:", message.messageId);
  });

  session.on("socketClose", (hadError, session) => {
    console.log("Connection closed:", hadError ? "with error" : "normally");
  });
});

SDP Integration

MSRP sessions work with SDP (Session Description Protocol) for connection setup:

// Create a session for SIP call setup
const session = msrp.SessionController.createSession();

// Generate local SDP offer
const localSdp = session.getDescription();
console.log("Local SDP:", localSdp);

// When you receive remote SDP answer
const remoteSdp = `
v=0
o=user-b 789012 210987 IN IP4 192.168.1.100
s=user-b
c=IN IP4 192.168.1.100
t=0 0
m=message 2856 TCP/MSRP *
a=accept-types:text/plain
a=path:msrp://192.168.1.100:2856/session456;tcp
a=setup:passive
`;

try {
  session.setDescription(remoteSdp.trim());
  console.log("SDP negotiation complete");
} catch (error) {
  console.error("SDP error:", error);
}

SDP Setup Attributes

  • setup:active - This endpoint initiates the TCP connection
  • setup:passive - This endpoint waits for incoming connections
  • setup:actpass - This endpoint can be either active or passive

Server Management

// Start server
msrp.Server.start((err) => {
  if (err) console.error("Start error:", err);
  else console.log("Server started");
});

// Stop server
msrp.Server.stop(() => {
  console.log("Server stopped");
});

// Graceful shutdown
process.on("SIGINT", () => {
  msrp.Server.stop(() => process.exit(0));
});

API Reference

Session Methods

const session = msrp.SessionController.createSession();

// Send a message
session.sendMessage("Hello World!", (error) => {
  if (error) console.error("Send failed:", error);
  else console.log("Message queued");
});

// Get local SDP description
const sdp = session.getDescription();

// Set remote SDP description
session.setDescription(remoteSdp);

// End the session
session.end();

SessionController Methods

// Create a new session
const session = msrp.SessionController.createSession();

// Get session by ID
const session = msrp.SessionController.getSession(sessionId);

// Get sessions by remote address
const sessions =
  msrp.SessionController.getSessionsByRemoteSocketAddress("192.168.1.100:2856");

// Remove a session
msrp.SessionController.removeSession(session);

Server Methods

// Start the server
msrp.Server.start((error) => {
  // Handle start result
});

// Stop the server
msrp.Server.stop(() => {
  // Handle stop completion
});

License

This project is licensed under the MIT License.