Giter Site home page Giter Site logo

node-ssdp's Introduction

Build Status Coverage Status Dependency Status NPM version

Installation

npm install node-ssdp

There is another package called ssdp which is the original unmaintained version. Make sure to install node-ssdp instead.

Usage - Client

    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');

Usage - Server

    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
    })

Take a look at example directory as well to see examples or client and server.

Configuration

Client

const Client = require('node-ssdp').Client
const client = new Client({...})
  • interfaces String[] List of interfaces to explicitly bind. By default, bind to all available interfaces.
  • explicitSocketBind Boolean Bind sockets to each discovered interface explicitly instead of relying on the system. Might help with issues with multiple NICs.
  • customLogger Function A logger function to use instead of the default. The first argument to the function can contain a format string.
  • reuseAddr Boolean When true socket.bind() will reuse the address, even if another process has already bound a socket on it. Default: true

Server

const Server = require('node-ssdp').Server
const server = new Server({...})
  • location String URL pointing to description of your service, or a function which returns that URL
  • location Object For cases where there are multiple network interfaces or IP of the host isn't known in advance, it's possible to specify location as an object. Host will be set to the IP of the responding interface.
    • location.protocol String Location protocol, defaults to http://
    • location.port Number Location port. No default.
    • location.path String Location path. No default.
  • udn String Unique Device Name. Default: uuid:f40c2981-7329-40b7-8b04-27f187aecfb5.
  • allowWildcards Boolean Accept wildcards (*) in serviceTypes of M-SEARCH packets, e.g. usn:Belkin:device:**. Default: false
  • interfaces String[] List of interfaces to explicitly bind. By default, bind to all available interfaces.
  • explicitSocketBind Boolean Bind sockets to each discovered interface explicitly instead of relying on the system. Might help with issues with multiple NICs.
  • customLogger Function A logger function to use instead of the default. The first argument to the function can contain a format string.
  • suppressRootDeviceAdvertisements Boolean When true the SSDP server will not advertise the root device (i.e. the bare UDN). In some scenarios this advertisement is not needed. Default: false
  • reuseAddr Boolean When true socket.bind() will reuse the address, even if another process has already bound a socket on it. Default: true
  • adInterval Number advertise event frequency (ms). Default: 10 sec.
  • ttl Number Packet TTL. Default: 1800.

SSDP configuration:

  • 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

Logging

You can enable logging via an environment variable DEBUG. Set DEBUG=node-ssdp:* to enable all logs. To enable only client or server logs, use DEBUG=node-ssdp:client or DEBUG=node-ssdp:server respectively.

Alternatively, you can provide your own customLogger function, in which case the DEBUG environment variable will be ignored.

License

(The MIT License)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Analytics

node-ssdp's People

Contributors

aleno avatar andrewshatnyy avatar axit-joost avatar bryant1410 avatar dhleong avatar diversario avatar driskell avatar feross avatar hchho avatar mlehman avatar mnkhouri avatar mrose17 avatar muka avatar oeuillot avatar scottmadinsonos avatar sherwinliu avatar sherwinliusonos avatar waffle-iron avatar wagmarcel avatar yaronyg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-ssdp's Issues

Why no notify event for the client?

Hi,

in my understanding (maybe I'm wrong) of the UPnP specifications, a client, which is the control point, should be able to listen to ssdp:alive, ssdp:byebye and ssdp:update notifications from devices. In the /example/client.js there is such a "notify" event, which is, however, never be emitted?
Looking at the code, in the method SSDP.prototype._notify such events are handled.
So why does the following not work?

var SSDP = require('node-ssdp').Client;
var client = new SSDP();

client.on('advertise-alive', function (headers, rinfo) {
  console.log(headers);
  console.log(rinfo);
});

client.on('advertise-bye', function (headers, rinfo) {
  console.log(headers);
  console.log(rinfo);
});

Thanks!

Crash when starting without network connection

lib/index.js:146 self.sock.addMembership(self._ssdpIp) throws an error with code ENODEV, if there is no multicast interface available, for example if a device is not connected to any network. The uncaught exception crashes the application using node-ssdp.

It would be preferable to catch that error and retry later, so that the functionality could be restored, when the network connection becomes available.

A related issue is that currently the "location" option has to be specified when the node-ssdp server starts. It should be possible to make it dynamic, so that it could contain the current IP of the device, rather than be limited to the IP specified on startup.

Terminology: server.on('advertise-{alive, bye}') for device?

I need some clarification in the terminology.

In UPnP standard, the control point ("client") sends M-SEARCH broadcasts and the device ("server") sends NOTIFY announcements.

In this node-ssdp context, the control point is the "client", and it must respond to "advertise-alive" and "advertise-bye" messages. Why is this method available in the device (or "server in node-ssdp)?

Shouldn't the following logic exist in the control point ("client")?

server.on('advertise-alive', function (heads) {
  //console.log('advertise-alive', heads)
  // Expire old devices from your cache.
  // Register advertising device somewhere (as designated in http headers heads)
})

server.on('advertise-bye', function (heads) {
  //console.log('advertise-bye', heads)
  // Remove specified device from cache.
})

Uncaught error when running on machine with no active network

When running discovery on a machine that currently has no active network (e.g. moved out of wifi range) then I get the following error:

TypeError: Cannot read property 'addMembership' of null
at addMembership [as _onTimeout] (/home/hardillb/.node-red/node_modules/node-red-node-wemo/node_modules/node-ssdp/lib/index.js:183:18)
at Timer.listOnTimeout (timers.js:92:15)

It looks like there is a test wrapped round the addMembership call but no check to see if _createSocket returns null.

M-Search Host header

The spec says the Host header must be 239.255.255.250:1900, but the default config of node-ssdp sends 0.0.0.0:1900 the first time, but the next messages (as seen by TRACE logging) send the correct host.

screen shot 2014-06-07 at 10 52 32 am

Conflict with Samsung AllShare

I'm using node-ssdp to check for MediaRenderer with:

client.search('urn:schemas-upnp-org:device:MediaRenderer:1');

This works great in all cases except when I have Samsung AllShare Agent opened, it seems it creates some conflict as when it is open client.on('response') is never triggered.

I checked the console log, there are no JS errors of any kind. Any thoughts on why this scenario could be an issue for node-ssdp? (I know Samsung AllShare also uses upnp/dlna to share folders and stream to the TV)

require('./lib-cov/server'), etc... on index.js

On index.js there are 3 require('./lib-cov/*') but lib-cov folder is not present in the source code.
Is it sufficient to copy lib folder (and all his content) as lib-cov or modify the index.js to include directly the 3 lib files?

Use nodeip library to compute the hostname

Upnpserver fails to communicate with upnp clients with some Ubuntu installation !

It seems that:

    dns.lookup(os.hostname(), function (err, add) {
      self._httphost = 'http://' + add + ':' + portno
      bind()
    })

returns 127.0.0.1 and not the right IP !

I propose to use:

var ip = require('ip');
 httphost =ip.address();

it works on systems I have access. (Windows/Linux)

Regards,

OSX Mavericks Issue

I am running the same client code on a debian box and osx mavericks. The code works on the debian box but on the OSX machine 'client.on("response"..) is not triggered. It appears from stack trace that client is receiving data.

Client code:

var SSDP = require('node-ssdp').Client;
var client = new SSDP({logLevel: 'TRACE'});
client.on('notify', function () {
    console.log('Got a notification.');
});
client.on('response', function inResponse(header, code, rinfo) {
    console.log('Got a response to an m-search.');
});
client.search('urn:schemas-upnp-org:service:ContentDirectory:1');
// Or maybe if you want to scour for everything
client.search('ssdp:all');

Snippet client trace output on osx machine:

[2014-07-04T18:51:01.929Z] TRACE: ssdp/28208 on Colins-MacBook-Pro-2.local(/Users/colinbes/coding/node/ssdp/node_modules/node-ssdp/lib/index.js:164 in SSDP._parseMessage): Multicast message
    message: 
    NOTIFY * HTTP/1.1
    HOST: 239.255.255.250:1900
    NT: uuid:f40c2981-7329-40b7-8b04-27f187aecfb5
    NTS: ssdp:alive
    USN: uuid:f40c2981-7329-40b7-8b04-27f187aecfb5
    LOCATION: http://192.168.1.141/desc.html
    CACHE-CONTROL: max-age=1800
    SERVER: node.js/0.10.26 UPnP/1.1 node-ssdp/2.0.1

On debian box, I get out from 'response' trigger.

I am running node 0.10.26 on osx machine and 0.10.25 on debian machine.

package.json is:

{
  "name": "ssdp",
  "version": "0.0.1",
  "description": "SSDP test server",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-ssdp": "^2.0.1"
  }
}

Incompatible with Mac OS Mavericks

As far as I guess the code should have no compatibility issue, an update to package.json should fix this.

Log dump:

npm ERR! notsup Valid OS:    linux,windows,mac
npm ERR! notsup Valid Arch:  any
npm ERR! notsup Actual OS:   darwin
npm ERR! notsup Actual Arch: x64

SsdpClient does not have a stop()

Currently, the SsdpClient does not expose a stop() method. So if one wants to scan for devices for 10 seconds and then stop, the only way you can do that now is to do a setTimeout() and call process.exit(); rendering the use of the SsdpClient limited to only command line tools.

SSDP does have a private _stop() method, which SsdpClient does not use. Is that due to the fact that its original intended functionality is to be used by SsdpServer to stop advertising and unbinding the socket?

Server.start needs to return promise or accept a callback

There is no way to say when servers stars listening. Which makes tests depended on timeouts.

// when server.start takes a callback
describe('Client Server', (done) => {
  const server = new Server(options);
  server.start(done);
});

or with promise (preferred) which is yieldable

// when server.start returns a `new Promise()`
describe('Client Server', function* cs() {
  const server = new Server(options);
  yield server.start();
});

Please let me know if anyone needs this and which is more useful. I'd patch the server gladly.

nodejs v12

Does this need to be updated for v12 of nodejs?

Extra advert?

When I start a node-ssdp server and log all the headers during the advertise-alive event, I see two adverts from my local machine:

var server = new Server()
server.addUSN('my-service-type')
server.start()

server.on('advertise-alive', function (headers) {
  console.info(headers)
})

Results in:

{
  HOST: '239.255.255.250:1900',
  NT: 'my-service-type',
  NTS: 'ssdp:alive',
  USN: 'uuid:f40c2981-7329-40b7-8b04-27f187aecfb5::my-service-type',
  LOCATION: 'http://10.1.83.55:10293/upnp/desc.html',
  'CACHE-CONTROL': 'max-age=1800',
  SERVER: 'node.js/0.12.6 UPnP/1.1 node-ssdp/2.2.2'
}
{
  HOST: '239.255.255.250:1900',
  NT: 'uuid:f40c2981-7329-40b7-8b04-27f187aecfb5',
  NTS: 'ssdp:alive',
  USN: 'uuid:f40c2981-7329-40b7-8b04-27f187aecfb5',
  LOCATION: 'http://10.1.83.55:10293/upnp/desc.html',
  'CACHE-CONTROL': 'max-age=1800',
  SERVER: 'node.js/0.12.6 UPnP/1.1 node-ssdp/2.2.2'
}

I would expect to only see the USN I specified advertised. I think this is because server.js adds it's UDN to it's list of UPNs.

Was this done on purpose? Would you be amenable to a PR that changes it to give the user a bit more control over what's advertised?

A better way to set LOCATION

SsdpServer.prototype.start = function (ipAddress, portno, socket) {

ipAddress and portno are both used to construct LOCATION header but ipAddress is also used for socket binding. It doesn't have to be the same ip:port pair, so maybe move this out to config or something.

"notify" event doesn't exist?

In the README, it says:

client.on('notify', function () {
  console.log('Got a notification.');
});

I was wondering what a notification is, so I tried looking for "notify" in index.js, and didn't find emit for it.

Should the example be changed to use "advertise-alive" and "advertise-bye"?

the package has disappeared from the npm repository!

fyi - i tried an 'npm install -l node-ssdp' yesterday and it said:

mrose% npm -l install node-ssdp
npm http GET https://registry.npmjs.org/node-ssdp
npm http 404 https://registry.npmjs.org/node-ssdp
npm ERR! 404 'node-ssdp' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it
npm ERR! 404
npm ERR! 404 Maybe try 'npm search ssdp'
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, or http url, or git url.

npm ERR! System Darwin 12.3.0
npm ERR! command "/Users/mrose/.nvm/v0.8.20/bin/node" "/Users/mrose/.nvm/v0.8.20/bin/npm" "-l" "install" "node-ssdp"
npm ERR! cwd /private/tmp
npm ERR! node -v v0.8.20
npm ERR! npm -v 1.2.11
npm ERR! code E404
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /private/tmp/npm-debug.log
npm ERR! not ok code 0

mrose% npm search node-ssdp
npm http GET https://registry.npmjs.org/-/all/since?stale=update_after&startkey=1366477186032
npm http 200 https://registry.npmjs.org/-/all/since?stale=update_after&startkey=1366477186032
No match found for "node-ssdp"

Remove `bunyan` dependency

Hi there! Excellent package – thanks for the good work.

We use this in webtorrent and peerflix and there's been one repeated issue that keeps coming up.

Some users don't have compiler toolchains installed on their machines, so they get huge ugly error warnings when trying to install anything that depends on node-ssdp since it uses bunyan (which has a native dependency on dtrace-provider).

It's nice that you've used optionalDependencies so the installation won't fail entirely, but it's still terrible UX for inexperienced users. Seeing a wall of errors makes them think that their installation has failed, even when it has not.

For this reason, I think we should aggressively avoid native dependencies wherever possible. Even more so, when the native dependencies have nothing to do with the main purpose of the package.

bunyan is just a logger, so it seems silly to have all of this trouble for a logging utility when we could just use one that's pure javascript and avoid the trouble all together. There are simpler, lighter weight loggers that we could use. I'm a fan of debug but anything without a native dependency is just fine. πŸ‘

Another reason to get rid of bunyan is how much of the production dependency tree is devoted to it. All the packages with ** in front of them are installed for bunyan.

[email protected] /Users/feross/code/test
└─┬ [email protected]
**  β”œβ”€β”¬ [email protected]
**  β”‚ β”œβ”€β”¬ [email protected]
**  β”‚ β”‚ └── [email protected]
**  β”‚ β”œβ”€β”¬ [email protected]
**  β”‚ β”‚ β”œβ”€β”¬ [email protected]
**  β”‚ β”‚ β”‚ └── [email protected]
**  β”‚ β”‚ β”œβ”€β”€ [email protected]
**  β”‚ β”‚ └─┬ [email protected]
**  β”‚ β”‚   └─┬ [email protected]
**  β”‚ β”‚     β”œβ”€β”¬ [email protected]
**  β”‚ β”‚     β”‚ └── [email protected]
**  β”‚ β”‚     β”œβ”€β”€ [email protected]
**  β”‚ β”‚     β”œβ”€β”¬ [email protected]
**  β”‚ β”‚     β”‚ └─┬ [email protected]
**  β”‚ β”‚     β”‚   β”œβ”€β”€ [email protected]
**  β”‚ β”‚     β”‚   └── [email protected]
**  β”‚ β”‚     β”œβ”€β”¬ [email protected]
**  β”‚ β”‚     β”‚ └── [email protected]
**  β”‚ β”‚     └── [email protected]
**  β”‚ └── [email protected]
**  β”œβ”€β”€ [email protected]
**  β”œβ”€β”€ [email protected]
  └── [email protected]

An install script, native compilation, and 22 dependencies is just too high of a cost for a logging utility.

I'm happy to send a PR to use debug if you're interested. Cheers! πŸ‘

SSDP Client doesn't find Server advertise

I've implemented a server/client implementation of node-ssdp using the examples provided. Everything "appears" to work but my client does not pick up the server's packet. I get a lot of different payloads from different devices/locations but not the payload from my node-ssdp server.

I'm running on the same machine and I'm running on OSX. I have two separate node projects: one for my client and one for my server.

I've also verified that the server is actually broadcasting by running:
sudo tcpdump -i en0 -s 0 -B 524288 -w ~/Desktop/DumpFile01.pcap
and then reading the info by
tcpdump -s 0 -n -e -x -vvv -r ~/Desktop/DumpFile01.pcap

Any suggestions? Is it possible that I can't run the server and client on the same machine?

Here are my implementations just in case I messed something up:
Server

var SSDP = require('node-ssdp').Server
  , server = new SSDP({
    //unicastHost: '192.168.11.63',
    location: 'http://' + require('ip').address() + ':33333',
    ssdpPort: 33333
  })
console.log(require('ip').address())
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 (heads) {
  console.log('advertise-alive', heads)
  // Expire old devices from your cache.
  // Register advertising device somewhere (as designated in http headers heads)
})

server.on('advertise-bye', function (heads) {
  console.log('advertise-bye', heads)
  // Remove specified device from cache.
})

// start server on all interfaces
console.log('starting ssdp server')
server.start()

Client

var ssdp = require('node-ssdp').Client
  , client = new ssdp({
//    unicastHost: '192.168.11.63'
  })

client.on('notify', function () {
  //console.log('Got a notification.')
})

client.on('response', function inResponse(headers, code, rinfo) {
  console.log('Got a response to an m-search:\n%d\n%s\n%s', code, JSON.stringify(headers, null, '  '), JSON.stringify(rinfo, null, '  '))
})

client.search('ssdp:all')

// Or maybe if you want to scour for everything after 5 seconds
/*setTimeout(function() {
  client.search('ssdp:all')
}, 5000)*/

// And after 10 seconds, you want to stop
setTimeout(function () {
  client.stop()
}, 10000)

Server can't be started after it has been stopped

The issue can be reproduced with the following code:

var Server = require('./index.js').Server;
var server = new Server();
server.start();
// The stop can't be called immediately after
// start so a timeout is needed before calling stop.
setTimeout(function () {
  server.stop();
  server.start();
}, 500);

The expected behavior would be that the server can be started again, but instead an error like below is seen:

TypeError: Cannot read property 'on' of null

Fix README.md

Replace

var ssdp = require('../')

by

var ssdp = require('node-ssdp')

in README.md :-P

Exception while stoping

The advertise() checks this.sock, but stop() does not null it.

SSDP.prototype.advertise = function (alive) {
  var self = this

  if (!this.sock) return
  if (alive === undefined) alive = true
...
SSDP.prototype.stop = function () {
  this.advertise(false)
  this.advertise(false)
  this.sock.close()
  this.sock = null  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< changes
}

can't receive any response message on the client

I'm writing a client to get my TV server, and i can't get any response message.
So i try to run the example instead.

  1. the server.js works fine.
  2. the client.js just exit after some time , even i commented the client.stop(), no response message either.

can any one help on this, thanks .

Not getting "response" event

Hi,
I am having troubles getting the "response" event on the client
I am doing a search on the client

var client = new Client({customLogger: logx});
client.search('urn:schemas-upnp-org:device:MediaRenderer:1');

client.on('notify', function () {
  console.log('Got a notification.')
})

client.on('response', function inResponse() {
    console.log('response');
})

client.on('advertise-alive', function inResponse() {
    console.log('advertise-alive');
})

client.on('advertise-bye', function inResponse() {
    console.log('advertise-bye');
})

client.on('m-search', function inResponse() {
    console.log('m-search');
})

and the log i am getting is this one

SSDP listening: %o  {"address":"http://0.0.0.0:1900","interface":"192.168.56.1"}
SSDP listening: %o  {"address":"http://0.0.0.0:1900","interface":"10.0.0.4"}
Sending an M-SEARCH request  undefined
Sent M-SEARCH request: %o  {"message":"M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nST: urn:schemas-upnp-org:device:MediaRenderer:1\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\n\r\n"}
SSDP M-SEARCH event: %o  {"ST":"urn:schemas-upnp-org:device:MediaRenderer:1","address":"10.0.0.4","port":1900}
SSDP M-SEARCH event: %o  {"ST":"urn:schemas-upnp-org:device:MediaRenderer:1","address":"10.0.0.4","port":1900}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":38182}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":38182}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":38182}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":38182}
SSDP M-SEARCH event: %o  {"ST":"ssdp:all","address":"10.0.0.111","port":53319}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":54712}
SSDP M-SEARCH event: %o  {"ST":"upnp:rootdevice","address":"10.0.0.111","port":54712}

So it seems that i am getting 2 Media Renderers Search events which should trigger the "response" event? But the response is nerver been called?
What i am doeing wrong? I tried several branches and the current stable package. All behave a little bit different.

I have a Virtual Ethernet Adapter. If i am deactivating this adapter the problem persists.
Any Idea?

Config to turn off debugging

The debugging is really annoying and there is no flag to turn it off. Right now I have to do this

var client = new ssdp();

var noop = function(){};
var fakeLogger = {
    error: noop,
    warning: noop,
    notice: noop,
    info: noop
};
client.logger = fakeLogger;

SSDP server does not respond to mutlicast M-SEARCH requests

Hi,

I am hoping to use node-ssdp server to advertise a custom UPnP-like device on my network. I've got it up and running and I can see that it is sending out multicast SSDP advertisements as expected. However, I also need it to be able to respond to multicast M-SEARCH requests too. Here, it falls down (or at least, there is no documentation explaining how to enable it).

My setup:

var ssdpServer  = require('node-ssdp').Server;
ssdp = new ssdpServer({
    location: require('ip').address() + '/desc.xml'
});
ssdp.addUSN('urn:codersaur-com:device:DeviceType:1');
ssdp.start();

A typical M-SEARCH multicast request (sent from a client):

M-SEARCH * HTTP/1.1 
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 4
ST: codersaur-com:device:DeviceType:1

Doing some debugging, I can see that the ssdpServer is simply ignoring multicast packets.

Following the advice here it seems the solution is to bind the socket to the multicast port (i.e. 1900) only. I have been able to do this by specifying the sourcePort in the configuration parameters to be the same, i.e.:

var ssdpServer  = require('node-ssdp').Server;
ssdp = new ssdpServer({
    location: require('ip').address() + '/desc.xml',
    sourcePort: 1900,
});
ssdp.addUSN('urn:codersaur-com:device:DeviceType:1');
ssdp.start();

The SSDP server now binds to address: 'http://0.0.0.0:1900', ... and is able to respond to multicast M-SEARCH requests properly with a unicast response to the originator of the M-SEARCH request.

However, this leaves me with some questions:

  1. is this the correct way to get node-ssdp to respond to multicast M-SEARCH requests?
  2. would it not be better for node-ssdp to bind two sockets on each interface (one for receiving multicast M-SEARCH requests, and another for sending/receiving all unicast traffic)?
  3. is sourcePort supposed to be used this way? I think there is possibly a mis-match between the code and the documentation as unicastBindPort is mentioned in the readme, but not the code (and vice-versa)?

Thanks, codersaur.

Multiple NIC support?

I've been using node-ssdp 2.2.1 as a client on Windows 8.1 and it has been working perfectly, thanks!

Recently I installed on another Windows 8.1 machine and found that everything went silent. I unfortunately don't have full-time access to that machine, but I did notice it has two network cards returned by os.networkInterfaces() as:

"network_interfaces": {
            "Ethernet": [
              {
                "family": "IPv6", 
                "netmask": "ffff:ffff:ffff:ffff::", 
                "mac": "xx:xx:xx:xx:xx:xx", 
                "internal": false, 
                "scopeid": 3, 
                "address": "fe80::c570:b450:f38c:e02b"
              }, 
              {
                "mac": "xx:xx:xx:xx:xx:xx", 
                "internal": false, 
                "netmask": "255.255.255.0", 
                "family": "IPv4", 
                "address": "10.10.20.1"
              }
            ], 
            "Ethernet_2": [
              {
                "family": "IPv6", 
                "netmask": "ffff:ffff:ffff:ffff::", 
                "mac": "yy:yy:yy:yy:yy:yy", 
                "internal": false, 
                "scopeid": 4, 
                "address": "fe80::9864:ed9b:ea63:6506"
              }, 
              {
                "mac": "yy:yy:yy:yy:yy:yy", 
                "internal": false, 
                "netmask": "255.255.255.0", 
                "family": "IPv4", 
                "address": "192.168.35.54"
              }
            ], 
            "Loopback_Pseudo-Interface_1": [
              {
                "family": "IPv6", 
                "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 
                "mac": "00:00:00:00:00:00", 
                "internal": true, 
                "scopeid": 0, 
                "address": "::1"
              }, 
              {
                "mac": "00:00:00:00:00:00", 
                "internal": true, 
                "netmask": "255.0.0.0", 
                "family": "IPv4", 
                "address": "127.0.0.1"
              }
            ]
          }

Here Ethernet is connected to a single machine using 10.10.20.1, while Ethernet_2 is connected to the wider internal network via 192.168.35.54. I'm wondering how node-ssdp behaves in this scenario?

I noticed a similar issue here, and it looks like the relevant code actually creates a socket for each host IP address it finds.

I'm wondering if the simple solution is to create a new Client() for each IP address? Or if this scenario should be handled at a lower level? Thoughts?

Thanks!

implementing ssdp in nodejs

Can anyone help me write a server-cache-client where the client does a M-Search and the request is stored in a intermediate cache like server and then re-routed to the actual server(device)

did you get the server side working?

hi. i'm glad you cloned this to github, and made it more "node-like" in terms of the coding style!

have you ever gotten the server part of the code to work? i've never had any problems using the client side with ssdp.search('ssdp:all');

but, using the server example in the readme markdown runs, but never seems to see any traffic.

just curious.

thanks,

/mtr

Not working in Windows 10

Hey,
first of all thank you for developing this great node package! Unfortunately, I am not able to use it under Windows 10. I get the following error message:

 Error: addMembership EHOSTUNREACH
    at exports._errnoException (util.js:1026:11)
    at Socket.addMembership (dgram.js:508:11)
    at addMembership ([***]\wemo-test\node_modules\node
-ssdp\lib\index.js:177:19)
    at Socket.onSocketListening ([***]\wemo-test\node_m
odules\node-ssdp\lib\index.js:173:5)
    at emitNone (events.js:91:20)
    at Socket.emit (events.js:185:7)
    at startListening (dgram.js:121:10)
    at dgram.js:228:7
    at _combinedTickCallback (internal/process/next_tick.js:77:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

Is there anything I can do?

Thanks and all the best,
Max

not working on win 8.1

hi

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.');
});
client.search('ssdp:all');

does not found anything on win 8.1 ...

ok on seven/linux/osx ....

xbmc find all my devices

thanks

M-SEARCH is sent each adapter which has an ip?

Hi,

When checking the SSDP messages when using the lib i am seeing that the M-SEARCH is done each adapter which has an IP? But the M-SEARCHES are completely the same. Why is this necessary? This will result in getting multiple responses for the same devices. Is this a Bug or is this as by design?
grafik

When i am deactivating the second adapter, only one M-SEARCH is beeing created and the devices only response once, what would be ok.

License and license headers.

Could You add license file as a part of node-ssdp repository?
I am going to use it in my project by my organisation doesn't allow to use any library which doesn't include license file. Yes, I know that ypur README.md refers to the MIT license but it is not good enough for me.
Could you think also about adding license header to the source code files?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.