node-ssdp

repository·master·Indexed 43 days ago

https://github.com/diversario/node-ssdp

A Node.js implementation of the Simple Service Discovery Protocol (SSDP) version 4.0.1. It provides a Client class for discovering UPnP services via M-SEARCH requests and a Server class for advertising services on a network using NOTIFY messages.

Tokens
2.9K
Snippets
13
Records
15
Agent score
55%

What's inside node-ssdp

  1. Configure the SSDP Server

    master

    When instantiating new Server({...}), you can provide the following options:

    • location (String or Object): URL pointing to the service description. If an object, it can specify:
      • location.protocol (String): Defaults to http://.
      • location.port (Number).
      • location.path (String).
    • udn (String): Unique Device Name. Default: uuid:f40c2981-7329-40b7-8b04-27f187aecfb5.
    • allowWildcards (Boolean): Accept wildcards (*) in serviceTypes of M-SEARCH packets. Default: false.
    • interfaces (String[]): List of interfaces to explicitly bind. Defaults to all available interfaces.
    • explicitSocketBind (Boolean): Bind sockets to each discovered interface explicitly. Useful for multiple NICs.
    • customLogger (Function): A custom logger function.
    • suppressRootDeviceAdvertisements (Boolean): If true, the server will not advertise the root device (bare UDN). Default: false.
    • reuseAddr (Boolean): If true, socket.bind() will reuse the address. Default: true.
    • adInterval (Number): Frequency of advertise events in ms. Default: 10000 (10 sec).
    • ttl (Number): Packet TTL. Default: 1800.
    const Server = require('node-ssdp').Server
    const server = new Server({...})
  2. Configure the SSDP Client

    master

    When instantiating new Client({...}), you can provide the following options:

    • interfaces (String[]): List of interfaces to explicitly bind. Defaults to all available interfaces.
    • explicitSocketBind (Boolean): If true, binds sockets to each discovered interface explicitly. Useful for systems with multiple NICs.
    • customLogger (Function): A custom logger function. The first argument can contain a format string.
    • reuseAddr (Boolean): If true, socket.bind() will reuse the address even if another process has bound it. Default: true.
    const Client = require('node-ssdp').Client
    const client = new Client({...})
  3. Enable logging via DEBUG environment variable

    master

    You can enable logging by setting the DEBUG environment variable.

    • To enable all logs: DEBUG=node-ssdp:*
    • To enable only client logs: DEBUG=node-ssdp:client
    • To enable only server logs: DEBUG=node-ssdp:server

    Note: If you provide a customLogger function in the configuration, the DEBUG environment variable will be ignored.

  4. Use the SSDP Server to advertise services

    master

    The Server class allows you to advertise your own UPnP services on the network.

    1. Instantiate the Server.
    2. Use server.addUSN(usn) to add Unique Service Names (USNs) to the server.
    3. Listen for advertise-alive and advertise-bye events to manage device state/cache.
    4. Call server.start() to begin advertising.
    5. Call server.stop() when shutting down to advertise the shutdown and stop listening.
    var Server = require('node-ssdp').Server
      , server = new Server()
    ;
    
    server.addUSN('upnp:rootdevice');
    server.addUSN('urn:schemas-upnp-org:device:MediaServer:1');
    server.addUSN('urn:schemas-upnp-org:service:ContentDirectory:1');
    server.addUSN('urn:schemas-upnp-org:service:ConnectionManager:1');
    
    server.on('advertise-alive', function (headers) {
      // Expire old devices from your cache.
      // Register advertising device somewhere (as designated in http headers heads)
    });
    
    server.on('advertise-bye', function (headers) {
      // Remove specified device from cache.
    });
    
    // start the server
    server.start();
    
    process.on('exit', function({
      server.stop() // advertise shutting down and stop listening
    })
  5. Use the SSDP Client to search for services

    master

    The Client class allows you to discover UPnP services on the network by sending M-SEARCH requests. You can listen for the response event to handle discovered services.

    To search for a specific service type, use client.search(serviceType). To discover all services on the network, use client.search('ssdp:all').

    var Client = require('node-ssdp').Client
      , client = new Client();
    
    client.on('response', function (headers, statusCode, rinfo) {
      console.log('Got a response to an m-search.');
    });
    
    // search for a service type
    client.search('urn:schemas-upnp-org:service:ContentDirectory:1');
    
    // Or get a list of all services on the network
    client.search('ssdp:all');
  6. Configure SSDP protocol settings

    master

    The following settings control the underlying SSDP protocol behavior:

    • ssdpSig (String): SSDP signature. Default: node.js/NODE_VERSION UPnP/1.1 node-ssdp/PACKAGE_VERSION.
    • ssdpIp (String): SSDP multicast group. Default: 239.255.255.250.
    • ssdpPort (Number): SSDP port. Default: 1900.
    • ssdpTtl (Number): Multicast TTL. Default: 4.
  7. Use SsdpServer to advertise services

    master

    The SsdpServer class is used to create an SSDP server that advertises services on a network via UDP. It manages a background advertisement loop that periodically sends NOTIFY messages (typically alive or bye notifications) to let other devices know about available services.

    Key Methods

    • start([callback]): Binds the UDP socket to the configured interface/port and begins the advertisement loop. Returns a Promise that resolves when the socket is ready. If a callback is provided, it is called with the result of the socket bind.
    • stop(): Shuts down the server, stops the advertisement loop, and closes the UDP socket. It sends a bye advertisement before closing.
    • advertise(alive): Manually triggers an advertisement.
      • Passing true (or omitting the argument) sends an alive notification.
      • Passing false sends a bye notification.

    Important Configuration Note

    If you set the sourcePort option to a value other than the default SSDP port, the server will likely not receive any incoming messages. It is highly recommended to use the default SSDP port.

    const SsdpServer = require('node-ssdp/lib/server');
    
    const server = new SsdpServer({
      // options inherited from SSDP
    });
    
    server.start()
      .then(() => {
        console.log('Server started and advertising');
      })
      .catch((err) => {
        console.error('Failed to start server:', err);
      });
    
    // To stop the server later
    // server.stop();
  8. Use SsdpClient to discover services

    master

    The SsdpClient class is used to send SSDP M-SEARCH requests to discover devices on the network. It inherits from the base SSDP class.

    To use it:

    1. Instantiate SsdpClient with your desired options.
    2. Call .start() to begin listening for multicast notifications.
    3. Call .search(serviceType) to send a discovery request for a specific service type (e.g., urn:schemas-upnp-org:service:renderer:1).
    4. Call .stop() to close the UDP socket and stop listening.

    Note: If you call .search() before the client has been started, the client will automatically call .start() for you.

    const SsdpClient = require('node-ssdp').Client;
    
    const client = new SsdpClient();
    
    // Start the client and search for a specific service type
    client.start().then(() => {
      client.search('urn:schemas-upnp-org:service:renderer:1');
    });
    
    // To stop the client later
    // client.stop();
  9. Start the SsdpClient listener

    master

    The .start([cb]) method initializes the UDP socket and begins listening for multicast notifications from SSDP devices.

    • Returns: A Promise that resolves when the socket is successfully bound. If the binding fails, the promise is rejected.
    • Callback: An optional callback cb that is executed when the binding process completes (receiving err as the first argument).
    client.start((err) => {
      if (err) {
        console.error('Failed to start client:', err);
      } else {
        console.log('Client started and listening.');
      }
    });
  10. Use the Base class for custom SSDP implementations

    master

    The Base class provides the underlying logic for both Client and Server implementations. It is exported as a top-level property of the module and can be used as a foundation for building custom SSDP-related functionality.

    const { Base } = require('node-ssdp');
    // Base is the foundation for Client and Server
  11. Use the Server class to announce services

    master

    The Server class is used to host an SSDP service, allowing other devices on the network to discover your application by sending search requests. It is exported as a top-level property of the module.

    const { Server } = require('node-ssdp');
    const server = new Server();