mqtt and socket added
This commit is contained in:
1897
WebUI/node_modules/mqtt/lib/client.js
generated
vendored
Normal file
1897
WebUI/node_modules/mqtt/lib/client.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
129
WebUI/node_modules/mqtt/lib/connect/ali.js
generated
vendored
Normal file
129
WebUI/node_modules/mqtt/lib/connect/ali.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const Transform = require('readable-stream').Transform
|
||||
const duplexify = require('duplexify')
|
||||
|
||||
/* global FileReader */
|
||||
let my
|
||||
let proxy
|
||||
let stream
|
||||
let isInitialized = false
|
||||
|
||||
function buildProxy () {
|
||||
const proxy = new Transform()
|
||||
proxy._write = function (chunk, encoding, next) {
|
||||
my.sendSocketMessage({
|
||||
data: chunk.buffer,
|
||||
success: function () {
|
||||
next()
|
||||
},
|
||||
fail: function () {
|
||||
next(new Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
proxy._flush = function socketEnd (done) {
|
||||
my.closeSocket({
|
||||
success: function () {
|
||||
done()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return proxy
|
||||
}
|
||||
|
||||
function setDefaultOpts (opts) {
|
||||
if (!opts.hostname) {
|
||||
opts.hostname = 'localhost'
|
||||
}
|
||||
if (!opts.path) {
|
||||
opts.path = '/'
|
||||
}
|
||||
|
||||
if (!opts.wsOptions) {
|
||||
opts.wsOptions = {}
|
||||
}
|
||||
}
|
||||
|
||||
function buildUrl (opts, client) {
|
||||
const protocol = opts.protocol === 'alis' ? 'wss' : 'ws'
|
||||
let url = protocol + '://' + opts.hostname + opts.path
|
||||
if (opts.port && opts.port !== 80 && opts.port !== 443) {
|
||||
url = protocol + '://' + opts.hostname + ':' + opts.port + opts.path
|
||||
}
|
||||
if (typeof (opts.transformWsUrl) === 'function') {
|
||||
url = opts.transformWsUrl(url, opts, client)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
function bindEventHandler () {
|
||||
if (isInitialized) return
|
||||
|
||||
isInitialized = true
|
||||
|
||||
my.onSocketOpen(function () {
|
||||
stream.setReadable(proxy)
|
||||
stream.setWritable(proxy)
|
||||
stream.emit('connect')
|
||||
})
|
||||
|
||||
my.onSocketMessage(function (res) {
|
||||
if (typeof res.data === 'string') {
|
||||
const buffer = Buffer.from(res.data, 'base64')
|
||||
proxy.push(buffer)
|
||||
} else {
|
||||
const reader = new FileReader()
|
||||
reader.addEventListener('load', function () {
|
||||
let data = reader.result
|
||||
|
||||
if (data instanceof ArrayBuffer) data = Buffer.from(data)
|
||||
else data = Buffer.from(data, 'utf8')
|
||||
proxy.push(data)
|
||||
})
|
||||
reader.readAsArrayBuffer(res.data)
|
||||
}
|
||||
})
|
||||
|
||||
my.onSocketClose(function () {
|
||||
stream.end()
|
||||
stream.destroy()
|
||||
})
|
||||
|
||||
my.onSocketError(function (res) {
|
||||
stream.destroy(res)
|
||||
})
|
||||
}
|
||||
|
||||
function buildStream (client, opts) {
|
||||
opts.hostname = opts.hostname || opts.host
|
||||
|
||||
if (!opts.hostname) {
|
||||
throw new Error('Could not determine host. Specify host manually.')
|
||||
}
|
||||
|
||||
const websocketSubProtocol =
|
||||
(opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3)
|
||||
? 'mqttv3.1'
|
||||
: 'mqtt'
|
||||
|
||||
setDefaultOpts(opts)
|
||||
|
||||
const url = buildUrl(opts, client)
|
||||
my = opts.my
|
||||
my.connectSocket({
|
||||
url: url,
|
||||
protocols: websocketSubProtocol
|
||||
})
|
||||
|
||||
proxy = buildProxy()
|
||||
stream = duplexify.obj()
|
||||
|
||||
bindEventHandler()
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
module.exports = buildStream
|
||||
165
WebUI/node_modules/mqtt/lib/connect/index.js
generated
vendored
Normal file
165
WebUI/node_modules/mqtt/lib/connect/index.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
'use strict'
|
||||
|
||||
const MqttClient = require('../client')
|
||||
const Store = require('../store')
|
||||
const url = require('url')
|
||||
const xtend = require('xtend')
|
||||
const debug = require('debug')('mqttjs')
|
||||
|
||||
const protocols = {}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
if ((typeof process !== 'undefined' && process.title !== 'browser') || typeof __webpack_require__ !== 'function') {
|
||||
protocols.mqtt = require('./tcp')
|
||||
protocols.tcp = require('./tcp')
|
||||
protocols.ssl = require('./tls')
|
||||
protocols.tls = require('./tls')
|
||||
protocols.mqtts = require('./tls')
|
||||
} else {
|
||||
protocols.wx = require('./wx')
|
||||
protocols.wxs = require('./wx')
|
||||
|
||||
protocols.ali = require('./ali')
|
||||
protocols.alis = require('./ali')
|
||||
}
|
||||
|
||||
protocols.ws = require('./ws')
|
||||
protocols.wss = require('./ws')
|
||||
|
||||
/**
|
||||
* Parse the auth attribute and merge username and password in the options object.
|
||||
*
|
||||
* @param {Object} [opts] option object
|
||||
*/
|
||||
function parseAuthOptions (opts) {
|
||||
let matches
|
||||
if (opts.auth) {
|
||||
matches = opts.auth.match(/^(.+):(.+)$/)
|
||||
if (matches) {
|
||||
opts.username = matches[1]
|
||||
opts.password = matches[2]
|
||||
} else {
|
||||
opts.username = opts.auth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* connect - connect to an MQTT broker.
|
||||
*
|
||||
* @param {String} [brokerUrl] - url of the broker, optional
|
||||
* @param {Object} opts - see MqttClient#constructor
|
||||
*/
|
||||
function connect (brokerUrl, opts) {
|
||||
debug('connecting to an MQTT broker...')
|
||||
if ((typeof brokerUrl === 'object') && !opts) {
|
||||
opts = brokerUrl
|
||||
brokerUrl = null
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (brokerUrl) {
|
||||
// eslint-disable-next-line
|
||||
const parsed = url.parse(brokerUrl, true)
|
||||
if (parsed.port != null) {
|
||||
parsed.port = Number(parsed.port)
|
||||
}
|
||||
|
||||
opts = xtend(parsed, opts)
|
||||
|
||||
if (opts.protocol === null) {
|
||||
throw new Error('Missing protocol')
|
||||
}
|
||||
|
||||
opts.protocol = opts.protocol.replace(/:$/, '')
|
||||
}
|
||||
|
||||
// merge in the auth options if supplied
|
||||
parseAuthOptions(opts)
|
||||
|
||||
// support clientId passed in the query string of the url
|
||||
if (opts.query && typeof opts.query.clientId === 'string') {
|
||||
opts.clientId = opts.query.clientId
|
||||
}
|
||||
|
||||
if (opts.cert && opts.key) {
|
||||
if (opts.protocol) {
|
||||
if (['mqtts', 'wss', 'wxs', 'alis'].indexOf(opts.protocol) === -1) {
|
||||
switch (opts.protocol) {
|
||||
case 'mqtt':
|
||||
opts.protocol = 'mqtts'
|
||||
break
|
||||
case 'ws':
|
||||
opts.protocol = 'wss'
|
||||
break
|
||||
case 'wx':
|
||||
opts.protocol = 'wxs'
|
||||
break
|
||||
case 'ali':
|
||||
opts.protocol = 'alis'
|
||||
break
|
||||
default:
|
||||
throw new Error('Unknown protocol for secure connection: "' + opts.protocol + '"!')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// A cert and key was provided, however no protocol was specified, so we will throw an error.
|
||||
throw new Error('Missing secure protocol key')
|
||||
}
|
||||
}
|
||||
|
||||
if (!protocols[opts.protocol]) {
|
||||
const isSecure = ['mqtts', 'wss'].indexOf(opts.protocol) !== -1
|
||||
opts.protocol = [
|
||||
'mqtt',
|
||||
'mqtts',
|
||||
'ws',
|
||||
'wss',
|
||||
'wx',
|
||||
'wxs',
|
||||
'ali',
|
||||
'alis'
|
||||
].filter(function (key, index) {
|
||||
if (isSecure && index % 2 === 0) {
|
||||
// Skip insecure protocols when requesting a secure one.
|
||||
return false
|
||||
}
|
||||
return (typeof protocols[key] === 'function')
|
||||
})[0]
|
||||
}
|
||||
|
||||
if (opts.clean === false && !opts.clientId) {
|
||||
throw new Error('Missing clientId for unclean clients')
|
||||
}
|
||||
|
||||
if (opts.protocol) {
|
||||
opts.defaultProtocol = opts.protocol
|
||||
}
|
||||
|
||||
function wrapper (client) {
|
||||
if (opts.servers) {
|
||||
if (!client._reconnectCount || client._reconnectCount === opts.servers.length) {
|
||||
client._reconnectCount = 0
|
||||
}
|
||||
|
||||
opts.host = opts.servers[client._reconnectCount].host
|
||||
opts.port = opts.servers[client._reconnectCount].port
|
||||
opts.protocol = (!opts.servers[client._reconnectCount].protocol ? opts.defaultProtocol : opts.servers[client._reconnectCount].protocol)
|
||||
opts.hostname = opts.host
|
||||
|
||||
client._reconnectCount++
|
||||
}
|
||||
|
||||
debug('calling streambuilder for', opts.protocol)
|
||||
return protocols[opts.protocol](client, opts)
|
||||
}
|
||||
const client = new MqttClient(wrapper, opts)
|
||||
client.on('error', function () { /* Automatically set up client error handling */ })
|
||||
return client
|
||||
}
|
||||
|
||||
module.exports = connect
|
||||
module.exports.connect = connect
|
||||
module.exports.MqttClient = MqttClient
|
||||
module.exports.Store = Store
|
||||
20
WebUI/node_modules/mqtt/lib/connect/tcp.js
generated
vendored
Normal file
20
WebUI/node_modules/mqtt/lib/connect/tcp.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
const net = require('net')
|
||||
const debug = require('debug')('mqttjs:tcp')
|
||||
|
||||
/*
|
||||
variables port and host can be removed since
|
||||
you have all required information in opts object
|
||||
*/
|
||||
function streamBuilder (client, opts) {
|
||||
opts.port = opts.port || 1883
|
||||
opts.hostname = opts.hostname || opts.host || 'localhost'
|
||||
|
||||
const port = opts.port
|
||||
const host = opts.hostname
|
||||
|
||||
debug('port %d and host %s', port, host)
|
||||
return net.createConnection(port, host)
|
||||
}
|
||||
|
||||
module.exports = streamBuilder
|
||||
48
WebUI/node_modules/mqtt/lib/connect/tls.js
generated
vendored
Normal file
48
WebUI/node_modules/mqtt/lib/connect/tls.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict'
|
||||
const tls = require('tls')
|
||||
const net = require('net')
|
||||
const debug = require('debug')('mqttjs:tls')
|
||||
|
||||
function buildBuilder (mqttClient, opts) {
|
||||
opts.port = opts.port || 8883
|
||||
opts.host = opts.hostname || opts.host || 'localhost'
|
||||
|
||||
if (net.isIP(opts.host) === 0) {
|
||||
opts.servername = opts.host
|
||||
}
|
||||
|
||||
opts.rejectUnauthorized = opts.rejectUnauthorized !== false
|
||||
|
||||
delete opts.path
|
||||
|
||||
debug('port %d host %s rejectUnauthorized %b', opts.port, opts.host, opts.rejectUnauthorized)
|
||||
|
||||
const connection = tls.connect(opts)
|
||||
/* eslint no-use-before-define: [2, "nofunc"] */
|
||||
connection.on('secureConnect', function () {
|
||||
if (opts.rejectUnauthorized && !connection.authorized) {
|
||||
connection.emit('error', new Error('TLS not authorized'))
|
||||
} else {
|
||||
connection.removeListener('error', handleTLSerrors)
|
||||
}
|
||||
})
|
||||
|
||||
function handleTLSerrors (err) {
|
||||
// How can I get verify this error is a tls error?
|
||||
if (opts.rejectUnauthorized) {
|
||||
mqttClient.emit('error', err)
|
||||
}
|
||||
|
||||
// close this connection to match the behaviour of net
|
||||
// otherwise all we get is an error from the connection
|
||||
// and close event doesn't fire. This is a work around
|
||||
// to enable the reconnect code to work the same as with
|
||||
// net.createConnection
|
||||
connection.end()
|
||||
}
|
||||
|
||||
connection.on('error', handleTLSerrors)
|
||||
return connection
|
||||
}
|
||||
|
||||
module.exports = buildBuilder
|
||||
257
WebUI/node_modules/mqtt/lib/connect/ws.js
generated
vendored
Normal file
257
WebUI/node_modules/mqtt/lib/connect/ws.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const WS = require('ws')
|
||||
const debug = require('debug')('mqttjs:ws')
|
||||
const duplexify = require('duplexify')
|
||||
const Transform = require('readable-stream').Transform
|
||||
|
||||
const WSS_OPTIONS = [
|
||||
'rejectUnauthorized',
|
||||
'ca',
|
||||
'cert',
|
||||
'key',
|
||||
'pfx',
|
||||
'passphrase'
|
||||
]
|
||||
// eslint-disable-next-line camelcase
|
||||
const IS_BROWSER = (typeof process !== 'undefined' && process.title === 'browser') || typeof __webpack_require__ === 'function'
|
||||
function buildUrl (opts, client) {
|
||||
let url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path
|
||||
if (typeof (opts.transformWsUrl) === 'function') {
|
||||
url = opts.transformWsUrl(url, opts, client)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
function setDefaultOpts (opts) {
|
||||
const options = opts
|
||||
if (!opts.hostname) {
|
||||
options.hostname = 'localhost'
|
||||
}
|
||||
if (!opts.port) {
|
||||
if (opts.protocol === 'wss') {
|
||||
options.port = 443
|
||||
} else {
|
||||
options.port = 80
|
||||
}
|
||||
}
|
||||
if (!opts.path) {
|
||||
options.path = '/'
|
||||
}
|
||||
|
||||
if (!opts.wsOptions) {
|
||||
options.wsOptions = {}
|
||||
}
|
||||
if (!IS_BROWSER && opts.protocol === 'wss') {
|
||||
// Add cert/key/ca etc options
|
||||
WSS_OPTIONS.forEach(function (prop) {
|
||||
if (Object.prototype.hasOwnProperty.call(opts, prop) && !Object.prototype.hasOwnProperty.call(opts.wsOptions, prop)) {
|
||||
options.wsOptions[prop] = opts[prop]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
function setDefaultBrowserOpts (opts) {
|
||||
const options = setDefaultOpts(opts)
|
||||
|
||||
if (!options.hostname) {
|
||||
options.hostname = options.host
|
||||
}
|
||||
|
||||
if (!options.hostname) {
|
||||
// Throwing an error in a Web Worker if no `hostname` is given, because we
|
||||
// can not determine the `hostname` automatically. If connecting to
|
||||
// localhost, please supply the `hostname` as an argument.
|
||||
if (typeof (document) === 'undefined') {
|
||||
throw new Error('Could not determine host. Specify host manually.')
|
||||
}
|
||||
const parsed = new URL(document.URL)
|
||||
options.hostname = parsed.hostname
|
||||
|
||||
if (!options.port) {
|
||||
options.port = parsed.port
|
||||
}
|
||||
}
|
||||
|
||||
// objectMode should be defined for logic
|
||||
if (options.objectMode === undefined) {
|
||||
options.objectMode = !(options.binary === true || options.binary === undefined)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
function createWebSocket (client, url, opts) {
|
||||
debug('createWebSocket')
|
||||
debug('protocol: ' + opts.protocolId + ' ' + opts.protocolVersion)
|
||||
const websocketSubProtocol =
|
||||
(opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3)
|
||||
? 'mqttv3.1'
|
||||
: 'mqtt'
|
||||
|
||||
debug('creating new Websocket for url: ' + url + ' and protocol: ' + websocketSubProtocol)
|
||||
const socket = new WS(url, [websocketSubProtocol], opts.wsOptions)
|
||||
return socket
|
||||
}
|
||||
|
||||
function createBrowserWebSocket (client, opts) {
|
||||
const websocketSubProtocol =
|
||||
(opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3)
|
||||
? 'mqttv3.1'
|
||||
: 'mqtt'
|
||||
|
||||
const url = buildUrl(opts, client)
|
||||
/* global WebSocket */
|
||||
const socket = new WebSocket(url, [websocketSubProtocol])
|
||||
socket.binaryType = 'arraybuffer'
|
||||
return socket
|
||||
}
|
||||
|
||||
function streamBuilder (client, opts) {
|
||||
debug('streamBuilder')
|
||||
const options = setDefaultOpts(opts)
|
||||
const url = buildUrl(options, client)
|
||||
const socket = createWebSocket(client, url, options)
|
||||
const webSocketStream = WS.createWebSocketStream(socket, options.wsOptions)
|
||||
webSocketStream.url = url
|
||||
socket.on('close', () => { webSocketStream.destroy() })
|
||||
return webSocketStream
|
||||
}
|
||||
|
||||
function browserStreamBuilder (client, opts) {
|
||||
debug('browserStreamBuilder')
|
||||
let stream
|
||||
const options = setDefaultBrowserOpts(opts)
|
||||
// sets the maximum socket buffer size before throttling
|
||||
const bufferSize = options.browserBufferSize || 1024 * 512
|
||||
|
||||
const bufferTimeout = opts.browserBufferTimeout || 1000
|
||||
|
||||
const coerceToBuffer = !opts.objectMode
|
||||
|
||||
const socket = createBrowserWebSocket(client, opts)
|
||||
|
||||
const proxy = buildProxy(opts, socketWriteBrowser, socketEndBrowser)
|
||||
|
||||
if (!opts.objectMode) {
|
||||
proxy._writev = writev
|
||||
}
|
||||
proxy.on('close', () => { socket.close() })
|
||||
|
||||
const eventListenerSupport = (typeof socket.addEventListener !== 'undefined')
|
||||
|
||||
// was already open when passed in
|
||||
if (socket.readyState === socket.OPEN) {
|
||||
stream = proxy
|
||||
} else {
|
||||
stream = stream = duplexify(undefined, undefined, opts)
|
||||
if (!opts.objectMode) {
|
||||
stream._writev = writev
|
||||
}
|
||||
|
||||
if (eventListenerSupport) {
|
||||
socket.addEventListener('open', onopen)
|
||||
} else {
|
||||
socket.onopen = onopen
|
||||
}
|
||||
}
|
||||
|
||||
stream.socket = socket
|
||||
|
||||
if (eventListenerSupport) {
|
||||
socket.addEventListener('close', onclose)
|
||||
socket.addEventListener('error', onerror)
|
||||
socket.addEventListener('message', onmessage)
|
||||
} else {
|
||||
socket.onclose = onclose
|
||||
socket.onerror = onerror
|
||||
socket.onmessage = onmessage
|
||||
}
|
||||
|
||||
// methods for browserStreamBuilder
|
||||
|
||||
function buildProxy (options, socketWrite, socketEnd) {
|
||||
const proxy = new Transform({
|
||||
objectModeMode: options.objectMode
|
||||
})
|
||||
|
||||
proxy._write = socketWrite
|
||||
proxy._flush = socketEnd
|
||||
|
||||
return proxy
|
||||
}
|
||||
|
||||
function onopen () {
|
||||
stream.setReadable(proxy)
|
||||
stream.setWritable(proxy)
|
||||
stream.emit('connect')
|
||||
}
|
||||
|
||||
function onclose () {
|
||||
stream.end()
|
||||
stream.destroy()
|
||||
}
|
||||
|
||||
function onerror (err) {
|
||||
stream.destroy(err)
|
||||
}
|
||||
|
||||
function onmessage (event) {
|
||||
let data = event.data
|
||||
if (data instanceof ArrayBuffer) data = Buffer.from(data)
|
||||
else data = Buffer.from(data, 'utf8')
|
||||
proxy.push(data)
|
||||
}
|
||||
|
||||
// this is to be enabled only if objectMode is false
|
||||
function writev (chunks, cb) {
|
||||
const buffers = new Array(chunks.length)
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
if (typeof chunks[i].chunk === 'string') {
|
||||
buffers[i] = Buffer.from(chunks[i], 'utf8')
|
||||
} else {
|
||||
buffers[i] = chunks[i].chunk
|
||||
}
|
||||
}
|
||||
|
||||
this._write(Buffer.concat(buffers), 'binary', cb)
|
||||
}
|
||||
|
||||
function socketWriteBrowser (chunk, enc, next) {
|
||||
if (socket.bufferedAmount > bufferSize) {
|
||||
// throttle data until buffered amount is reduced.
|
||||
setTimeout(socketWriteBrowser, bufferTimeout, chunk, enc, next)
|
||||
}
|
||||
|
||||
if (coerceToBuffer && typeof chunk === 'string') {
|
||||
chunk = Buffer.from(chunk, 'utf8')
|
||||
}
|
||||
|
||||
try {
|
||||
socket.send(chunk)
|
||||
} catch (err) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
function socketEndBrowser (done) {
|
||||
socket.close()
|
||||
done()
|
||||
}
|
||||
|
||||
// end methods for browserStreamBuilder
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
if (IS_BROWSER) {
|
||||
module.exports = browserStreamBuilder
|
||||
} else {
|
||||
module.exports = streamBuilder
|
||||
}
|
||||
133
WebUI/node_modules/mqtt/lib/connect/wx.js
generated
vendored
Normal file
133
WebUI/node_modules/mqtt/lib/connect/wx.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const Transform = require('readable-stream').Transform
|
||||
const duplexify = require('duplexify')
|
||||
|
||||
/* global wx */
|
||||
let socketTask, proxy, stream
|
||||
|
||||
function buildProxy () {
|
||||
const proxy = new Transform()
|
||||
proxy._write = function (chunk, encoding, next) {
|
||||
socketTask.send({
|
||||
data: chunk.buffer,
|
||||
success: function () {
|
||||
next()
|
||||
},
|
||||
fail: function (errMsg) {
|
||||
next(new Error(errMsg))
|
||||
}
|
||||
})
|
||||
}
|
||||
proxy._flush = function socketEnd (done) {
|
||||
socketTask.close({
|
||||
success: function () {
|
||||
done()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return proxy
|
||||
}
|
||||
|
||||
function setDefaultOpts (opts) {
|
||||
if (!opts.hostname) {
|
||||
opts.hostname = 'localhost'
|
||||
}
|
||||
if (!opts.path) {
|
||||
opts.path = '/'
|
||||
}
|
||||
|
||||
if (!opts.wsOptions) {
|
||||
opts.wsOptions = {}
|
||||
}
|
||||
}
|
||||
|
||||
function buildUrl (opts, client) {
|
||||
const protocol = opts.protocol === 'wxs' ? 'wss' : 'ws'
|
||||
let url = protocol + '://' + opts.hostname + opts.path
|
||||
if (opts.port && opts.port !== 80 && opts.port !== 443) {
|
||||
url = protocol + '://' + opts.hostname + ':' + opts.port + opts.path
|
||||
}
|
||||
if (typeof (opts.transformWsUrl) === 'function') {
|
||||
url = opts.transformWsUrl(url, opts, client)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
function bindEventHandler () {
|
||||
socketTask.onOpen(function () {
|
||||
stream.setReadable(proxy)
|
||||
stream.setWritable(proxy)
|
||||
stream.emit('connect')
|
||||
})
|
||||
|
||||
socketTask.onMessage(function (res) {
|
||||
let data = res.data
|
||||
|
||||
if (data instanceof ArrayBuffer) data = Buffer.from(data)
|
||||
else data = Buffer.from(data, 'utf8')
|
||||
proxy.push(data)
|
||||
})
|
||||
|
||||
socketTask.onClose(function () {
|
||||
stream.end()
|
||||
stream.destroy()
|
||||
})
|
||||
|
||||
socketTask.onError(function (res) {
|
||||
stream.destroy(new Error(res.errMsg))
|
||||
})
|
||||
}
|
||||
|
||||
function buildStream (client, opts) {
|
||||
opts.hostname = opts.hostname || opts.host
|
||||
|
||||
if (!opts.hostname) {
|
||||
throw new Error('Could not determine host. Specify host manually.')
|
||||
}
|
||||
|
||||
const websocketSubProtocol =
|
||||
(opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3)
|
||||
? 'mqttv3.1'
|
||||
: 'mqtt'
|
||||
|
||||
setDefaultOpts(opts)
|
||||
|
||||
const url = buildUrl(opts, client)
|
||||
socketTask = wx.connectSocket({
|
||||
url: url,
|
||||
protocols: [websocketSubProtocol]
|
||||
})
|
||||
|
||||
proxy = buildProxy()
|
||||
stream = duplexify.obj()
|
||||
stream._destroy = function (err, cb) {
|
||||
socketTask.close({
|
||||
success: function () {
|
||||
cb && cb(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const destroyRef = stream.destroy
|
||||
stream.destroy = function () {
|
||||
stream.destroy = destroyRef
|
||||
|
||||
const self = this
|
||||
setTimeout(function () {
|
||||
socketTask.close({
|
||||
fail: function () {
|
||||
self._destroy(new Error())
|
||||
}
|
||||
})
|
||||
}, 0)
|
||||
}.bind(stream)
|
||||
|
||||
bindEventHandler()
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
module.exports = buildStream
|
||||
69
WebUI/node_modules/mqtt/lib/default-message-id-provider.js
generated
vendored
Normal file
69
WebUI/node_modules/mqtt/lib/default-message-id-provider.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* DefaultMessageAllocator constructor
|
||||
* @constructor
|
||||
*/
|
||||
function DefaultMessageIdProvider () {
|
||||
if (!(this instanceof DefaultMessageIdProvider)) {
|
||||
return new DefaultMessageIdProvider()
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageIDs starting with 1
|
||||
* ensure that nextId is min. 1, see https://github.com/mqttjs/MQTT.js/issues/810
|
||||
*/
|
||||
this.nextId = Math.max(1, Math.floor(Math.random() * 65535))
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate
|
||||
*
|
||||
* Get the next messageId.
|
||||
* @return unsigned int
|
||||
*/
|
||||
DefaultMessageIdProvider.prototype.allocate = function () {
|
||||
// id becomes current state of this.nextId and increments afterwards
|
||||
const id = this.nextId++
|
||||
// Ensure 16 bit unsigned int (max 65535, nextId got one higher)
|
||||
if (this.nextId === 65536) {
|
||||
this.nextId = 1
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
/**
|
||||
* getLastAllocated
|
||||
* Get the last allocated messageId.
|
||||
* @return unsigned int
|
||||
*/
|
||||
DefaultMessageIdProvider.prototype.getLastAllocated = function () {
|
||||
return (this.nextId === 1) ? 65535 : (this.nextId - 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* register
|
||||
* Register messageId. If success return true, otherwise return false.
|
||||
* @param { unsigned int } - messageId to register,
|
||||
* @return boolean
|
||||
*/
|
||||
DefaultMessageIdProvider.prototype.register = function (messageId) {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* deallocate
|
||||
* Deallocate messageId.
|
||||
* @param { unsigned int } - messageId to deallocate,
|
||||
*/
|
||||
DefaultMessageIdProvider.prototype.deallocate = function (messageId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* clear
|
||||
* Deallocate all messageIds.
|
||||
*/
|
||||
DefaultMessageIdProvider.prototype.clear = function () {
|
||||
}
|
||||
|
||||
module.exports = DefaultMessageIdProvider
|
||||
128
WebUI/node_modules/mqtt/lib/store.js
generated
vendored
Normal file
128
WebUI/node_modules/mqtt/lib/store.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
const xtend = require('xtend')
|
||||
|
||||
const Readable = require('readable-stream').Readable
|
||||
const streamsOpts = { objectMode: true }
|
||||
const defaultStoreOptions = {
|
||||
clean: true
|
||||
}
|
||||
|
||||
/**
|
||||
* In-memory implementation of the message store
|
||||
* This can actually be saved into files.
|
||||
*
|
||||
* @param {Object} [options] - store options
|
||||
*/
|
||||
function Store (options) {
|
||||
if (!(this instanceof Store)) {
|
||||
return new Store(options)
|
||||
}
|
||||
|
||||
this.options = options || {}
|
||||
|
||||
// Defaults
|
||||
this.options = xtend(defaultStoreOptions, options)
|
||||
|
||||
this._inflights = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet to the store, a packet is
|
||||
* anything that has a messageId property.
|
||||
*
|
||||
*/
|
||||
Store.prototype.put = function (packet, cb) {
|
||||
this._inflights.set(packet.messageId, packet)
|
||||
|
||||
if (cb) {
|
||||
cb()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a stream with all the packets in the store
|
||||
*
|
||||
*/
|
||||
Store.prototype.createStream = function () {
|
||||
const stream = new Readable(streamsOpts)
|
||||
const values = []
|
||||
let destroyed = false
|
||||
let i = 0
|
||||
|
||||
this._inflights.forEach(function (value, key) {
|
||||
values.push(value)
|
||||
})
|
||||
|
||||
stream._read = function () {
|
||||
if (!destroyed && i < values.length) {
|
||||
this.push(values[i++])
|
||||
} else {
|
||||
this.push(null)
|
||||
}
|
||||
}
|
||||
|
||||
stream.destroy = function () {
|
||||
if (destroyed) {
|
||||
return
|
||||
}
|
||||
|
||||
const self = this
|
||||
|
||||
destroyed = true
|
||||
|
||||
setTimeout(function () {
|
||||
self.emit('close')
|
||||
}, 0)
|
||||
}
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a packet from the store.
|
||||
*/
|
||||
Store.prototype.del = function (packet, cb) {
|
||||
packet = this._inflights.get(packet.messageId)
|
||||
if (packet) {
|
||||
this._inflights.delete(packet.messageId)
|
||||
cb(null, packet)
|
||||
} else if (cb) {
|
||||
cb(new Error('missing packet'))
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* get a packet from the store.
|
||||
*/
|
||||
Store.prototype.get = function (packet, cb) {
|
||||
packet = this._inflights.get(packet.messageId)
|
||||
if (packet) {
|
||||
cb(null, packet)
|
||||
} else if (cb) {
|
||||
cb(new Error('missing packet'))
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the store
|
||||
*/
|
||||
Store.prototype.close = function (cb) {
|
||||
if (this.options.clean) {
|
||||
this._inflights = null
|
||||
}
|
||||
if (cb) {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Store
|
||||
47
WebUI/node_modules/mqtt/lib/topic-alias-recv.js
generated
vendored
Normal file
47
WebUI/node_modules/mqtt/lib/topic-alias-recv.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Topic Alias receiving manager
|
||||
* This holds alias to topic map
|
||||
* @param {Number} [max] - topic alias maximum entries
|
||||
*/
|
||||
function TopicAliasRecv (max) {
|
||||
if (!(this instanceof TopicAliasRecv)) {
|
||||
return new TopicAliasRecv(max)
|
||||
}
|
||||
this.aliasToTopic = {}
|
||||
this.max = max
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update topic - alias entry.
|
||||
* @param {String} [topic] - topic
|
||||
* @param {Number} [alias] - topic alias
|
||||
* @returns {Boolean} - if success return true otherwise false
|
||||
*/
|
||||
TopicAliasRecv.prototype.put = function (topic, alias) {
|
||||
if (alias === 0 || alias > this.max) {
|
||||
return false
|
||||
}
|
||||
this.aliasToTopic[alias] = topic
|
||||
this.length = Object.keys(this.aliasToTopic).length
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get topic by alias
|
||||
* @param {String} [topic] - topic
|
||||
* @returns {Number} - if mapped topic exists return topic alias, otherwise return undefined
|
||||
*/
|
||||
TopicAliasRecv.prototype.getTopicByAlias = function (alias) {
|
||||
return this.aliasToTopic[alias]
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all entries
|
||||
*/
|
||||
TopicAliasRecv.prototype.clear = function () {
|
||||
this.aliasToTopic = {}
|
||||
}
|
||||
|
||||
module.exports = TopicAliasRecv
|
||||
91
WebUI/node_modules/mqtt/lib/topic-alias-send.js
generated
vendored
Normal file
91
WebUI/node_modules/mqtt/lib/topic-alias-send.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
const LruMap = require('lru-cache')
|
||||
const NumberAllocator = require('number-allocator').NumberAllocator
|
||||
|
||||
/**
|
||||
* Topic Alias sending manager
|
||||
* This holds both topic to alias and alias to topic map
|
||||
* @param {Number} [max] - topic alias maximum entries
|
||||
*/
|
||||
function TopicAliasSend (max) {
|
||||
if (!(this instanceof TopicAliasSend)) {
|
||||
return new TopicAliasSend(max)
|
||||
}
|
||||
|
||||
if (max > 0) {
|
||||
this.aliasToTopic = new LruMap({ max: max })
|
||||
this.topicToAlias = {}
|
||||
this.numberAllocator = new NumberAllocator(1, max)
|
||||
this.max = max
|
||||
this.length = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update topic - alias entry.
|
||||
* @param {String} [topic] - topic
|
||||
* @param {Number} [alias] - topic alias
|
||||
* @returns {Boolean} - if success return true otherwise false
|
||||
*/
|
||||
TopicAliasSend.prototype.put = function (topic, alias) {
|
||||
if (alias === 0 || alias > this.max) {
|
||||
return false
|
||||
}
|
||||
const entry = this.aliasToTopic.get(alias)
|
||||
if (entry) {
|
||||
delete this.topicToAlias[entry]
|
||||
}
|
||||
this.aliasToTopic.set(alias, topic)
|
||||
this.topicToAlias[topic] = alias
|
||||
this.numberAllocator.use(alias)
|
||||
this.length = this.aliasToTopic.length
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get topic by alias
|
||||
* @param {Number} [alias] - topic alias
|
||||
* @returns {String} - if mapped topic exists return topic, otherwise return undefined
|
||||
*/
|
||||
TopicAliasSend.prototype.getTopicByAlias = function (alias) {
|
||||
return this.aliasToTopic.get(alias)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get topic by alias
|
||||
* @param {String} [topic] - topic
|
||||
* @returns {Number} - if mapped topic exists return topic alias, otherwise return undefined
|
||||
*/
|
||||
TopicAliasSend.prototype.getAliasByTopic = function (topic) {
|
||||
const alias = this.topicToAlias[topic]
|
||||
if (typeof alias !== 'undefined') {
|
||||
this.aliasToTopic.get(alias) // LRU update
|
||||
}
|
||||
return alias
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all entries
|
||||
*/
|
||||
TopicAliasSend.prototype.clear = function () {
|
||||
this.aliasToTopic.reset()
|
||||
this.topicToAlias = {}
|
||||
this.numberAllocator.clear()
|
||||
this.length = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Least Recently Used (LRU) topic alias
|
||||
* @returns {Number} - if vacant alias exists then return it, otherwise then return LRU alias
|
||||
*/
|
||||
TopicAliasSend.prototype.getLruAlias = function () {
|
||||
const alias = this.numberAllocator.firstVacant()
|
||||
if (alias) return alias
|
||||
return this.aliasToTopic.keys()[this.aliasToTopic.length - 1]
|
||||
}
|
||||
|
||||
module.exports = TopicAliasSend
|
||||
65
WebUI/node_modules/mqtt/lib/unique-message-id-provider.js
generated
vendored
Normal file
65
WebUI/node_modules/mqtt/lib/unique-message-id-provider.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
'use strict'
|
||||
|
||||
const NumberAllocator = require('number-allocator').NumberAllocator
|
||||
|
||||
/**
|
||||
* UniqueMessageAllocator constructor
|
||||
* @constructor
|
||||
*/
|
||||
function UniqueMessageIdProvider () {
|
||||
if (!(this instanceof UniqueMessageIdProvider)) {
|
||||
return new UniqueMessageIdProvider()
|
||||
}
|
||||
|
||||
this.numberAllocator = new NumberAllocator(1, 65535)
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate
|
||||
*
|
||||
* Get the next messageId.
|
||||
* @return if messageId is fully allocated then return null,
|
||||
* otherwise return the smallest usable unsigned int messageId.
|
||||
*/
|
||||
UniqueMessageIdProvider.prototype.allocate = function () {
|
||||
this.lastId = this.numberAllocator.alloc()
|
||||
return this.lastId
|
||||
}
|
||||
|
||||
/**
|
||||
* getLastAllocated
|
||||
* Get the last allocated messageId.
|
||||
* @return unsigned int
|
||||
*/
|
||||
UniqueMessageIdProvider.prototype.getLastAllocated = function () {
|
||||
return this.lastId
|
||||
}
|
||||
|
||||
/**
|
||||
* register
|
||||
* Register messageId. If success return true, otherwise return false.
|
||||
* @param { unsigned int } - messageId to register,
|
||||
* @return boolean
|
||||
*/
|
||||
UniqueMessageIdProvider.prototype.register = function (messageId) {
|
||||
return this.numberAllocator.use(messageId)
|
||||
}
|
||||
|
||||
/**
|
||||
* deallocate
|
||||
* Deallocate messageId.
|
||||
* @param { unsigned int } - messageId to deallocate,
|
||||
*/
|
||||
UniqueMessageIdProvider.prototype.deallocate = function (messageId) {
|
||||
this.numberAllocator.free(messageId)
|
||||
}
|
||||
|
||||
/**
|
||||
* clear
|
||||
* Deallocate all messageIds.
|
||||
*/
|
||||
UniqueMessageIdProvider.prototype.clear = function () {
|
||||
this.numberAllocator.clear()
|
||||
}
|
||||
|
||||
module.exports = UniqueMessageIdProvider
|
||||
52
WebUI/node_modules/mqtt/lib/validations.js
generated
vendored
Normal file
52
WebUI/node_modules/mqtt/lib/validations.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Validate a topic to see if it's valid or not.
|
||||
* A topic is valid if it follow below rules:
|
||||
* - Rule #1: If any part of the topic is not `+` or `#`, then it must not contain `+` and '#'
|
||||
* - Rule #2: Part `#` must be located at the end of the mailbox
|
||||
*
|
||||
* @param {String} topic - A topic
|
||||
* @returns {Boolean} If the topic is valid, returns true. Otherwise, returns false.
|
||||
*/
|
||||
function validateTopic (topic) {
|
||||
const parts = topic.split('/')
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (parts[i] === '+') {
|
||||
continue
|
||||
}
|
||||
|
||||
if (parts[i] === '#') {
|
||||
// for Rule #2
|
||||
return i === parts.length - 1
|
||||
}
|
||||
|
||||
if (parts[i].indexOf('+') !== -1 || parts[i].indexOf('#') !== -1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an array of topics to see if any of them is valid or not
|
||||
* @param {Array} topics - Array of topics
|
||||
* @returns {String} If the topics is valid, returns null. Otherwise, returns the invalid one
|
||||
*/
|
||||
function validateTopics (topics) {
|
||||
if (topics.length === 0) {
|
||||
return 'empty_topic_list'
|
||||
}
|
||||
for (let i = 0; i < topics.length; i++) {
|
||||
if (!validateTopic(topics[i])) {
|
||||
return topics[i]
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateTopics: validateTopics
|
||||
}
|
||||
Reference in New Issue
Block a user