(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.mqtt = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
(function (process,global){
'use strict'
/**
* Module dependencies
*/
var events = require('events')
var Store = require('./store')
var mqttPacket = require('mqtt-packet')
var Writable = require('readable-stream').Writable
var inherits = require('inherits')
var reInterval = require('reinterval')
var validations = require('./validations')
var xtend = require('xtend')
var setImmediate = global.setImmediate || function (callback) {
// works in node v0.8
process.nextTick(callback)
}
var defaultConnectOptions = {
keepalive: 60,
reschedulePings: true,
protocolId: 'MQTT',
protocolVersion: 4,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
clean: true,
resubscribe: true
}
var errors = {
0: '',
1: 'Unacceptable protocol version',
2: 'Identifier rejected',
3: 'Server unavailable',
4: 'Bad username or password',
5: 'Not authorized',
16: 'No matching subscribers',
17: 'No subscription existed',
128: 'Unspecified error',
129: 'Malformed Packet',
130: 'Protocol Error',
131: 'Implementation specific error',
132: 'Unsupported Protocol Version',
133: 'Client Identifier not valid',
134: 'Bad User Name or Password',
135: 'Not authorized',
136: 'Server unavailable',
137: 'Server busy',
138: 'Banned',
139: 'Server shutting down',
140: 'Bad authentication method',
141: 'Keep Alive timeout',
142: 'Session taken over',
143: 'Topic Filter invalid',
144: 'Topic Name invalid',
145: 'Packet identifier in use',
146: 'Packet Identifier not found',
147: 'Receive Maximum exceeded',
148: 'Topic Alias invalid',
149: 'Packet too large',
150: 'Message rate too high',
151: 'Quota exceeded',
152: 'Administrative action',
153: 'Payload format invalid',
154: 'Retain not supported',
155: 'QoS not supported',
156: 'Use another server',
157: 'Server moved',
158: 'Shared Subscriptions not supported',
159: 'Connection rate exceeded',
160: 'Maximum connect time',
161: 'Subscription Identifiers not supported',
162: 'Wildcard Subscriptions not supported'
}
function defaultId () {
return 'mqttjs_' + Math.random().toString(16).substr(2, 8)
}
function sendPacket (client, packet, cb) {
client.emit('packetsend', packet)
var result = mqttPacket.writeToStream(packet, client.stream, client.options)
if (!result && cb) {
client.stream.once('drain', cb)
} else if (cb) {
cb()
}
}
function flush (queue) {
if (queue) {
Object.keys(queue).forEach(function (messageId) {
if (typeof queue[messageId] === 'function') {
queue[messageId](new Error('Connection closed'))
delete queue[messageId]
}
})
}
}
function storeAndSend (client, packet, cb, cbStorePut) {
client.outgoingStore.put(packet, function storedPacket (err) {
if (err) {
return cb && cb(err)
}
cbStorePut()
sendPacket(client, packet, cb)
})
}
function nop () {}
/**
* MqttClient constructor
*
* @param {Stream} stream - stream
* @param {Object} [options] - connection options
* (see Connection#connect)
*/
function MqttClient (streamBuilder, options) {
var k
var that = this
if (!(this instanceof MqttClient)) {
return new MqttClient(streamBuilder, options)
}
this.options = options || {}
// Defaults
for (k in defaultConnectOptions) {
if (typeof this.options[k] === 'undefined') {
this.options[k] = defaultConnectOptions[k]
} else {
this.options[k] = options[k]
}
}
this.options.clientId = (typeof options.clientId === 'string') ? options.clientId : defaultId()
this.options.customHandleAcks = (options.protocolVersion === 5 && options.customHandleAcks) ? options.customHandleAcks : function () { arguments[3](0) }
this.streamBuilder = streamBuilder
// Inflight message storages
this.outgoingStore = options.outgoingStore || new Store()
this.incomingStore = options.incomingStore || new Store()
// Should QoS zero messages be queued when the connection is broken?
this.queueQoSZero = options.queueQoSZero === undefined ? true : options.queueQoSZero
// map of subscribed topics to support reconnection
this._resubscribeTopics = {}
// map of a subscribe messageId and a topic
this.messageIdToTopic = {}
// Ping timer, setup in _setupPingTimer
this.pingTimer = null
// Is the client connected?
this.connected = false
// Are we disconnecting?
this.disconnecting = false
// Packet queue
this.queue = []
// connack timer
this.connackTimer = null
// Reconnect timer
this.reconnectTimer = null
// Is processing store?
this._storeProcessing = false
// Packet Ids are put into the store during store processing
this._packetIdsDuringStoreProcessing = {}
/**
* 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))
// Inflight callbacks
this.outgoing = {}
// True if connection is first time.
this._firstConnection = true
// Mark disconnected on stream close
this.on('close', function () {
this.connected = false
clearTimeout(this.connackTimer)
})
// Send queued packets
this.on('connect', function () {
var queue = this.queue
function deliver () {
var entry = queue.shift()
var packet = null
if (!entry) {
return
}
packet = entry.packet
that._sendPacket(
packet,
function (err) {
if (entry.cb) {
entry.cb(err)
}
deliver()
}
)
}
deliver()
})
// Clear ping timer
this.on('close', function () {
if (that.pingTimer !== null) {
that.pingTimer.clear()
that.pingTimer = null
}
})
// Setup reconnect timer on disconnect
this.on('close', this._setupReconnect)
events.EventEmitter.call(this)
this._setupStream()
}
inherits(MqttClient, events.EventEmitter)
/**
* setup the event handlers in the inner stream.
*
* @api private
*/
MqttClient.prototype._setupStream = function () {
var connectPacket
var that = this
var writable = new Writable()
var parser = mqttPacket.parser(this.options)
var completeParse = null
var packets = []
this._clearReconnect()
this.stream = this.streamBuilder(this)
parser.on('packet', function (packet) {
packets.push(packet)
})
function nextTickWork () {
process.nextTick(work)
}
function work () {
var packet = packets.shift()
var done = completeParse
if (packet) {
that._handlePacket(packet, nextTickWork)
} else {
completeParse = null
done()
}
}
writable._write = function (buf, enc, done) {
completeParse = done
parser.parse(buf)
work()
}
this.stream.pipe(writable)
// Suppress connection errors
this.stream.on('error', nop)
// Echo stream close
this.stream.on('close', function () {
that.emit('close')
})
// Send a connect packet
connectPacket = Object.create(this.options)
connectPacket.cmd = 'connect'
// avoid message queue
sendPacket(this, connectPacket)
// Echo connection errors
parser.o