@achingbrain/ sdp (英语)
SSDP针对节点的又一执行
关于
首先,导入模块,调用函数并设置一个错误处理器:
import ssdp from '@achingbrain/ssdp'
const bus = await ssdp()
// print error messages to the console
bus.on('error', console.error)
示例 - 找到服务
传出 a serviceType 页:1 discover 方法 - 当发现服务事件时会释放:
// this is the unique service name we are interested in:
const serviceType = 'urn:schemas-upnp-org:service:ContentDirectory:1'
for await (const service of bus.discover({ serviceType })) {
// search for instances of a specific service
}
bus.on('service:discover', service => {
// receive a notification about discovery of a service
})
bus.on('service:update', service => {
// receive a notification when that service is updated - nb. this will only happen
// after the service max-age is reached and if the service's device description
// document has changed
})
示例 - 查找所有服务
不要给任何选择 discover 方法(n.b.您还将接收与协议相关的事件):
for await (const service of bus.discover()) {
// receive a notification about all service types
}
示例 - 广告服务
// advertise a service
const advert = await bus.advertise({
usn: 'urn:schemas-upnp-org:service:ContentDirectory:1',
details: {
URLBase: 'https://192.168.0.1:8001'
}
})
// stop advertising a service
await advert.stop()
关于全部选项,见 自由/广告/选择
与现有的 HTTP 服务器整合
默认情况下,您创建广告时会创建 HTTP 服务器为您服务 details.xml 描述您服务的文档。 要使用已有的服务器, 请做一些诸如:
示例 - Hapi
const advert = await bus.advertise({
usn: 'urn:schemas-upnp-org:service:ContentDirectory:1',
location: {
udp4: 'http://192.168.0.1:8000/ssdp/details.xml'
},
details: {
URLBase: 'https://192.168.0.1:8001'
}
})
server.route({
method: 'GET',
path: '/ssdp/details.xml',
handler: (request, reply) => {
reply(advert.service.details())
.type('text/xml')
}
})
示例 - 快捷键
const advert = await bus.advertise({
usn: 'urn:schemas-upnp-org:service:ContentDirectory:1',
location: {
udp4: 'http://192.168.0.1:8000/ssdp/details.xml'
},
details: {
URLBase: 'https://192.168.0.1:8001'
}
})
app.get('/ssdp/details.xml', async (request, response) => {
response.set('Content-Type', 'text/xml')
try {
const details = await advert.service.details()
response.send(details)
} catch (err) {
response.set('Content-Type', 'text/xml')
response.send(err)
}
})
实例 - 优雅地关闭
ssdp 打开数个端口与您网络上的其他设备进行通信,关闭它们,做一些类似的事情:
process.on('SIGINT',() => {
// stop the server(s) from running - this will also send ssdp:byebye messages for all
// advertised services however they'll only have been sent once the callback is
// invoked so it won't work with process.on('exit') as you can only perform synchronous
// operations there
bus.stop(error => {
process.exit(error ? 1 : 0)
})
})
完整 API 和选项
import ssdp from '@achingbrain/ssdp'
// all arguments are optional
var bus = ssdp({
udn: 'unique-identifier', // defaults to a random UUID
// a string to identify the server by
signature: 'node.js/0.12.6 UPnP/1.1 @achingbrain/ssdp/1.0.0',
retry {
times: 5, // how many times to attempt joining the UDP multicast group
interval: 5000 // how long to wait between attempts
},
// specify one or more sockets to listen on
sockets: [{
type: 'udp4', // or 'udp6'
broadcast: {
address: '239.255.255.250', // or 'FF02::C'
port: 1900 // SSDP broadcast port
},
bind: {
address: '0.0.0.0', // or '0:0:0:0:0:0:0:0'
port: 1900
},
maxHops: 4 // how many network segments packets are allow to travel through (UDP TTL)
}]
})
bus.on('error', console.error)
// this is the type of service we are interested in
var serviceType = 'urn:schemas-upnp-org:service:ContentDirectory:1'
// search for one type of service
for await (const service of bus.discover({ serviceType })) {
}
bus.on('service:discover', service => {
// receive a notification when a service of the passed type is discovered
})
bus.on('service:update', service => {
// receive a notification when that service is updated
})
// search for all types of service
for await (const service of bus.discover()) {
}
// advertise a service
const advert = await bus.advertise({
usn: 'a-usn', // unique service name
interval: 10000, // how often to broadcast service adverts in ms
ttl: 1800000, // how long the advert is valid for in ms
ipv4: true, // whether or not to broadcast the advert over IPv4
ipv6: true, // whether or not to broadcast the advert over IPv6
location: { // where the description document(s) are available - omit to have an http server automatically created
udp4: 'http://192.168.0.1/details.xml', // where the description document is available over ipv4
udp6: 'http://FE80::0202:B3FF:FE1E:8329/details.xml' // where the description document is available over ipv6
},
details: { // the contents of the description document
specVersion: {
major: 1,
minor: 1
},
URLBase: 'http://example.com',
device: {
deviceType: 'a-usn',
friendlyName: 'A friendly device name',
manufacturer: 'Manufactuer name',
manufacturerURL: 'http://example.com',
modelDescription: 'A description of the device',
modelName: 'A model name',
modelNumber: 'A vendor specific model number',
modelURL: 'http://example.com',
serialNumber: 'A device specific serial number',
UDN: 'unique-identifier' // should be the same as the bus USN
presentationURL: 'index.html'
}
}
})
// stop advertising a service
advert.stop()
设备描述文档
在 UPnP 设备发现过程中,客户端可以请求 a 说明您所提供服务的各种能力。 。 。 .
要做到这一点,您可以存储一个 xml 文档并设定 location 您在文档中指向的广告字段
或自动生成.
例如,创建文档, description.xml 放在服务器上 http://server.com/path/to/description.xml数字 :
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.1.41:80</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
<friendlyName>I am a light controller</friendlyName>
<manufacturer>Royal Philips Electronics</manufacturer>
<manufacturerURL>http://www.philips.com</manufacturerURL>
<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>
<modelName>Philips hue bridge 2012</modelName>
<modelNumber>23409823049823</modelNumber>
<modelURL>http://www.meethue.com</modelURL>
<serialNumber>asd09f8s90832</serialNumber>
<UDN>uuid:2f402f80-da50-12321-9b23-2131298129</UDN>
<presentationURL>index.html</presentationURL>
</device>
</root>
然后创建您的广告:
bus.advertise({
usn: 'urn:schemas-upnp-org:device:Basic:1',
location: {
udp4: 'http://192.168.1.40/path/to/description.xml'
}
})
或者提供一个描述对象,让这个模块进行举重(n.b. 您的对象将运行于 xml2js 构建器:
bus.advertise({
usn: 'urn:schemas-upnp-org:device:Basic:1',
details: {
'$': {
'xmlns': 'urn:schemas-upnp-org:device-1-0'
},
'specVersion': {
'major': '1',
'minor': '0'
},
'URLBase': 'http://192.168.1.41:80',
'device': {
'deviceType': 'urn:schemas-upnp-org:device:Basic:1',
'friendlyName': 'I am a light controller',
'manufacturer': 'Royal Philips Electronics',
'manufacturerURL': 'http://www.philips.com',
'modelDescription': 'Philips hue Personal Wireless Lighting',
'modelName': 'Philips hue bridge 2012',
'modelNumber': '23409823049823',
'modelURL': 'http://www.meethue.com',
'serialNumber': 'asd09f8s90832',
'UDN': 'uuid:2f402f80-da50-12321-9b23-2131298129',
'presentationURL': 'index.html'
}
}
})
将选择一个随机高端口,一个 http 服务器将在该端口上收听并服务描述符和 LOCATION
标题将全部适当设置 ssdp 留言.
当你打电话时服务器将被关闭 advert.stop。 。 。 .
我想看所有协议信息
没问题,试试这个
bus.on('transport:outgoing-message', (socket, message, remote) => {
console.info('-> Outgoing to %s:%s via %s', remote.address, remote.port, socket.type)
console.info(message.toString('utf8'))
})
bus.on('transport:incoming-message', (message, remote) => {
console.info('<- Incoming from %s:%s', remote.address, remote.port)
console.info(message.toString('utf8'))
})
或见 试验/固定/全部js
参考资料
安装
$ npm i @achingbrain/ssdp
API 文档
许可证
根据其中任何一项颁发的许可证
- Apache 2.0, (英语:自由主义 编号 : http://www.apache.org/licenses/LICENSE-2.0 (中文(简体) )(中文(简体) )
- 麻省理工学院利马 编号 : http://opensource.org/licenses/MIT 互联网档案馆的存檔,存档日期2013-12-02(中文(简体) )
捐款
除非另有明确声明,Apache-2.0许可证中界定的、有意提交供列入作品的任何捐助,应具有上述双重许可证,不附加任何条件.