From a690c274e65bb708c2399d04af07b6f4618cc9be Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 1 Sep 2016 19:06:04 +0200 Subject: [PATCH] Standardized --- LICENSE.md | 2 +- README.md | 56 +- benchmarks/bombing.js | 30 +- benchmarks/throughputCounter.js | 30 +- bin/pub.js | 104 +- bin/sub.js | 84 +- example.js | 14 +- examples/client/secure-client.js | 31 +- examples/client/simple-both.js | 18 +- examples/client/simple-publish.js | 8 +- examples/client/simple-subscribe.js | 12 +- examples/server/broadcast.js | 56 - examples/server/orig.js | 67 - examples/server/redis.js | 48 - examples/server/tls.js | 52 - examples/server/websocket.js | 74 - examples/tls client/mqttclient.js | 67 +- examples/tls server/crt.server1.pem | 32 - examples/tls server/key.csr.server1.pem | 52 - examples/tls server/mqttserver.js | 48 - examples/wss/client.js | 68 +- lib/client.js | 676 +++++---- lib/connect/index.js | 116 +- lib/connect/tcp.js | 18 +- lib/connect/tls.js | 41 +- lib/connect/ws.js | 88 +- lib/store.js | 81 +- lib/validations.js | 31 +- mqtt.js | 43 +- package.json | 23 +- test/abstract_client.js | 1795 +++++++++++------------ test/abstract_store.js | 114 +- test/browser/server.js | 141 +- test/browser/test.js | 95 +- test/client.js | 313 ++-- test/helpers/server.js | 67 +- test/helpers/server_process.js | 15 +- test/mqtt.js | 200 ++- test/secure_client.js | 139 +- test/server.js | 57 +- test/store.js | 13 +- test/util.js | 21 +- test/websocket_client.js | 127 +- 43 files changed, 2336 insertions(+), 2831 deletions(-) delete mode 100644 examples/server/broadcast.js delete mode 100644 examples/server/orig.js delete mode 100644 examples/server/redis.js delete mode 100644 examples/server/tls.js delete mode 100644 examples/server/websocket.js delete mode 100644 examples/tls server/crt.server1.pem delete mode 100644 examples/tls server/key.csr.server1.pem delete mode 100644 examples/tls server/mqttserver.js diff --git a/LICENSE.md b/LICENSE.md index 07df702d3..d23ded902 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ The MIT License (MIT) ===================== -Copyright (c) 2015 MQTT.js contributors +Copyright (c) 2015-2016 MQTT.js contributors --------------------------------------- *MQTT.js contributors listed at * diff --git a/README.md b/README.md index e6edc2bf9..6b649b400 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ in JavaScript for node.js and the browser. MQTT.js is an OPEN Open Source Project, see the [Contributing](#contributing) section to find out what this means. +[![JavaScript Style +Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) + + ## Important notes for existing users @@ -63,19 +67,19 @@ npm install mqtt --save For the sake of simplicity, let's put the subscriber and the publisher in the same file: ```js -var mqtt = require('mqtt'); -var client = mqtt.connect('mqtt://test.mosquitto.org'); +var mqtt = require('mqtt') +var client = mqtt.connect('mqtt://test.mosquitto.org') client.on('connect', function () { - client.subscribe('presence'); - client.publish('presence', 'Hello mqtt'); -}); + client.subscribe('presence') + client.publish('presence', 'Hello mqtt') +}) client.on('message', function (topic, message) { // message is Buffer - console.log(message.toString()); - client.end(); -}); + console.log(message.toString()) + client.end() +}) ``` output: @@ -225,7 +229,7 @@ version 1.3 and 1.4 works fine without those. #### Event `'connect'` -`function(connack) {}` +`function (connack) {}` Emitted on successful (re)connection (i.e. connack rc=0). * `connack` received connack packet. When `clean` connection option is `false` and server has a previous session @@ -234,32 +238,32 @@ you may rely on stored session and prefer not to send subscribe commands for the #### Event `'reconnect'` -`function() {}` +`function () {}` Emitted when a reconnect starts. #### Event `'close'` -`function() {}` +`function () {}` Emitted after a disconnection. #### Event `'offline'` -`function() {}` +`function () {}` Emitted when the client goes offline. #### Event `'error'` -`function(error) {}` +`function (error) {}` Emitted when the client cannot connect (i.e. connack rc != 0) or when a parsing error occurs. ### Event `'message'` -`function(topic, message, packet) {}` +`function (topic, message, packet) {}` Emitted when the client receives a publish packet * `topic` topic of the received packet @@ -269,7 +273,7 @@ Emitted when the client receives a publish packet ### Event `'packetsend'` -`function(packet) {}` +`function (packet) {}` Emitted when the client sends any packet. This includes .published() packets as well as packets used by MQTT for managing subscriptions and connections @@ -278,7 +282,7 @@ as well as packets used by MQTT for managing subscriptions and connections ### Event `'packetreceive'` -`function(packet) {}` +`function (packet) {}` Emitted when the client receives any packet. This includes packets from subscribed topics as well as packets used by MQTT for managing subscriptions @@ -297,7 +301,7 @@ Publish a message to a topic * `options` is the options to publish with, including: * `qos` QoS level, `Number`, default `0` * `retain` retain flag, `Boolean`, default `false` -* `callback` - `function(err)`, fired when the QoS handling completes, +* `callback` - `function (err)`, fired when the QoS handling completes, or at the next tick if QoS 0. An error occurs if client is disconnecting. ------------------------------------------------------- @@ -311,7 +315,7 @@ Subscribe to a topic or topics keys the topic name and as value the QoS, like `{'test1': 0, 'test2': 1}`. * `options` is the options to subscribe with, including: * `qos` qos subscription level, default 0 -* `callback` - `function(err, granted)` +* `callback` - `function (err, granted)` callback fired on suback where: * `err` a subscription error or an error that occurs when client is disconnecting * `granted` is an array of `{topic, qos}` where: @@ -325,7 +329,7 @@ Subscribe to a topic or topics Unsubscribe from a topic or topics * `topic` is a `String` topic or an array of topics to unsubscribe from -* `callback` - `function(err)`, fired on unsuback. An error occurs if client is disconnecting. +* `callback` - `function (err)`, fired on unsuback. An error occurs if client is disconnecting. ------------------------------------------------------- @@ -436,15 +440,15 @@ you can then use mqtt.js in the browser with the same api than node's one. diff --git a/benchmarks/bombing.js b/benchmarks/bombing.js index 6b4536b40..adef01445 100755 --- a/benchmarks/bombing.js +++ b/benchmarks/bombing.js @@ -1,26 +1,26 @@ #! /usr/bin/env node -var mqtt = require('../'); -var client = mqtt.connect({ port: 1883, host: "localhost", clean: true, keepalive: 0 }); +var mqtt = require('../') +var client = mqtt.connect({ port: 1883, host: 'localhost', clean: true, keepalive: 0 }) -var sent = 0; -var interval = 5000; +var sent = 0 +var interval = 5000 -function count() { - console.log("sent/s", sent / interval * 1000); - sent = 0; +function count () { + console.log('sent/s', sent / interval * 1000) + sent = 0 } setInterval(count, interval) -function publish() { - sent++; - client.publish("test", "payload", publish); +function publish () { + sent++ + client.publish('test', 'payload', publish) } -client.on("connect", publish); +client.on('connect', publish) -client.on("error", function() { - console.log("reconnect!"); - client.stream.end(); -}); +client.on('error', function () { + console.log('reconnect!') + client.stream.end() +}) diff --git a/benchmarks/throughputCounter.js b/benchmarks/throughputCounter.js index a3ba66122..0b778ef2c 100755 --- a/benchmarks/throughputCounter.js +++ b/benchmarks/throughputCounter.js @@ -1,22 +1,22 @@ #! /usr/bin/env node -var mqtt = require('../'); +var mqtt = require('../') -var client = mqtt.connect({ port: 1883, host: "localhost", clean: true, encoding: 'binary', keepalive: 0 }); -var counter = 0; -var interval = 5000; +var client = mqtt.connect({ port: 1883, host: 'localhost', clean: true, encoding: 'binary', keepalive: 0 }) +var counter = 0 +var interval = 5000 -function count() { - console.log("received/s", counter / interval * 1000); - counter = 0; +function count () { + console.log('received/s', counter / interval * 1000) + counter = 0 } -setInterval(count, interval); +setInterval(count, interval) -client.on('connect', function() { - count(); - this.subscribe('test'); - this.on("message", function() { - counter++; - }); -}); +client.on('connect', function () { + count() + this.subscribe('test') + this.on('message', function () { + counter++ + }) +}) diff --git a/bin/pub.js b/bin/pub.js index 0d149aa3b..bc43a83cb 100755 --- a/bin/pub.js +++ b/bin/pub.js @@ -1,40 +1,42 @@ #!/usr/bin/env node -var mqtt = require('../') - , pump = require('pump') - , path = require('path') - , fs = require('fs') - , concat = require('concat-stream') - , Writable = require('readable-stream').Writable - , helpMe = require('help-me')({ - dir: path.join(__dirname, '..', 'doc') - }) - , minimist = require('minimist') - , split2 = require('split2'); - -function send(args) { - var client = mqtt.connect(args); - client.on('connect', function() { - client.publish(args.topic, args.message, args, function(err) { +'use strict' + +var mqtt = require('../') +var pump = require('pump') +var path = require('path') +var fs = require('fs') +var concat = require('concat-stream') +var Writable = require('readable-stream').Writable +var helpMe = require('help-me')({ + dir: path.join(__dirname, '..', 'doc') +}) +var minimist = require('minimist') +var split2 = require('split2') + +function send (args) { + var client = mqtt.connect(args) + client.on('connect', function () { + client.publish(args.topic, args.message, args, function (err) { if (err) { - console.warn(err); + console.warn(err) } - client.end(); - }); - }); - client.on('error', function(err){ - console.warn(err); - client.end(); - }); + client.end() + }) + }) + client.on('error', function (err) { + console.warn(err) + client.end() + }) } function multisend (args) { - var client = mqtt.connect(args); + var client = mqtt.connect(args) var sender = new Writable({ objectMode: true }) sender._write = function (line, enc, cb) { - client.publish(args.topic, line.trim(), args, cb); + client.publish(args.topic, line.trim(), args, cb) } client.on('connect', function () { @@ -47,7 +49,7 @@ function multisend (args) { }) } -function start(args) { +function start (args) { args = minimist(args, { string: ['hostname', 'username', 'password', 'key', 'cert', 'ca', 'message'], integer: ['port', 'qos'], @@ -74,70 +76,70 @@ function start(args) { retain: false, topic: '' } - }); + }) if (args.help) { - return helpMe.toStdout('publish'); + return helpMe.toStdout('publish') } if (args.key) { - args.key = fs.readFileSync(args.key); + args.key = fs.readFileSync(args.key) } if (args.cert) { - args.cert = fs.readFileSync(args.cert); + args.cert = fs.readFileSync(args.cert) } if (args.ca) { - args.ca = fs.readFileSync(args.ca); + args.ca = fs.readFileSync(args.ca) } if (args.key && args.cert && !args.protocol) { args.protocol = 'mqtts' } - if (args.port){ + if (args.port) { if (typeof args.port !== 'number') { - console.warn('# Port: number expected, \'%s\' was given.', typeof args.port); - return; + console.warn('# Port: number expected, \'%s\' was given.', typeof args.port) + return } } if (args['will-topic']) { - args.will = {}; - args.will.topic = args['will-topic']; - args.will.payload = args['will-message']; - args.will.qos = args['will-qos']; - args.will.retain = args['will-retain']; + args.will = {} + args.will.topic = args['will-topic'] + args.will.payload = args['will-message'] + args.will.qos = args['will-qos'] + args.will.retain = args['will-retain'] } if (args.insecure) { - args.rejectUnauthorized = false; + args.rejectUnauthorized = false } - args.topic = (args.topic || args._.shift()).toString(); - args.message = (args.message || args._.shift() || '').toString() || ''; + args.topic = (args.topic || args._.shift()).toString() + args.message = (args.message || args._.shift() || '').toString() || '' if (!args.topic) { - console.error('missing topic\n'); - return helpMe.toStdout('publish'); + console.error('missing topic\n') + return helpMe.toStdout('publish') } if (args.stdin) { if (args.multiline) { multisend(args) } else { - process.stdin.pipe(concat(function(data) { - args.message = data.toString().trim(); - send(args); - })); + process.stdin.pipe(concat(function (data) { + args.message = data.toString().trim() + send(args) + })) } } else { - send(args); + send(args) } } -module.exports = start; +module.exports = start if (require.main === module) { start(process.argv.slice(2)) diff --git a/bin/sub.js b/bin/sub.js index ad7a006f6..5045071bf 100755 --- a/bin/sub.js +++ b/bin/sub.js @@ -1,15 +1,14 @@ #!/usr/bin/env node -var mqtt = require('../') - , path = require('path') - , fs = require('fs') - , concat = require('concat-stream') - , helpMe = require('help-me')({ - dir: path.join(__dirname, '..', 'doc') - }) - , minimist = require('minimist'); - -function start(args) { +var mqtt = require('../') +var path = require('path') +var fs = require('fs') +var helpMe = require('help-me')({ + dir: path.join(__dirname, '..', 'doc') +}) +var minimist = require('minimist') + +function start (args) { args = minimist(args, { string: ['hostname', 'username', 'password', 'key', 'cert', 'ca'], integer: ['port', 'qos', 'keepAlive'], @@ -39,81 +38,86 @@ function start(args) { }) if (args.help) { - return helpMe.toStdout('subscribe'); + return helpMe.toStdout('subscribe') } - args.topic = args.topic || args._.shift(); + args.topic = args.topic || args._.shift() if (!args.topic) { console.error('missing topic\n') - return helpMe.toStdout('subscribe'); + return helpMe.toStdout('subscribe') } if (args.key) { - args.key = fs.readFileSync(args.key); + args.key = fs.readFileSync(args.key) } if (args.cert) { - args.cert = fs.readFileSync(args.cert); + args.cert = fs.readFileSync(args.cert) } if (args.ca) { - args.ca = fs.readFileSync(args.ca); + args.ca = fs.readFileSync(args.ca) } if (args.key && args.cert && !args.protocol) { - args.protocol = 'mqtts'; + args.protocol = 'mqtts' } if (args.insecure) { - args.rejectUnauthorized = false; + args.rejectUnauthorized = false } - if (args.port){ + if (args.port) { if (typeof args.port !== 'number') { - console.warn('# Port: number expected, \'%s\' was given.', typeof args.port); - return; + console.warn('# Port: number expected, \'%s\' was given.', typeof args.port) + return } } if (args['will-topic']) { - args.will = {}; - args.will.topic = args['will-topic']; - args.will.payload = args['will-message']; - args.will.qos = args['will-qos']; - args.will.retain = args['will-retain']; + args.will = {} + args.will.topic = args['will-topic'] + args.will.payload = args['will-message'] + args.will.qos = args['will-qos'] + args.will.retain = args['will-retain'] } - args.keepAlive = args['keep-alive']; + args.keepAlive = args['keep-alive'] - var client = mqtt.connect(args); + var client = mqtt.connect(args) - client.on('connect', function() { + client.on('connect', function () { client.subscribe(args.topic, { qos: args.qos }, function (err, result) { + if (err) { + console.error(err) + process.exit(1) + } + result.forEach(function (sub) { if (sub.qos > 2) { - console.error('subscription negated to', sub.topic, 'with code', sub.qos); - process.exit(1); + console.error('subscription negated to', sub.topic, 'with code', sub.qos) + process.exit(1) } }) - }); - }); + }) + }) - client.on('message', function(topic, payload) { + client.on('message', function (topic, payload) { if (args.verbose) { console.log(topic, payload.toString()) } else { console.log(payload.toString()) } - }); + }) - client.on('error', function(err){ - console.warn(err); - client.end(); - }); + client.on('error', function (err) { + console.warn(err) + client.end() + }) } -module.exports = start; +module.exports = start if (require.main === module) { start(process.argv.slice(2)) diff --git a/example.js b/example.js index ebf1c0f2c..ba14bf949 100644 --- a/example.js +++ b/example.js @@ -1,11 +1,11 @@ -var mqtt = require('./'); -var client = mqtt.connect('mqtt://test.mosquitto.org'); +var mqtt = require('./') +var client = mqtt.connect('mqtt://test.mosquitto.org') -client.subscribe('presence'); -client.publish('presence', 'Hello mqtt'); +client.subscribe('presence') +client.publish('presence', 'Hello mqtt') client.on('message', function (topic, message) { - console.log(message.toString()); -}); + console.log(message.toString()) +}) -client.end(); +client.end() diff --git a/examples/client/secure-client.js b/examples/client/secure-client.js index e7d7c4b81..bf9b6f092 100644 --- a/examples/client/secure-client.js +++ b/examples/client/secure-client.js @@ -1,21 +1,24 @@ +'use strict' -var mqtt = require('../..'); -var KEY = __dirname + '/../../test/helpers/tls-key.pem'; -var CERT = __dirname + '/../../test/helpers/tls-cert.pem'; +var mqtt = require('../..') +var path = require('path') +var fs = require('fs') +var KEY = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'helpers', 'tls-key.pem')) +var CERT = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'helpers', 'tls-cert.pem')) -var PORT = 8443; +var PORT = 8443 var options = { port: PORT, - keyPath: KEY, - certPath: CERT, - rejectUnauthorized : false -}; + key: KEY, + cert: CERT, + rejectUnauthorized: false +} -var client = mqtt.connect(options); +var client = mqtt.connect(options) -client.subscribe('messages'); -client.publish('messages', 'Current time is: ' + new Date()); -client.on('message', function(topic, message) { - console.log(message); -}); +client.subscribe('messages') +client.publish('messages', 'Current time is: ' + new Date()) +client.on('message', function (topic, message) { + console.log(message) +}) diff --git a/examples/client/simple-both.js b/examples/client/simple-both.js index 32b392a0a..8e9268b5f 100644 --- a/examples/client/simple-both.js +++ b/examples/client/simple-both.js @@ -1,11 +1,13 @@ +'use strict' + var mqtt = require('../..') - , host = '192.168.1.100' // or localhost - , client = mqtt.connect(); - // or , client = mqtt.connect({ port: 1883, host: host, keepalive: 10000}); +var client = mqtt.connect() + +// or var client = mqtt.connect({ port: 1883, host: '192.168.1.100', keepalive: 10000}); -client.subscribe('presence'); -client.publish('presence', 'bin hier'); +client.subscribe('presence') +client.publish('presence', 'bin hier') client.on('message', function (topic, message) { - console.log(message); -}); -client.end(); + console.log(message) +}) +client.end() diff --git a/examples/client/simple-publish.js b/examples/client/simple-publish.js index f5ee5fe9a..a8b0f89b6 100644 --- a/examples/client/simple-publish.js +++ b/examples/client/simple-publish.js @@ -1,5 +1,7 @@ +'use strict' + var mqtt = require('../..') - , client = mqtt.connect(); +var client = mqtt.connect() -client.publish('presence', 'hello!'); -client.end(); +client.publish('presence', 'hello!') +client.end() diff --git a/examples/client/simple-subscribe.js b/examples/client/simple-subscribe.js index 444cdb005..7989b9c22 100644 --- a/examples/client/simple-subscribe.js +++ b/examples/client/simple-subscribe.js @@ -1,7 +1,9 @@ +'use strict' + var mqtt = require('../..') - , client = mqtt.connect(); +var client = mqtt.connect() -client.subscribe('presence'); -client.on('message', function(topic, message) { - console.log(message); -}); +client.subscribe('presence') +client.on('message', function (topic, message) { + console.log(message) +}) diff --git a/examples/server/broadcast.js b/examples/server/broadcast.js deleted file mode 100644 index c6b0fae4f..000000000 --- a/examples/server/broadcast.js +++ /dev/null @@ -1,56 +0,0 @@ -/* broadcast.js - all published messages are relayed to all connected clients */ - -var mqtt = require('../..') - , util = require('util'); - -new mqtt.Server(function(client) { - var self = this; - - if (!self.clients) self.clients = {}; - - client.on('connect', function(packet) { - client.connack({returnCode: 0}); - client.id = packet.clientId; - console.log("CONNECT(%s): %j", client.id, packet); - self.clients[client.id] = client; - }); - - client.on('publish', function(packet) { - console.log("PUBLISH(%s): %j", client.id, packet); - for (var k in self.clients) { - self.clients[k].publish({topic: packet.topic, payload: packet.payload}); - } - }); - - client.on('subscribe', function(packet) { - console.log("SUBSCRIBE(%s): %j", client.id, packet); - var granted = []; - for (var i = 0; i < packet.subscriptions.length; i++) { - granted.push(packet.subscriptions[i].qos); - } - - client.suback({granted: granted, messageId: packet.messageId}); - }); - - client.on('pingreq', function(packet) { - console.log('PINGREQ(%s)', client.id); - client.pingresp(); - }); - - client.on('disconnect', function(packet) { - client.stream.end(); - }); - - client.on('close', function(err) { - delete self.clients[client.id]; - }); - - client.on('error', function(err) { - console.log('error!', err); - - if (!self.clients[client.id]) return; - - client.stream.end(); - console.dir(err); - }); -}).listen(process.argv[2] || 1883); diff --git a/examples/server/orig.js b/examples/server/orig.js deleted file mode 100644 index b3d83ad51..000000000 --- a/examples/server/orig.js +++ /dev/null @@ -1,67 +0,0 @@ -var mqtt = require('../..') - , util = require('util'); - -new mqtt.Server(function(client) { - var self = this; - - if (!self.clients) self.clients = {}; - - client.on('connect', function(packet) { - self.clients[packet.clientId] = client; - client.id = packet.clientId; - console.log("CONNECT: client id: " + client.id); - client.subscriptions = []; - client.connack({returnCode: 0}); - }); - - client.on('subscribe', function(packet) { - var granted = []; - - console.log("SUBSCRIBE(%s): %j", client.id, packet); - - for (var i = 0; i < packet.subscriptions.length; i++) { - var qos = packet.subscriptions[i].qos - , topic = packet.subscriptions[i].topic - , reg = new RegExp(topic.replace('+', '[^\/]+').replace('#', '.+') + '$'); - - granted.push(qos); - client.subscriptions.push(reg); - } - - client.suback({messageId: packet.messageId, granted: granted}); - }); - - client.on('publish', function(packet) { - console.log("PUBLISH(%s): %j", client.id, packet); - for (var k in self.clients) { - var c = self.clients[k]; - - for (var i = 0; i < c.subscriptions.length; i++) { - var s = c.subscriptions[i]; - - if (s.test(packet.topic)) { - c.publish({topic: packet.topic, payload: packet.payload}); - break; - } - } - } - }); - - client.on('pingreq', function(packet) { - console.log('PINGREQ(%s)', client.id); - client.pingresp(); - }); - - client.on('disconnect', function(packet) { - client.stream.end(); - }); - - client.on('close', function(packet) { - delete self.clients[client.id]; - }); - - client.on('error', function(e) { - client.stream.end(); - console.log(e); - }); -}).listen(process.argv[2] || 1883); diff --git a/examples/server/redis.js b/examples/server/redis.js deleted file mode 100644 index 7d2d88e03..000000000 --- a/examples/server/redis.js +++ /dev/null @@ -1,48 +0,0 @@ -var mqtt = require('../..') - , redis = require('redis'); - -mqtt.createServer(function(err, client) { - client.p = redis.createClient(null, null, {no_ready_check: true}); - client.s = redis.createClient(null, null, {no_ready_check: true}); - - client.on('connect', function(packet) { - client.connack({returnCode: 0}); - }); - - client.on('subscribe', function(packet) { - var granted = []; - for (var i = 0; i < packet.subscriptions.length; i++) { - var sub = packet.subscriptions[i] - granted.push(sub.qos); - - client.s.psubscribe( - sub.topic - .replace(/\+/g, '[^/]') - .replace(/\#/g, '*') - ); - } - - client.suback({messageId: packet.messageId, granted: granted}); - }); - client.on('publish', function(packet) { - client.p.publish(packet.topic, packet.payload); - }); - client.on('pingreq', function(packet) { - client.pingresp(); - }); - client.on('close', function() { - client.p.end(); - client.s.end(); - }); - client.s.on('pmessage', function(pattern, channel, message) { - client.publish({topic: channel, payload: message}); - }); - client.on('disconnect', function(packet) { - client.stream.end(); - }); - client.on('error', function(e) { - client.stream.end(); - console.log(e); - }); -}).listen(process.argv[2] || 1883); - diff --git a/examples/server/tls.js b/examples/server/tls.js deleted file mode 100644 index a2ff6024d..000000000 --- a/examples/server/tls.js +++ /dev/null @@ -1,52 +0,0 @@ -/* broadcast.js - all published messages are relayed to all connected clients */ - -var mqtt = require('../..'); -var fs = require('fs'); - -new mqtt.SecureServer({ - key: fs.readFileSync("../../test/helpers/private-key.pem"), - cert: fs.readFileSync("../../test/helpers/public-cert.pem") -}, function(client) { - var self = this; - - if (!self.clients) self.clients = {}; - - client.on('connect', function(packet) { - client.connack({returnCode: 0}); - client.id = packet.clientId; - console.log("CONNECT: client id: " + client.id); - self.clients[client.id] = client; - }); - - client.on('publish', function(packet) { - for (var k in self.clients) { - self.clients[k].publish({topic: packet.topic, payload: packet.payload}); - } - }); - - client.on('subscribe', function(packet) { - var granted = []; - for (var i = 0; i < packet.subscriptions.length; i++) { - granted.push(packet.subscriptions[i].qos); - } - - client.suback({granted: granted}); - }); - - client.on('pingreq', function(packet) { - client.pingresp(); - }); - - client.on('disconnect', function(packet) { - client.stream.end(); - }); - - client.on('close', function(err) { - delete self.clients[client.id]; - }); - - client.on('error', function(err) { - client.stream.end(); - util.log('error!'); - }); -}).listen(process.argv[2] || 1883); diff --git a/examples/server/websocket.js b/examples/server/websocket.js deleted file mode 100644 index b296803b2..000000000 --- a/examples/server/websocket.js +++ /dev/null @@ -1,74 +0,0 @@ -var mqtt = require('../..') - , http = require('http') - , util = require('util') - , server = http.createServer(); - -mqtt.attachWebsocketServer(server, handle); - -server.listen(process.argv[2] || 1883); - -function handle(client) { - var self = this; - - if (!self.clients) self.clients = {}; - - client.on('connect', function(packet) { - self.clients[packet.clientId] = client; - client.id = packet.clientId; - console.log("CONNECT: client id: " + client.id); - client.subscriptions = []; - client.connack({returnCode: 0}); - }); - - client.on('subscribe', function(packet) { - var granted = []; - - console.log("SUBSCRIBE(%s): %j", client.id, packet); - - for (var i = 0; i < packet.subscriptions.length; i++) { - var qos = packet.subscriptions[i].qos - , topic = packet.subscriptions[i].topic - , reg = new RegExp(topic.replace('+', '[^\/]+').replace('#', '.+') + '$'); - - granted.push(qos); - client.subscriptions.push(reg); - } - - client.suback({messageId: packet.messageId, granted: granted}); - }); - - client.on('publish', function(packet) { - console.log("PUBLISH(%s): %j", client.id, packet); - for (var k in self.clients) { - var c = self.clients[k]; - - for (var i = 0; i < c.subscriptions.length; i++) { - var s = c.subscriptions[i]; - - if (s.test(packet.topic)) { - c.publish({topic: packet.topic, payload: packet.payload}); - break; - } - } - } - }); - - client.on('pingreq', function(packet) { - console.log('PINGREQ(%s)', client.id); - client.pingresp(); - }); - - client.on('disconnect', function(packet) { - client.stream.end(); - }); - - client.on('close', function(packet) { - delete self.clients[client.id]; - }); - - client.on('error', function(e) { - client.stream.end(); - console.log(e); - }); -} - diff --git a/examples/tls client/mqttclient.js b/examples/tls client/mqttclient.js index cd67dd213..f598292b0 100644 --- a/examples/tls client/mqttclient.js +++ b/examples/tls client/mqttclient.js @@ -1,44 +1,47 @@ -/**************************** IMPORTANT NOTE *********************************** +'use strict' -The certificate used on this example has been generated for a host named stark. -So as host we SHOULD use stark if we want the server to be authorized. -For testing this we should add on the computer running this example a line on -the hosts file: - /etc/hosts [UNIX] - OR - \System32\drivers\etc\hosts [Windows] +/** ************************** IMPORTANT NOTE *********************************** -The line to add on the file should be as follows: - stark -*******************************************************************************/ + The certificate used on this example has been generated for a host named stark. + So as host we SHOULD use stark if we want the server to be authorized. + For testing this we should add on the computer running this example a line on + the hosts file: + /etc/hosts [UNIX] + OR + \System32\drivers\etc\hosts [Windows] -var mqtt = require('mqtt'); -var fs = require('fs'); -var KEY = fs.readFileSync(__dirname + '/tls-key.pem'); -var CERT = fs.readFileSync(__dirname + '/tls-cert.pem'); -var TRUSTED_CA_LIST = fs.readFileSync(__dirname + '/crt.ca.cg.pem'); + The line to add on the file should be as follows: + stark + *******************************************************************************/ -var PORT = 1883; -var HOST = 'stark'; +var mqtt = require('mqtt') +var fs = require('fs') +var path = require('path') +var KEY = fs.readFileSync(path.join(__dirname, '/tls-key.pem')) +var CERT = fs.readFileSync(path.join(__dirname, '/tls-cert.pem')) +var TRUSTED_CA_LIST = fs.readFileSync(path.join(__dirname, '/crt.ca.cg.pem')) + +var PORT = 1883 +var HOST = 'stark' var options = { port: PORT, host: HOST, - keyPath: KEY, - certPath: CERT, - rejectUnauthorized : true, - //The CA list will be used to determine if server is authorized + key: KEY, + cert: CERT, + rejectUnauthorized: true, + // The CA list will be used to determine if server is authorized ca: TRUSTED_CA_LIST -}; +} -var client = mqtt.connect(options); +var client = mqtt.connect(options) -client.subscribe('messages'); -client.publish('messages', 'Current time is: ' + new Date()); -client.on('message', function(topic, message) { - console.log(message); -}); +client.subscribe('messages') +client.publish('messages', 'Current time is: ' + new Date()) +client.on('message', function (topic, message) { + console.log(message) +}) -client.on('connect', function(){ - console.log('Connected'); -}); +client.on('connect', function () { + console.log('Connected') +}) diff --git a/examples/tls server/crt.server1.pem b/examples/tls server/crt.server1.pem deleted file mode 100644 index 1d90704dc..000000000 --- a/examples/tls server/crt.server1.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFlzCCA38CAQIwDQYJKoZIhvcNAQEFBQAwgY0xCzAJBgNVBAYTAkVTMREwDwYD -VQQIDAhaYXJhZ296YTERMA8GA1UEBwwIWmFyYWdvemExGTAXBgNVBAoMEE1RVFQg -Zm9yIG5vZGUuanMxEDAOBgNVBAsMB01RVFQuanMxDTALBgNVBAMMBG1xdHQxHDAa -BgkqhkiG9w0BCQEWDWZha2VAbWFpbC5jb20wHhcNMTMwOTAyMDcyMDQ4WhcNMjMw -ODMxMDcyMDQ4WjCBlDELMAkGA1UEBhMCRVMxETAPBgNVBAgMCFphcmFnb3phMREw -DwYDVQQHDAhaYXJhZ296YTESMBAGA1UECgwJQSBjb21wYW55MRgwFgYDVQQLDA9j -b21wYW55IHNlY3Rpb24xDjAMBgNVBAMMBXN0YXJrMSEwHwYJKoZIhvcNAQkBFhJz -dGFya0BmYWtlbWFpbC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDSMiMuVoQD7WVB4V2ZPsaOf/KBjgsSR548JzAexsALjhIak4MG0P6LMhmfETAv -P9uvEZVh4c2cqW1d+orwQg2I0uZDkz2A7wgNAsGSBeBJ0eRJ80NBnYDbpC5FHl15 -SrDgsSYSCaPnW3br3Fo5bvF+R3jVk4wpbBwg8Hju9dSyY5grda1av5N9NA5Vrw1j -08NnOW7sOuteK8KU8NiUUcf2Ynfi04UgtYs4huIWFYgMoeiSd65DnqsK/Pkh2Lwe -fLIZlwDwqqOFExwvZ2NmmV5ZRbLLObP7OqvbhAZlNN2DsJoCgJase7WC2a0qAKqt -AABFnSRJsvtT6oVh5ty3NL8TG2oeLjcP1l8U3MPQDBEdDcLp6nVf6j9lMx59XWbh -FzrkA8zUsFItIpXMwy44Wg3GNq4BKOLwhapbj6yB9We7llUOaJcsgShJMgxVtUnX -uLLEjOOmpnG6FCfrJqXL9JoRSODkT3F3+36muGXJ7Oal/y+OELV3pXCUtSJ1LlXN -1iLdeKlNXSFpEaWba12dFuZqEajSuWfd0QRXGZq/ivMrEP7sJWXC5o9ePOBtGhc9 -cJshWAPnVh1fsHAlqYBONJzXZNaFyJ4oT+d1Ml1OVXy/54M7rFAspnwgFOh6L+xV -2ug2IJabSq24RNZ8B8QX5Ts7ueMinQDNkVQ+9+PwC89ZUwIDAQABMA0GCSqGSIb3 -DQEBBQUAA4ICAQCNC6wWTU88I/du8rE4qLg6mrJs5q4metxBJ7icarxULwkSYMI2 -XNVF3X0iTkRCpHgjiRKEVDsT3Lvxim8Fpoa7Shh63lfLAv9qglyzlS9POiZmCyEr -X+ly+/z2y7xxQYWWkpiM0wRBdiZ2J+cK+wAi836AAg9Yh42oJrechYucDN91xQTf -Znkru8Zn3EsP+r+pPwtJe9CCc7A3ZqbXX6oajs0xJZCFUH8dshAWYsm/hLS5XRD/ -DvOhRyIZk0KyS/4UfhdPmwg3TkgJn/pNabVhXfc8txIarUtXRAVkzOk4dTGVC6ov -7e+JsVXqq6VVibI+lZNOyrRac5+8as9+ePYGN1O9VJGk5CZgbDGYYlnxH6WPaFAl -UIb6l2ej/+/Q9NJisCA5I8BNGF7fpYYOIlxFL6hj4hhMobJTC+wfXYSHWK1CTJ8Z -8Gx3gBC6f0VUZXBycUsB2ByWB7YZLOdg8HuyY+Y+R0DM38OEsRoEcgLj3pJg57IA -ZaHz51zrenILlKGvv5XRpmNJxPwHt57Wnbi3JFITvY9A2AeYKobux5XpaWyhnueR -JuXYFhaHnZXXu4+L3QXMnYplLTOaRWZMgqJyqF94DAhfZ6K1nfm2EJEfknfM+y/i -PW6v6yPBuY8Z4wig63ZV6YS+V/SE0Ppy3YybcqoJuBu4XNUD161eH1j6vw== ------END CERTIFICATE----- diff --git a/examples/tls server/key.csr.server1.pem b/examples/tls server/key.csr.server1.pem deleted file mode 100644 index 367dd8471..000000000 --- a/examples/tls server/key.csr.server1.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDSMiMuVoQD7WVB -4V2ZPsaOf/KBjgsSR548JzAexsALjhIak4MG0P6LMhmfETAvP9uvEZVh4c2cqW1d -+orwQg2I0uZDkz2A7wgNAsGSBeBJ0eRJ80NBnYDbpC5FHl15SrDgsSYSCaPnW3br -3Fo5bvF+R3jVk4wpbBwg8Hju9dSyY5grda1av5N9NA5Vrw1j08NnOW7sOuteK8KU -8NiUUcf2Ynfi04UgtYs4huIWFYgMoeiSd65DnqsK/Pkh2LwefLIZlwDwqqOFExwv -Z2NmmV5ZRbLLObP7OqvbhAZlNN2DsJoCgJase7WC2a0qAKqtAABFnSRJsvtT6oVh -5ty3NL8TG2oeLjcP1l8U3MPQDBEdDcLp6nVf6j9lMx59XWbhFzrkA8zUsFItIpXM -wy44Wg3GNq4BKOLwhapbj6yB9We7llUOaJcsgShJMgxVtUnXuLLEjOOmpnG6FCfr -JqXL9JoRSODkT3F3+36muGXJ7Oal/y+OELV3pXCUtSJ1LlXN1iLdeKlNXSFpEaWb -a12dFuZqEajSuWfd0QRXGZq/ivMrEP7sJWXC5o9ePOBtGhc9cJshWAPnVh1fsHAl -qYBONJzXZNaFyJ4oT+d1Ml1OVXy/54M7rFAspnwgFOh6L+xV2ug2IJabSq24RNZ8 -B8QX5Ts7ueMinQDNkVQ+9+PwC89ZUwIDAQABAoICABhu34wJXnseY0DPM5QWqfny -gXvxyPOtA4W2gG9zZutw7kXMk9R9ArmnbzcARnuXjq/A+X5RQxdM0nu0HeZjpzMa -YM3GFcYhAuyQP3P73uB113WJI25DIrFlWkOKjg8FUZ4suWIrYLQJ+77a9FnsvYGS -SUd6STafbH2ftk8AoGLEFPIoUahU0I4jOO9Y09Ogz/v1vyESkD14FLw/as2C3B2V -wJ3LPJRaxf4iH7G1ewUM5P3xj34ouXUjhsoaaXOZxxIWbXOMQkm7uPEBsZpBhagW -4/ufj35KiaOQqzWkeYNPSfe0fs856hV1vB0/ypclguKUq50tgu10O2Dv9wQMy5D0 -1K43KMYAgEB8fHY3FqXGkH/TJ7nsNOIFCxFHz4SAI3U3D9EwUv5qOyTHKATLv3kF -1B8hCezhuMe5WgQxCTROgUuuJ3gBmh7PgASXDVPL0uJrP99uwMUj7dBFmSJZSbKk -mfWeT7QkoMzQdfMXz/EXIJZuGRV08Ej4r9v+knzko5eeZ0W+CJFy8nZhK2Mz6L7j -pD/rmP/C6DUw9p8ZERlO8bEppBZ0iY4+1lozXVb8BTRokocnxIDmxI5ubxn02oZo -ZM1p8CYPpb/L7DvyTKFyqp8AO9/6OJ+oRYCYoQbvoqxSPXj4ZJkfb557CaT4NZBR -mkjcFEpqRHfdKHR4tp3RAoIBAQD/2PrF8cMG/g/xRK0KkfAQXxP6t1wGGdweHejK -ypRA+dLrOm801HQsmE5ib0Hn/MWmVikSaUbCO8FDaTV9Nv5IVpGCgj27ObVeH2Nw -LPF2oqVrsHmuZk54Ky7oioOBvUFmemRXs95UNbX4H8paHn3P9yrOYaN2hWjOfQyM -kAuAiV27CNRXM6ixNhTJ99EYPG+DDn7RJTbwnACmbSipt650hf/cGHpVcAl5I+iL -FLDgw9bsVg22KuyYDwUqiLn5MBpU892ZB2SI13wWpvDI356jAsZ+si1qfVMZSkKZ -3PYCJpZpEX6nmTVOcqplkrgI4d7ImgGfdkpceNmMDcJj/cvNAoIBAQDSUjH/QbLs -4BQmz37UKzPN7ldCORs3DkYCe7JiU9aPasIbj8RPVBhbW0iq6w21Mw0ny1g3gbsd -gPgvTe7g/WnoYxgJQsOWvy5ayWPAG8ur9jzmHPlDlLt/ZCnhcerhFYn6Ca0wwcB9 -P1km4FNkK8xGA9hQhmKZUc2S4CBvSDrv5U1msgJsE4pbVKoyTwAbByvO83ZBniUq -eSL+2F2x+kf8JQrSXeGDnOs7nhq2rclXLV8PtJSGFT3Somn9Vg/mDYchHhOPtnzP -vR9ttOQmxbuahvz6tdlkb2FZznG3vpp/g/6V7BpbP3l8HIM+2nkAfV6VY+4Il4jV -UrArpB6yIdmfAoIBAQCUf8V2lQ/FBDwOpvTlOLWlWvpGwJyaMfJQTL3szs5kNF0X -CXC4skPICpMckUUouM+j70ihlhdq77IKRYu1ZPEM3apRnPTlseYyfneCCaQRXvAy -5FiMQHd1SmNMt/ECoe3O5GVPfmgiapZ3MUSLMD2IMwdWiNePGHovt+dLwuPaNGEC -CWruPl7AlQpV/BASSCnVYNl83WPZHkNGVf+PGr0YhxpuDosbAg+Nj6kO6PCNVT5v -KLeGr71puPYfrQJ8v03ZVz6c7uyMfL5ai4UgoqL6LMc3jIXN1HYiLLchhV4I+4q7 -61qfPs7w/J8om5NUHH3p43Hjs44PxFlI8EePMCVVAoIBAQC8ghd15fjs/tqQ/qF6 -oU5JYTqsjGqsKgrt5ti38NT6roFUGsOlJoa+O08igpNCuYMtC8EB3zFK/HF2VK+q -0Pe/5jGA+2o7DxgJH0Bcy4z9kDJ9PbLcs85qG+i9vFD9dUS56zpj3QUePU023xFf -UzI//uo/InP1X7CV2HS5yU+p/Sgmx54MKGd1/KifdtdtYjwNvYFcxtYg/3oyWNOB -1gX3JWxRqPub72WXhdoDqjgv/uaZOQ12MEu9Iv1Ep4KQe8eGE2MNCE9OEwC8X8mu -RsQjeKH+REeZEYt75uFeA2SOrkvdLEVjS70jVJr+FuslWTkRRQPwh4GJUhe8xdkN -Z/GZAoIBACYkRvJLbQip32q2as5h6D/5WM3STn9aX2jDFdMh4ynalhZYepglwRd5 -5qvlKYAzTb4HvQ7PjtwdiBTnxx68HzgEhLKDsyBgeeYn9ymZHIMMuJmsKc4xspK8 -gol37gkB4MGXHtyua+5rwoeTebDuaVY1mVuwBVtUa0kUCZo50SohcX4pWoRJLuZh -JuuV1oXV/vtZ/XR0e4xV5eKhYjvq7gVKN6Tn79mfZISdqH+RDEK88hGRJ/JlVj1X -Zzp+S4J8GbaPtQNUeNdgNZldJ4W/Exu7ssxfsD6iOKXWmywRn2v0QEt5yBCWG+8Z -itinBdRtqOiQFrOR/zJawjCYf27k3Yw= ------END PRIVATE KEY----- diff --git a/examples/tls server/mqttserver.js b/examples/tls server/mqttserver.js deleted file mode 100644 index 7bb8e1c19..000000000 --- a/examples/tls server/mqttserver.js +++ /dev/null @@ -1,48 +0,0 @@ -var mqtt = require('../../'); -var fs = require('fs'); - -new mqtt.SecureServer({ - key: fs.readFileSync(__dirname + '/key.csr.server1.pem'), - cert: fs.readFileSync(__dirname + '/crt.server1.pem'), -}, function(client) { - var self = this; - - if (!self.clients) self.clients = {}; - - client.on('connect', function(packet) { - client.connack({returnCode: 0}); - client.id = packet.clientId; - self.clients[client.id] = client; - }); - - client.on('publish', function(packet) { - for (var k in self.clients) { - self.clients[k].publish({topic: packet.topic, payload: packet.payload}); - } - }); - - client.on('subscribe', function(packet) { - var granted = []; - for (var i = 0; i < packet.subscriptions.length; i++) { - granted.push(packet.subscriptions[i].qos); - } - client.suback({granted: granted, messageId: packet.messageId}); - }); - - client.on('pingreq', function(packet) { - client.pingresp(); - }); - - client.on('disconnect', function(packet) { - client.stream.end(); - }); - - client.on('close', function(err) { - delete self.clients[client.id]; - }); - - client.on('error', function(err) { - client.stream.end(); - console.log('error!'); - }); -}).listen(1883); diff --git a/examples/wss/client.js b/examples/wss/client.js index f11375196..c0d1d4379 100644 --- a/examples/wss/client.js +++ b/examples/wss/client.js @@ -1,47 +1,49 @@ -var mqtt = require('mqtt'); +'use strict' -var client_Id = 'mqttjs_' + Math.random().toString(16).substr(2, 8); +var mqtt = require('mqtt') -var host = 'wss://localhost:3001/Mosca'; +var clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8) + +var host = 'wss://localhost:3001/Mosca' var options = { - keepalive: 10, - clientId: client_Id, - protocolId: 'MQTT', - protocolVersion: 4, - clean: true, - reconnectPeriod: 1000, - connectTimeout: 30 * 1000, - will: { - topic: 'WillMsg', - payload: 'Connection Closed abnormally..!', - qos: 0, - retain: false - }, - username: 'demo', - password: 'demo', - rejectUnauthorized: false, -}; - -var client = mqtt.connect(host, options); + keepalive: 10, + clientId: clientId, + protocolId: 'MQTT', + protocolVersion: 4, + clean: true, + reconnectPeriod: 1000, + connectTimeout: 30 * 1000, + will: { + topic: 'WillMsg', + payload: 'Connection Closed abnormally..!', + qos: 0, + retain: false + }, + username: 'demo', + password: 'demo', + rejectUnauthorized: false +} + +var client = mqtt.connect(host, options) client.on('error', function (err) { - console.log(err); - client.end(); -}); + console.log(err) + client.end() +}) client.on('connect', function () { - console.log('client connected:' + client_Id); -}); + console.log('client connected:' + clientId) +}) -client.subscribe("topic", { qos: 0 }); +client.subscribe('topic', { qos: 0 }) -client.publish("topic", "wss secure connection demo...!", { qos: 0, retained: false }); +client.publish('topic', 'wss secure connection demo...!', { qos: 0, retained: false }) client.on('message', function (topic, message, pakcet) { - console.log("Received Message:= " + message.toString() + "\nOn topic:= " + topic); -}); + console.log('Received Message:= ' + message.toString() + '\nOn topic:= ' + topic) +}) client.on('close', function () { - console.log(client_Id + " disconnected"); -}); + console.log(clientId + ' disconnected') +}) diff --git a/lib/client.js b/lib/client.js index 67d69b789..1aa4e1fee 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1,53 +1,53 @@ -'use strict'; +'use strict' + /** * Module dependencies */ -/*global setImmediate:true*/ -var events = require('events'), - Store = require('./store'), - eos = require('end-of-stream'), - mqttPacket = require('mqtt-packet'), - Writable = require('readable-stream').Writable, - inherits = require('inherits'), - reInterval = require('reinterval'), - validations = require('./validations'), - setImmediate = global.setImmediate || function (callback) { - // works in node v0.8 - process.nextTick(callback); - }, - defaultConnectOptions = { - keepalive: 60, - reschedulePings: true, - protocolId: 'MQTT', - protocolVersion: 4, - reconnectPeriod: 1000, - connectTimeout: 30 * 1000, - clean: true - }; +var events = require('events') +var Store = require('./store') +var eos = require('end-of-stream') +var mqttPacket = require('mqtt-packet') +var Writable = require('readable-stream').Writable +var inherits = require('inherits') +var reInterval = require('reinterval') +var validations = require('./validations') +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 +} function defaultId () { - return 'mqttjs_' + Math.random().toString(16).substr(2, 8); + return 'mqttjs_' + Math.random().toString(16).substr(2, 8) } function sendPacket (client, packet, cb) { - client.emit('packetsend', packet); + client.emit('packetsend', packet) - var result = mqttPacket.writeToStream(packet, client.stream); + var result = mqttPacket.writeToStream(packet, client.stream) if (!result && cb) { - client.stream.once('drain', cb); + client.stream.once('drain', cb) } else if (cb) { - cb(); + cb() } } function storeAndSend (client, packet, cb) { client.outgoingStore.put(packet, function storedPacket (err) { if (err) { - return cb && cb(err); + return cb && cb(err) } - sendPacket(client, packet, cb); - }); + sendPacket(client, packet, cb) + }) } function nop () {} @@ -60,147 +60,148 @@ function nop () {} * (see Connection#connect) */ function MqttClient (streamBuilder, options) { - var k, - that = this; + var k + var that = this if (!(this instanceof MqttClient)) { - return new MqttClient(streamBuilder, options); + return new MqttClient(streamBuilder, options) } - this.options = options || {}; + this.options = options || {} // Defaults for (k in defaultConnectOptions) { - if ('undefined' === typeof this.options[k]) { - this.options[k] = defaultConnectOptions[k]; + if (typeof this.options[k] === 'undefined') { + this.options[k] = defaultConnectOptions[k] } else { - this.options[k] = options[k]; + this.options[k] = options[k] } } - this.options.clientId = this.options.clientId || defaultId(); + this.options.clientId = this.options.clientId || defaultId() - this.streamBuilder = streamBuilder; + this.streamBuilder = streamBuilder // Inflight message storages - this.outgoingStore = this.options.outgoingStore || new Store(); - this.incomingStore = this.options.incomingStore || new Store(); + this.outgoingStore = this.options.outgoingStore || new Store() + this.incomingStore = this.options.incomingStore || new Store() // Should QoS zero messages be queued when the connection is broken? - this.queueQoSZero = null == this.options.queueQoSZero ? true : this.options.queueQoSZero; + this.queueQoSZero = this.options.queueQoSZero === undefined ? true : this.options.queueQoSZero // Ping timer, setup in _setupPingTimer - this.pingTimer = null; + this.pingTimer = null // Is the client connected? - this.connected = false; + this.connected = false // Are we disconnecting? - this.disconnecting = false; + this.disconnecting = false // Packet queue - this.queue = []; + this.queue = [] // connack timer - this.connackTimer = null; + this.connackTimer = null // Reconnect timer - this.reconnectTimer = null; + this.reconnectTimer = null // MessageIDs starting with 1 - this.nextId = Math.floor(Math.random() * 65535); + this.nextId = Math.floor(Math.random() * 65535) // Inflight callbacks - this.outgoing = {}; + this.outgoing = {} // Mark connected on connect this.on('connect', function () { if (this.disconnected) { - return; + return } - this.connected = true; - var outStore = null; - outStore = this.outgoingStore.createStream(); + this.connected = true + var outStore = null + outStore = this.outgoingStore.createStream() // Control of stored messages outStore.once('readable', function () { function storeDeliver () { - var packet = outStore.read(1), - cb; + var packet = outStore.read(1) + var cb + if (!packet) { - return; + return } + // Avoid unnecesary stream read operations when disconnected - if (!that.disconnecting && !that.reconnectTimer && (0 < that.options.reconnectPeriod)) { - outStore.read(0); - cb = that.outgoing[packet.messageId]; + if (!that.disconnecting && !that.reconnectTimer && that.options.reconnectPeriod > 0) { + outStore.read(0) + cb = that.outgoing[packet.messageId] that.outgoing[packet.messageId] = function () { // Ensure that the original callback passed in to publish gets invoked if (cb) { - cb(); + cb() } // Ensure that the next message will only be read after callback is issued - storeDeliver(); - }; - that._sendPacket(packet); + storeDeliver() + } + that._sendPacket(packet) } else if (outStore.destroy) { - outStore.destroy(); + outStore.destroy() } } - storeDeliver(); + storeDeliver() }) - .on('error', this.emit.bind(this, 'error')); - }); + .on('error', this.emit.bind(this, 'error')) + }) // Mark disconnected on stream close this.on('close', function () { - this.connected = false; - clearTimeout(this.connackTimer); - }); + this.connected = false + clearTimeout(this.connackTimer) + }) // Setup ping timer - this.on('connect', this._setupPingTimer); + this.on('connect', this._setupPingTimer) // Send queued packets this.on('connect', function () { - var queue = this.queue; + var queue = this.queue function deliver () { - var entry = queue.shift(), - packet = null; + var entry = queue.shift() + var packet = null if (!entry) { - return; + return } - packet = entry.packet; + packet = entry.packet that._sendPacket( packet, function (err) { if (entry.cb) { - entry.cb(err); + entry.cb(err) } - deliver(); + deliver() } - ); + ) } - deliver(); - }); - + deliver() + }) // Clear ping timer this.on('close', function () { - if (null !== that.pingTimer) { - that.pingTimer.clear(); - that.pingTimer = null; + if (that.pingTimer !== null) { + that.pingTimer.clear() + that.pingTimer = null } - }); + }) // Setup reconnect timer on disconnect - this.on('close', this._setupReconnect); + this.on('close', this._setupReconnect) - events.EventEmitter.call(this); + events.EventEmitter.call(this) - this._setupStream(); + this._setupStream() } -inherits(MqttClient, events.EventEmitter); +inherits(MqttClient, events.EventEmitter) /** * setup the event handlers in the inner stream. @@ -208,108 +209,109 @@ inherits(MqttClient, events.EventEmitter); * @api private */ MqttClient.prototype._setupStream = function () { - var connectPacket, - that = this, - writable = new Writable(), - parser = mqttPacket.parser(this.options), - completeParse = null, - packets = []; + var connectPacket + var that = this + var writable = new Writable() + var parser = mqttPacket.parser(this.options) + var completeParse = null + var packets = [] - this._clearReconnect(); + this._clearReconnect() - this.stream = this.streamBuilder(this); + this.stream = this.streamBuilder(this) parser.on('packet', function (packet) { - packets.push(packet); - }); + packets.push(packet) + }) function process () { - var packet = packets.shift(), - done = completeParse; + var packet = packets.shift() + var done = completeParse + if (packet) { - that._handlePacket(packet, process); + that._handlePacket(packet, process) } else { - completeParse = null; - done(); + completeParse = null + done() } } writable._write = function (buf, enc, done) { - completeParse = done; - parser.parse(buf); - process(); - }; + completeParse = done + parser.parse(buf) + process() + } - this.stream.pipe(writable); + this.stream.pipe(writable) // Suppress connection errors - this.stream.on('error', nop); + this.stream.on('error', nop) // Echo stream close - eos(this.stream, this.emit.bind(this, 'close')); + eos(this.stream, this.emit.bind(this, 'close')) // Send a connect packet - connectPacket = Object.create(this.options); - connectPacket.cmd = 'connect'; + connectPacket = Object.create(this.options) + connectPacket.cmd = 'connect' // avoid message queue - sendPacket(this, connectPacket); + sendPacket(this, connectPacket) // Echo connection errors - parser.on('error', this.emit.bind(this, 'error')); + parser.on('error', this.emit.bind(this, 'error')) // many drain listeners are needed for qos 1 callbacks if the connection is intermittent - this.stream.setMaxListeners(1000); + this.stream.setMaxListeners(1000) - clearTimeout(this.connackTimer); + clearTimeout(this.connackTimer) this.connackTimer = setTimeout(function () { - that._cleanUp(true); - }, this.options.connectTimeout); -}; + that._cleanUp(true) + }, this.options.connectTimeout) +} MqttClient.prototype._handlePacket = function (packet, done) { - this.emit('packetreceive', packet); + this.emit('packetreceive', packet) switch (packet.cmd) { case 'publish': - this._handlePublish(packet, done); - break; + this._handlePublish(packet, done) + break case 'puback': case 'pubrec': case 'pubcomp': case 'suback': case 'unsuback': - this._handleAck(packet); - done(); - break; + this._handleAck(packet) + done() + break case 'pubrel': - this._handlePubrel(packet, done); - break; + this._handlePubrel(packet, done) + break case 'connack': - this._handleConnack(packet); - done(); - break; + this._handleConnack(packet) + done() + break case 'pingresp': - this._handlePingresp(packet); - done(); - break; + this._handlePingresp(packet) + done() + break default: // do nothing // maybe we should do an error handling // or just log it - break; + break } -}; +} MqttClient.prototype._checkDisconnecting = function (callback) { if (this.disconnecting) { if (callback) { - callback(new Error('client disconnecting')); + callback(new Error('client disconnecting')) } else { - this.emit('error', new Error('client disconnecting')); + this.emit('error', new Error('client disconnecting')) } } - return this.disconnecting; -}; + return this.disconnecting +} /** * publish - publish to @@ -330,21 +332,21 @@ MqttClient.prototype._checkDisconnecting = function (callback) { * @example client.publish('topic', 'message', console.log); */ MqttClient.prototype.publish = function (topic, message, opts, callback) { - var packet; + var packet // .publish(topic, payload, cb); - if ('function' === typeof opts) { - callback = opts; - opts = null; + if (typeof opts === 'function') { + callback = opts + opts = null } // Default opts if (!opts) { - opts = {qos: 0, retain: false}; + opts = {qos: 0, retain: false} } if (this._checkDisconnecting(callback)) { - return this; + return this } packet = { @@ -354,23 +356,23 @@ MqttClient.prototype.publish = function (topic, message, opts, callback) { qos: opts.qos, retain: opts.retain, messageId: this._nextId() - }; + } switch (opts.qos) { case 1: case 2: // Add to callbacks - this.outgoing[packet.messageId] = callback || nop; - this._sendPacket(packet); - break; + this.outgoing[packet.messageId] = callback || nop + this._sendPacket(packet) + break default: - this._sendPacket(packet, callback); - break; + this._sendPacket(packet, callback) + break } - return this; -}; + return this +} /** * subscribe - subscribe to @@ -389,35 +391,35 @@ MqttClient.prototype.publish = function (topic, message, opts, callback) { * @example client.subscribe('topic', console.log); */ MqttClient.prototype.subscribe = function () { - var packet, - args = Array.prototype.slice.call(arguments), - subs = [], - obj = args.shift(), - callback = args.pop() || nop, - opts = args.pop(), - invalidTopic; + var packet + var args = Array.prototype.slice.call(arguments) + var subs = [] + var obj = args.shift() + var callback = args.pop() || nop + var opts = args.pop() + var invalidTopic - if ('string' === typeof obj) { - obj = [obj]; + if (typeof obj === 'string') { + obj = [obj] } - if ('function' !== typeof callback) { - opts = callback; - callback = nop; + if (typeof callback !== 'function') { + opts = callback + callback = nop } - invalidTopic = validations.validateTopics(obj); - if ( null !== invalidTopic ) { - callback(new Error('Invalid topic ' + invalidTopic)); - return this; + invalidTopic = validations.validateTopics(obj) + if (invalidTopic !== null) { + callback(new Error('Invalid topic ' + invalidTopic)) + return this } if (this._checkDisconnecting(callback)) { - return this; + return this } if (!opts) { - opts = { qos: 0 }; + opts = { qos: 0 } } if (Array.isArray(obj)) { @@ -425,8 +427,8 @@ MqttClient.prototype.subscribe = function () { subs.push({ topic: topic, qos: opts.qos - }); - }); + }) + }) } else { Object .keys(obj) @@ -434,8 +436,8 @@ MqttClient.prototype.subscribe = function () { subs.push({ topic: k, qos: obj[k] - }); - }); + }) + }) } packet = { @@ -445,14 +447,14 @@ MqttClient.prototype.subscribe = function () { retain: false, dup: false, messageId: this._nextId() - }; + } - this.outgoing[packet.messageId] = callback; + this.outgoing[packet.messageId] = callback - this._sendPacket(packet); + this._sendPacket(packet) - return this; -}; + return this +} /** * unsubscribe - unsubscribe from topic(s) @@ -469,26 +471,26 @@ MqttClient.prototype.unsubscribe = function (topic, callback) { cmd: 'unsubscribe', qos: 1, messageId: this._nextId() - }; + } - callback = callback || nop; + callback = callback || nop if (this._checkDisconnecting(callback)) { - return this; + return this } - if ('string' === typeof topic) { - packet.unsubscriptions = [topic]; - } else if ('object' === typeof topic && topic.length) { - packet.unsubscriptions = topic; + if (typeof topic === 'string') { + packet.unsubscriptions = [topic] + } else if (typeof topic === 'object' && topic.length) { + packet.unsubscriptions = topic } - this.outgoing[packet.messageId] = callback; + this.outgoing[packet.messageId] = callback - this._sendPacket(packet); + this._sendPacket(packet) - return this; -}; + return this +} /** * end - close connection @@ -500,94 +502,92 @@ MqttClient.prototype.unsubscribe = function (topic, callback) { * @api public */ MqttClient.prototype.end = function (force, cb) { - var that = this; + var that = this - if ('function' === typeof force) { - cb = force; - force = false; + if (typeof force === 'function') { + cb = force + force = false } function closeStores () { - that.disconnected = true; + that.disconnected = true that.incomingStore.close(function () { - that.outgoingStore.close(cb); - }); + that.outgoingStore.close(cb) + }) } function finish () { // defer closesStores of an I/O cycle, // just to make sure things are // ok for websockets - that._cleanUp(force, setImmediate.bind(null, closeStores)); + that._cleanUp(force, setImmediate.bind(null, closeStores)) } if (this.disconnecting) { - return this; + return this } - this._clearReconnect(); + this._clearReconnect() - this.disconnecting = true; + this.disconnecting = true - if (!force && 0 < Object.keys(this.outgoing).length) { + if (!force && Object.keys(this.outgoing).length > 0) { // wait 10ms, just to be sure we received all of it - this.once('outgoingEmpty', setTimeout.bind(null, finish, 10)); + this.once('outgoingEmpty', setTimeout.bind(null, finish, 10)) } else { - finish(); + finish() } - return this; -}; + return this +} /** * _reconnect - implement reconnection * @api privateish */ MqttClient.prototype._reconnect = function () { - this.emit('reconnect'); - this._setupStream(); -}; + this.emit('reconnect') + this._setupStream() +} /** * _setupReconnect - setup reconnect timer */ MqttClient.prototype._setupReconnect = function () { - var that = this; + var that = this - if (!that.disconnecting && !that.reconnectTimer && (0 < that.options.reconnectPeriod)) { + if (!that.disconnecting && !that.reconnectTimer && (that.options.reconnectPeriod > 0)) { if (!this.reconnecting) { - this.emit('offline'); - this.reconnecting = true; + this.emit('offline') + this.reconnecting = true } that.reconnectTimer = setInterval(function () { - that._reconnect(); - }, that.options.reconnectPeriod); + that._reconnect() + }, that.options.reconnectPeriod) } -}; +} /** * _clearReconnect - clear the reconnect timer */ MqttClient.prototype._clearReconnect = function () { if (this.reconnectTimer) { - clearInterval(this.reconnectTimer); - this.reconnectTimer = null; + clearInterval(this.reconnectTimer) + this.reconnectTimer = null } -}; - +} /** * _cleanUp - clean up on connection end * @api private */ MqttClient.prototype._cleanUp = function (forced, done) { - if (done) { - this.stream.on('close', done); + this.stream.on('close', done) } if (forced) { - this.stream.destroy(); + this.stream.destroy() } else { this._sendPacket( { cmd: 'disconnect' }, @@ -595,19 +595,19 @@ MqttClient.prototype._cleanUp = function (forced, done) { null, this.stream.end.bind(this.stream) ) - ); + ) } if (!this.disconnecting) { - this._clearReconnect(); - this._setupReconnect(); + this._clearReconnect() + this._setupReconnect() } - if (null !== this.pingTimer) { - this.pingTimer.clear(); - this.pingTimer = null; + if (this.pingTimer !== null) { + this.pingTimer.clear() + this.pingTimer = null } -}; +} /** * _sendPacket - send or queue a packet @@ -618,23 +618,23 @@ MqttClient.prototype._cleanUp = function (forced, done) { */ MqttClient.prototype._sendPacket = function (packet, cb) { if (!this.connected) { - if (0 < packet.qos || 'publish' !== packet.cmd || this.queueQoSZero) { - this.queue.push({ packet: packet, cb: cb }); + if (packet.qos > 0 || packet.cmd !== 'publish' || this.queueQoSZero) { + this.queue.push({ packet: packet, cb: cb }) } else if (cb) { - cb(new Error('No connection to broker')); + cb(new Error('No connection to broker')) } - return; + return } // When sending a packet, reschedule the ping timer - this._shiftPingInterval(); + this._shiftPingInterval() switch (packet.qos) { case 2: case 1: - storeAndSend(this, packet, cb); - break; + storeAndSend(this, packet, cb) + break /** * no need of case here since it will be caught by default * and jshint comply that before default it must be a break @@ -643,10 +643,10 @@ MqttClient.prototype._sendPacket = function (packet, cb) { case 0: /* falls through */ default: - sendPacket(this, packet, cb); - break; + sendPacket(this, packet, cb) + break } -}; +} /** * _setupPingTimer - setup the ping timer @@ -654,15 +654,15 @@ MqttClient.prototype._sendPacket = function (packet, cb) { * @api private */ MqttClient.prototype._setupPingTimer = function () { - var that = this; + var that = this if (!this.pingTimer && this.options.keepalive) { - this.pingResp = true; + this.pingResp = true this.pingTimer = reInterval(function () { - that._checkPing(); - }, this.options.keepalive * 1000); + that._checkPing() + }, this.options.keepalive * 1000) } -}; +} /** * _shiftPingInterval - reschedule the ping interval @@ -671,9 +671,9 @@ MqttClient.prototype._setupPingTimer = function () { */ MqttClient.prototype._shiftPingInterval = function () { if (this.pingTimer && this.options.keepalive && this.options.reschedulePings) { - this.pingTimer.reschedule(this.options.keepalive * 1000); + this.pingTimer.reschedule(this.options.keepalive * 1000) } -}; +} /** * _checkPing - check if a pingresp has come back, and ping the server again * @@ -681,13 +681,13 @@ MqttClient.prototype._shiftPingInterval = function () { */ MqttClient.prototype._checkPing = function () { if (this.pingResp) { - this.pingResp = false; - this._sendPacket({ cmd: 'pingreq' }); + this.pingResp = false + this._sendPacket({ cmd: 'pingreq' }) } else { // do a forced cleanup since socket will be in bad shape - this._cleanUp(true); + this._cleanUp(true) } -}; +} /** * _handlePingresp - handle a pingresp @@ -695,8 +695,8 @@ MqttClient.prototype._checkPing = function () { * @api private */ MqttClient.prototype._handlePingresp = function () { - this.pingResp = true; -}; + this.pingResp = true +} /** * _handleConnack @@ -706,27 +706,25 @@ MqttClient.prototype._handlePingresp = function () { */ MqttClient.prototype._handleConnack = function (packet) { - var rc = packet.returnCode, - // TODO: move to protocol - errors = [ - '', - 'Unacceptable protocol version', - 'Identifier rejected', - 'Server unavailable', - 'Bad username or password', - 'Not authorized' - ]; - - clearTimeout(this.connackTimer); - - if (0 === rc) { - this.reconnecting = false; - this.emit('connect', packet); - } else if (0 < rc) { - this.emit('error', - new Error('Connection refused: ' + errors[rc])); - } -}; + var rc = packet.returnCode + var errors = [ + '', + 'Unacceptable protocol version', + 'Identifier rejected', + 'Server unavailable', + 'Bad username or password', + 'Not authorized' + ] + + clearTimeout(this.connackTimer) + + if (rc === 0) { + this.reconnecting = false + this.emit('connect', packet) + } else if (rc > 0) { + this.emit('error', new Error('Connection refused: ' + errors[rc])) + } +} /** * _handlePublish @@ -759,37 +757,37 @@ default: for now i just suppressed the warnings */ MqttClient.prototype._handlePublish = function (packet, done) { - var topic = packet.topic.toString(), - message = packet.payload, - qos = packet.qos, - mid = packet.messageId, - that = this; + var topic = packet.topic.toString() + var message = packet.payload + var qos = packet.qos + var mid = packet.messageId + var that = this switch (qos) { case 2: this.incomingStore.put(packet, function () { - that._sendPacket({cmd: 'pubrec', messageId: mid}, done); - }); - break; + that._sendPacket({cmd: 'pubrec', messageId: mid}, done) + }) + break case 1: // do not wait sending a puback // no callback passed this._sendPacket({ cmd: 'puback', messageId: mid - }); + }) /* falls through */ case 0: // emit the message event for both qos 1 and 0 - this.emit('message', topic, message, packet); - this.handleMessage(packet, done); - break; + this.emit('message', topic, message, packet) + this.handleMessage(packet, done) + break default: // do nothing // log or throw an error about unknown qos - break; + break } -}; +} /** * Handle messages with backpressure support, one at a time. @@ -800,8 +798,8 @@ MqttClient.prototype._handlePublish = function (packet, done) { * @api public */ MqttClient.prototype.handleMessage = function (packet, callback) { - callback(); -}; + callback() +} /** * _handleAck @@ -811,15 +809,16 @@ MqttClient.prototype.handleMessage = function (packet, callback) { */ MqttClient.prototype._handleAck = function (packet) { - var mid = packet.messageId, - type = packet.cmd, - response = null, - cb = this.outgoing[mid], - that = this; + /* eslint no-fallthrough: "off" */ + var mid = packet.messageId + var type = packet.cmd + var response = null + var cb = this.outgoing[mid] + var that = this if (!cb) { // Server sent an ack in error, ignore it. - return; + return } // Process @@ -828,50 +827,49 @@ MqttClient.prototype._handleAck = function (packet) { // same thing as puback for QoS 2 case 'puback': // Callback - we're done - delete this.outgoing[mid]; - this.outgoingStore.del(packet, cb); - break; + delete this.outgoing[mid] + this.outgoingStore.del(packet, cb) + break case 'pubrec': response = { cmd: 'pubrel', qos: 2, messageId: mid - }; + } - this._sendPacket(response); - break; + this._sendPacket(response) + break case 'suback': - delete this.outgoing[mid]; + delete this.outgoing[mid] this.outgoingStore.del(packet, function (err, original) { if (err) { // missing packet, what should we do? - return that.emit('error', err); + return that.emit('error', err) } - var i, - origSubs = original.subscriptions, - granted = packet.granted; + var origSubs = original.subscriptions + var granted = packet.granted - for (i = 0; i < granted.length; i += 1) { - origSubs[i].qos = granted[i]; + for (var i = 0; i < granted.length; i += 1) { + origSubs[i].qos = granted[i] } - cb(null, origSubs); - }); - break; + cb(null, origSubs) + }) + break case 'unsuback': - delete this.outgoing[mid]; - this.outgoingStore.del(packet, cb); - break; + delete this.outgoing[mid] + this.outgoingStore.del(packet, cb) + break default: - that.emit('error', new Error('unrecognized packet type')); + that.emit('error', new Error('unrecognized packet type')) } if (this.disconnecting && - 0 === Object.keys(this.outgoing).length) { - this.emit('outgoingEmpty'); + Object.keys(this.outgoing).length === 0) { + this.emit('outgoingEmpty') } -}; +} /** * _handlePubrel @@ -881,33 +879,33 @@ MqttClient.prototype._handleAck = function (packet) { */ MqttClient.prototype._handlePubrel = function (packet, callback) { - var mid = packet.messageId, - that = this; + var mid = packet.messageId + var that = this that.incomingStore.get(packet, function (err, pub) { if (err) { - return that.emit('error', err); + return that.emit('error', err) } - if ('pubrel' !== pub.cmd) { - that.emit('message', pub.topic, pub.payload, pub); - that.incomingStore.put(packet); + if (pub.cmd !== 'pubrel') { + that.emit('message', pub.topic, pub.payload, pub) + that.incomingStore.put(packet) } - that._sendPacket({cmd: 'pubcomp', messageId: mid}, callback); - }); -}; + that._sendPacket({cmd: 'pubcomp', messageId: mid}, callback) + }) +} /** * _nextId */ MqttClient.prototype._nextId = function () { - var id = this.nextId++; + var id = this.nextId++ // Ensure 16 bit unsigned int: - if (65535 === id) { - this.nextId = 1; + if (id === 65535) { + this.nextId = 1 } - return id; -}; + return id +} -module.exports = MqttClient; +module.exports = MqttClient diff --git a/lib/connect/index.js b/lib/connect/index.js index 7891c7e12..c6874634e 100644 --- a/lib/connect/index.js +++ b/lib/connect/index.js @@ -1,28 +1,28 @@ -'use strict'; -var MqttClient = require('../client'), - url = require('url'), - xtend = require('xtend'), - protocols = {}, - protocolList = []; - -if ('browser' !== process.title) { - protocols.mqtt = require('./tcp'); - protocols.tcp = require('./tcp'); - protocols.ssl = require('./tls'); - protocols.tls = require('./tls'); - protocols.mqtts = require('./tls'); +'use strict' + +var MqttClient = require('../client') +var url = require('url') +var xtend = require('xtend') +var protocols = {} +var protocolList = [] + +if (process.title !== 'browser') { + protocols.mqtt = require('./tcp') + protocols.tcp = require('./tcp') + protocols.ssl = require('./tls') + protocols.tls = require('./tls') + protocols.mqtts = require('./tls') } -protocols.ws = require('./ws'); -protocols.wss = require('./ws'); +protocols.ws = require('./ws') +protocols.wss = require('./ws') protocolList = [ 'mqtt', 'mqtts', 'ws', 'wss' -]; - +] /** * Parse the auth attribute and merge username and password in the options object. @@ -30,14 +30,14 @@ protocolList = [ * @param {Object} [opts] option object */ function parseAuthOptions (opts) { - var matches; + var matches if (opts.auth) { - matches = opts.auth.match(/^(.+):(.+)$/); + matches = opts.auth.match(/^(.+):(.+)$/) if (matches) { - opts.username = matches[1]; - opts.password = matches[2]; + opts.username = matches[1] + opts.password = matches[2] } else { - opts.username = opts.auth; + opts.username = opts.auth } } } @@ -49,30 +49,29 @@ function parseAuthOptions (opts) { * @param {Object} opts - see MqttClient#constructor */ function connect (brokerUrl, opts) { - - if (('object' === typeof brokerUrl) && !opts) { - opts = brokerUrl; - brokerUrl = null; + if ((typeof brokerUrl === 'object') && !opts) { + opts = brokerUrl + brokerUrl = null } - opts = opts || {}; + opts = opts || {} if (brokerUrl) { - opts = xtend(url.parse(brokerUrl, true), opts); - opts.protocol = opts.protocol.replace(/\:$/, ''); + opts = xtend(url.parse(brokerUrl, true), opts) + opts.protocol = opts.protocol.replace(/:$/, '') } // merge in the auth options if supplied - parseAuthOptions(opts); + parseAuthOptions(opts) // support clientId passed in the query string of the url - if (opts.query && 'string' === typeof opts.query.clientId) { - opts.clientId = opts.query.clientId; + if (opts.query && typeof opts.query.clientId === 'string') { + opts.clientId = opts.query.clientId } if (opts.cert && opts.key) { if (opts.protocol) { - if (-1 === ['mqtts', 'wss'].indexOf(opts.protocol)) { + if (['mqtts', 'wss'].indexOf(opts.protocol) === -1) { /* * jshint and eslint * complains that break from default cannot be reached after throw @@ -80,58 +79,57 @@ function connect (brokerUrl, opts) { * maybe add a check after switch to see if it went through default * and then throw the error */ - /*jshint -W027*/ - /*eslint no-unreachable:1*/ + /* jshint -W027 */ + /* eslint no-unreachable:1 */ switch (opts.protocol) { case 'mqtt': - opts.protocol = 'mqtts'; - break; + opts.protocol = 'mqtts' + break case 'ws': - opts.protocol = 'wss'; - break; + opts.protocol = 'wss' + break default: - throw new Error('Unknown protocol for secure connection: "' + opts.protocol + '"!'); - break; + throw new Error('Unknown protocol for secure connection: "' + opts.protocol + '"!') + break } - /*eslint no-unreachable:0*/ - /*jshint +W027*/ + /* eslint no-unreachable:0 */ + /* jshint +W027 */ } } else { // don't know what protocol he want to use, mqtts or wss - throw new Error('Missing secure protocol key'); + throw new Error('Missing secure protocol key') } } if (!protocols[opts.protocol]) { opts.protocol = protocolList.filter(function (key) { - return 'function' === typeof protocols[key]; - })[0]; + return typeof protocols[key] === 'function' + })[0] } - if (false === opts.clean && !opts.clientId) { - throw new Error('Missing clientId for unclean clients'); + if (opts.clean === false && !opts.clientId) { + throw new Error('Missing clientId for unclean clients') } - function wrapper (client) { if (opts.servers) { if (!client._reconnectCount || client._reconnectCount === opts.servers.length) { - client._reconnectCount = 0; + client._reconnectCount = 0 } - opts.host = opts.servers[client._reconnectCount].host; - opts.port = opts.servers[client._reconnectCount].port; - opts.hostname = opts.host; + opts.host = opts.servers[client._reconnectCount].host + opts.port = opts.servers[client._reconnectCount].port + opts.hostname = opts.host - client._reconnectCount++; + client._reconnectCount++ } - return protocols[opts.protocol](client, opts); + return protocols[opts.protocol](client, opts) } - return new MqttClient(wrapper, opts); + return new MqttClient(wrapper, opts) } -module.exports = connect; -module.exports.connect = connect; -module.exports.MqttClient = MqttClient; +module.exports = connect +module.exports.connect = connect +module.exports.MqttClient = MqttClient diff --git a/lib/connect/tcp.js b/lib/connect/tcp.js index ac61ea8e8..b47770db9 100644 --- a/lib/connect/tcp.js +++ b/lib/connect/tcp.js @@ -1,19 +1,19 @@ -'use strict'; -var net = require('net'); +'use strict' +var net = require('net') /* variables port and host can be removed since you have all required information in opts object */ function buildBuilder (client, opts) { - var port, host; - opts.port = opts.port || 1883; - opts.hostname = opts.hostname || opts.host || 'localhost'; + var port, host + opts.port = opts.port || 1883 + opts.hostname = opts.hostname || opts.host || 'localhost' - port = opts.port; - host = opts.hostname; + port = opts.port + host = opts.hostname - return net.createConnection(port, host); + return net.createConnection(port, host) } -module.exports = buildBuilder; +module.exports = buildBuilder diff --git a/lib/connect/tls.js b/lib/connect/tls.js index 74f6e949c..f4913e6e6 100644 --- a/lib/connect/tls.js +++ b/lib/connect/tls.js @@ -1,35 +1,27 @@ -'use strict'; -var tls = require('tls'); +'use strict' +var tls = require('tls') function buildBuilder (mqttClient, opts) { - var connection; - opts.port = opts.port || 8883; - opts.host = opts.hostname || opts.host || 'localhost'; + var connection + opts.port = opts.port || 8883 + opts.host = opts.hostname || opts.host || 'localhost' - opts.rejectUnauthorized = false !== opts.rejectUnauthorized; + opts.rejectUnauthorized = opts.rejectUnauthorized !== false - connection = tls.connect(opts); - /*eslint no-use-before-define: [2, "nofunc"]*/ + 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')); + connection.emit('error', new Error('TLS not authorized')) } else { - connection.removeListener('error', handleTLSerrors); + connection.removeListener('error', handleTLSerrors) } - }); + }) - /* - * to comply with strict rules, a function must be - * declared before it can be used - * so i moved it has to be moved before its first call - * later on maybe we can move all of them to the top of the file - * for now i just suppressed the warning - */ - /*jshint latedef:false*/ function handleTLSerrors (err) { // How can I get verify this error is a tls error? if (opts.rejectUnauthorized) { - mqttClient.emit('error', err); + mqttClient.emit('error', err) } // close this connection to match the behaviour of net @@ -37,12 +29,11 @@ function buildBuilder (mqttClient, opts) { // 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.end() } - /*jshint latedef:false*/ - connection.on('error', handleTLSerrors); - return connection; + connection.on('error', handleTLSerrors) + return connection } -module.exports = buildBuilder; +module.exports = buildBuilder diff --git a/lib/connect/ws.js b/lib/connect/ws.js index 629176743..f0226a273 100644 --- a/lib/connect/ws.js +++ b/lib/connect/ws.js @@ -1,85 +1,89 @@ -'use strict'; +'use strict' -var websocket = require('websocket-stream'), - _URL = require('url'), - wssProperties = [ - 'rejectUnauthorized', - 'ca', - 'cert', - 'key', - 'pfx', - 'passphrase' - ]; +var websocket = require('websocket-stream') +var _URL = require('url') +var wssProperties = [ + 'rejectUnauthorized', + 'ca', + 'cert', + 'key', + 'pfx', + 'passphrase' +] function buildBuilder (client, opts) { var wsOpt = { - protocol: 'mqtt' - }, - host = opts.hostname || 'localhost', - port = String(opts.port || 80), - path = opts.path || '/', - url = opts.protocol + '://' + host + ':' + port + path; - if (('MQIsdp' === opts.protocolId) && (3 === opts.protocolVersion)) { - wsOpt.protocol = 'mqttv3.1'; + protocol: 'mqtt' } + var host = opts.hostname || 'localhost' + var port = String(opts.port || 80) + var path = opts.path || '/' + var url = opts.protocol + '://' + host + ':' + port + path - if ('wss' === opts.protocol) { + if ((opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3)) { + wsOpt.protocol = 'mqttv3.1' + } + + if (opts.protocol === 'wss') { wssProperties.forEach(function (prop) { if (opts.hasOwnProperty(prop)) { - wsOpt[prop] = opts[prop]; + wsOpt[prop] = opts[prop] } - }); + }) } - return websocket(url, wsOpt); + return websocket(url, wsOpt) } function buildBuilderBrowser (mqttClient, opts) { - var url, parsed; - if ('undefined' !== typeof (document)) { // for Web Workers! P.S: typeof(document) !== undefined may be becoming the faster one these days. - parsed = _URL.parse(document.URL); + var url + var parsed + + // for Web Workers! P.S: typeof(document) !== undefined may be becoming the faster one these days. + if (typeof (document) !== 'undefined') { + parsed = _URL.parse(document.URL) } else { - throw new Error('Could not determine host. Specify host manually.'); + throw new Error('Could not determine host. Specify host manually.') } if (!opts.protocol) { - if ('https:' === parsed.protocol) { - opts.protocol = 'wss'; + if (parsed.protocol === 'https:') { + opts.protocol = 'wss' } else { - opts.protocol = 'ws'; + opts.protocol = 'ws' } } if (!opts.hostname) { - opts.hostname = opts.host; + opts.hostname = opts.host } if (!opts.hostname) { - opts.hostname = parsed.hostname; + opts.hostname = parsed.hostname if (!opts.port) { - opts.port = parsed.port; + opts.port = parsed.port } } if (!opts.port) { - if ('wss' === opts.protocol) { - opts.port = 443; + if (opts.protocol === 'wss') { + opts.port = 443 } else { - opts.port = 80; + opts.port = 80 } } if (!opts.path) { - opts.path = '/'; + opts.path = '/' } - url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path; + url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path - return websocket(url, 'mqttv3.1'); + return websocket(url, 'mqttv3.1') } -if ('browser' !== process.title) { - module.exports = buildBuilder; +if (process.title !== 'browser') { + module.exports = buildBuilder } else { - module.exports = buildBuilderBrowser; + module.exports = buildBuilderBrowser } diff --git a/lib/store.js b/lib/store.js index baaf20a75..8df8c27a7 100644 --- a/lib/store.js +++ b/lib/store.js @@ -1,6 +1,7 @@ -'use strict'; -var Readable = require('readable-stream').Readable, - streamsOpts = { objectMode: true }; +'use strict' + +var Readable = require('readable-stream').Readable +var streamsOpts = { objectMode: true } /** * In-memory implementation of the message store @@ -9,10 +10,10 @@ var Readable = require('readable-stream').Readable, */ function Store () { if (!(this instanceof Store)) { - return new Store(); + return new Store() } - this._inflights = {}; + this._inflights = {} } /** @@ -21,88 +22,88 @@ function Store () { * */ Store.prototype.put = function (packet, cb) { - this._inflights[packet.messageId] = packet; + this._inflights[packet.messageId] = packet if (cb) { - cb(); + cb() } - return this; -}; + return this +} /** * Creates a stream with all the packets in the store * */ Store.prototype.createStream = function () { - var stream = new Readable(streamsOpts), - inflights = this._inflights, - ids = Object.keys(this._inflights), - destroyed = false, - i = 0; + var stream = new Readable(streamsOpts) + var inflights = this._inflights + var ids = Object.keys(this._inflights) + var destroyed = false + var i = 0 stream._read = function () { if (!destroyed && i < ids.length) { - this.push(inflights[ids[i++]]); + this.push(inflights[ids[i++]]) } else { - this.push(null); + this.push(null) } - }; + } stream.destroy = function () { if (destroyed) { - return; + return } - var self = this; + var self = this - destroyed = true; + destroyed = true process.nextTick(function () { - self.emit('close'); - }); - }; + self.emit('close') + }) + } - return stream; -}; + return stream +} /** * deletes a packet from the store. */ Store.prototype.del = function (packet, cb) { - packet = this._inflights[packet.messageId]; + packet = this._inflights[packet.messageId] if (packet) { - delete this._inflights[packet.messageId]; - cb(null, packet); + delete this._inflights[packet.messageId] + cb(null, packet) } else if (cb) { - cb(new Error('missing packet')); + cb(new Error('missing packet')) } - return this; -}; + return this +} /** * get a packet from the store. */ Store.prototype.get = function (packet, cb) { - packet = this._inflights[packet.messageId]; + packet = this._inflights[packet.messageId] if (packet) { - cb(null, packet); + cb(null, packet) } else if (cb) { - cb(new Error('missing packet')); + cb(new Error('missing packet')) } - return this; -}; + return this +} /** * Close the store */ Store.prototype.close = function (cb) { - this._inflights = null; + this._inflights = null if (cb) { - cb(); + cb() } -}; +} -module.exports = Store; +module.exports = Store diff --git a/lib/validations.js b/lib/validations.js index ccdf777b8..edd07fe39 100644 --- a/lib/validations.js +++ b/lib/validations.js @@ -1,6 +1,4 @@ -'use strict'; -/*eslint no-unused-expressions:0*/ -/*jshint expr:true*/ +'use strict' /** * Validate a topic to see if it's valid or not. @@ -12,25 +10,24 @@ * @returns {Boolean} If the topic is valid, returns true. Otherwise, returns false. */ function validateTopic (topic) { - var parts = topic.split('/'), - i = 0; + var parts = topic.split('/') - for (i = 0; i < parts.length; i++) { - if ('+' === parts[i]) { - continue; + for (var i = 0; i < parts.length; i++) { + if (parts[i] === '+') { + continue } - if ('#' === parts[i] ) { + if (parts[i] === '#') { // for Rule #2 - return i === parts.length - 1; + return i === parts.length - 1 } - if ( -1 !== parts[i].indexOf('+') || -1 !== parts[i].indexOf('#')) { - return false; + if (parts[i].indexOf('+') !== -1 || parts[i].indexOf('#') !== -1) { + return false } } - return true; + return true } /** @@ -40,13 +37,13 @@ function validateTopic (topic) { */ function validateTopics (topics) { for (var i = 0; i < topics.length; i++) { - if ( !validateTopic(topics[i]) ) { - return topics[i]; + if (!validateTopic(topics[i])) { + return topics[i] } } - return null; + return null } module.exports = { validateTopics: validateTopics -}; +} diff --git a/mqtt.js b/mqtt.js index 5bebf04d5..d60f7bd6f 100755 --- a/mqtt.js +++ b/mqtt.js @@ -1,38 +1,41 @@ #!/usr/bin/env node -'use strict'; +'use strict' + /* - * Copyright (c) 2011 Adam Rudd. + * Copyright (c) 2015-2015 MQTT.js contributors. + * Copyright (c) 2011-2014 Adam Rudd. + * * See LICENSE for more information */ -var MqttClient = require('./lib/client'), - connect = require('./lib/connect'), - Store = require('./lib/store'); +var MqttClient = require('./lib/client') +var connect = require('./lib/connect') +var Store = require('./lib/store') -module.exports.connect = connect; +module.exports.connect = connect // Expose MqttClient -module.exports.MqttClient = MqttClient; -module.exports.Client = MqttClient; -module.exports.Store = Store; +module.exports.MqttClient = MqttClient +module.exports.Client = MqttClient +module.exports.Store = Store function cli () { - var commist = require('commist')(), - helpMe = require('help-me')(); + var commist = require('commist')() + var helpMe = require('help-me')() - commist.register('publish', require('./bin/pub')); - commist.register('subscribe', require('./bin/sub')); + commist.register('publish', require('./bin/pub')) + commist.register('subscribe', require('./bin/sub')) commist.register('version', function () { - console.log('MQTT.js version:', require('./package.json').version); - }); - commist.register('help', helpMe.toStdout); + console.log('MQTT.js version:', require('./package.json').version) + }) + commist.register('help', helpMe.toStdout) - if (null !== commist.parse(process.argv.slice(2))) { - console.log('No such command:', process.argv[2], '\n'); - helpMe.toStdout(); + if (commist.parse(process.argv.slice(2)) !== null) { + console.log('No such command:', process.argv[2], '\n') + helpMe.toStdout() } } if (require.main === module) { - cli(); + cli() } diff --git a/package.json b/package.json index af8bafc00..b493b9fc1 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,7 @@ "main": "mqtt.js", "scripts": { "test": "mocha", - "pretest": "npm run check-style", - "check-style:eslint": "eslint mqtt.js lib test test/browser test/helpers", - "check-style:jshint": "jshint mqtt.js lib test test/browser test/helpers", - "check-style:jscs": "jscs mqtt.js lib test test/browser test/helpers", - "check-style": "npm run check-style:jshint && npm run check-style:jscs && npm run check-style:eslint", + "pretest": "standard", "browser-test": "zuul --server test/browser/server.js --local --open test/browser/test.js", "sauce-test": "zuul --server test/browser/server.js --tunnel ngrok -- test/browser/test.js" }, @@ -53,9 +49,8 @@ "inherits": "^2.0.1", "minimist": "^1.1.0", "mqtt-packet": "^4.0.0", - "readable-stream": "^2.0.0", - "pump": "^1.0.1", "readable-stream": "~1.0.2", + "pump": "^1.0.1", "reinterval": "^1.0.1", "split2": "^2.0.1", "websocket-stream": "^3.1.0", @@ -63,18 +58,24 @@ }, "devDependencies": { "browserify": "^11.0.1", - "eslint": "^1.3.1", - "jscs": "^2.1.1", - "jshint": "2.7.0", "mocha": "*", + "mqtt-connection": "^2.0.0", "pre-commit": "1.1.1", "should": "*", "sinon": "~1.10.0", + "standard": "^8.0.0", "through2": "^2.0.0", - "mqtt-connection": "^2.0.0", "uglify": "^0.1.1", "ws": "^0.8.0", "zuul": "^3.4.0", "zuul-ngrok": "gnandretta/zuul-ngrok#upgrade-ngrok" + }, + "standard": { + "globals": [ + "it", + "describe", + "beforeEach", + "afterEach" + ] } } diff --git a/test/abstract_client.js b/test/abstract_client.js index 56e59521b..a70aacb4f 100644 --- a/test/abstract_client.js +++ b/test/abstract_client.js @@ -1,302 +1,288 @@ -'use strict'; +'use strict' -/*global setImmediate:true*/ -/*eslint no-unused-expressions:0*/ -/*jshint expr:true*/ /** * Testing dependencies */ -var should = require('should'), - sinon = require('sinon'), - mqtt = require('../'), - xtend = require('xtend'), - setImmediate = global.setImmediate || function (callback) { - // for node v0.8 support - process.nextTick(callback); - }; +var should = require('should') +var sinon = require('sinon') +var mqtt = require('../') +var xtend = require('xtend') module.exports = function (server, config) { function connect (opts) { - opts = xtend(config, opts); - return mqtt.connect(opts); + opts = xtend(config, opts) + return mqtt.connect(opts) } describe('closing', function () { it('should emit close if stream closes', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - client.stream.end(); - }); + client.stream.end() + }) client.once('close', function () { - client.end(); - done(); - }); - }); + client.end() + done() + }) + }) it('should mark the client as disconnected', function (done) { - var client = connect(); + var client = connect() client.once('close', function () { - client.end(); + client.end() if (!client.connected) { - done(); + done() } else { - done(new Error('Not marked as disconnected')); + done(new Error('Not marked as disconnected')) } - }); + }) client.once('connect', function () { - client.stream.end(); - }); - }); + client.stream.end() + }) + }) it('should stop ping timer if stream closes', function (done) { - var client = connect(); + var client = connect() client.once('close', function () { - should.not.exist(client.pingTimer); - client.end(); - done(); - }); + should.not.exist(client.pingTimer) + client.end() + done() + }) client.once('connect', function () { - should.exist(client.pingTimer); - client.stream.end(); - }); - }); + should.exist(client.pingTimer) + client.stream.end() + }) + }) it('should emit close after end called', function (done) { - var client = connect(); + var client = connect() client.once('close', function () { - done(); - }); + done() + }) client.once('connect', function () { - client.end(); - }); - }); + client.end() + }) + }) it('should return `this` if end called twice', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - client.end(); - var value = client.end(); + client.end() + var value = client.end() if (value === client) { - done(); + done() } else { - done(new Error('Not returning client.')); + done(new Error('Not returning client.')) } - }); - }); + }) + }) it('should stop ping timer after end called', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - should.exist(client.pingTimer); - client.end(); - should.not.exist(client.pingTimer); - done(); - }); - }); - }); + should.exist(client.pingTimer) + client.end() + should.not.exist(client.pingTimer) + done() + }) + }) + }) describe('connecting', function () { - it('should connect to the broker', function (done) { - var client = connect(); - client.on('error', done); + var client = connect() + client.on('error', done) server.once('client', function () { - client.end(); - done(); - }); - }); + client.end() + done() + }) + }) it('should send a default client id', function (done) { - var client = connect(); - client.on('error', done); + var client = connect() + client.on('error', done) server.once('client', function (serverClient) { serverClient.once('connect', function (packet) { - packet.clientId.should.match(/mqttjs.*/); - serverClient.disconnect(); - done(); - }); - }); - }); + packet.clientId.should.match(/mqttjs.*/) + serverClient.disconnect() + done() + }) + }) + }) it('should send be clean by default', function (done) { - var client = connect(); - client.on('error', done); + var client = connect() + client.on('error', done) server.once('client', function (serverClient) { serverClient.once('connect', function (packet) { - packet.clean.should.be.true; - serverClient.disconnect(); - done(); - }); - }); - }); + packet.clean.should.be.true + serverClient.disconnect() + done() + }) + }) + }) it('should connect with the given client id', function (done) { - var client = connect({clientId: 'testclient'}); + var client = connect({clientId: 'testclient'}) client.on('error', function (err) { - throw err; - }); + throw err + }) server.once('client', function (serverClient) { serverClient.once('connect', function (packet) { - packet.clientId.should.match(/testclient/); - serverClient.disconnect(); - done(); - }); - }); - }); + packet.clientId.should.match(/testclient/) + serverClient.disconnect() + done() + }) + }) + }) it('should connect with the client id and unclean state', function (done) { - var client = connect({clientId: 'testclient', clean: false}); + var client = connect({clientId: 'testclient', clean: false}) client.on('error', function (err) { - throw err; - }); + throw err + }) server.once('client', function (serverClient) { serverClient.once('connect', function (packet) { - packet.clientId.should.match(/testclient/); - packet.clean.should.be.false; - serverClient.disconnect(); - done(); - }); - }); - }); + packet.clientId.should.match(/testclient/) + packet.clean.should.be.false + serverClient.disconnect() + done() + }) + }) + }) it('should require a clientId with clean=false', function (done) { try { - var client = connect({ clean: false }); + var client = connect({ clean: false }) client.on('error', function (err) { - done(err); + done(err) // done(new Error('should have thrown')); - }); + }) } catch (err) { - done(); + done() } - }); + }) it('should default to localhost', function (done) { - var client = connect({clientId: 'testclient'}); + var client = connect({clientId: 'testclient'}) client.on('error', function (err) { - throw err; - }); + throw err + }) server.once('client', function (serverClient) { serverClient.once('connect', function (packet) { - packet.clientId.should.match(/testclient/); - serverClient.disconnect(); - done(); - }); - }); - }); + packet.clientId.should.match(/testclient/) + serverClient.disconnect() + done() + }) + }) + }) it('should emit connect', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - client.end(); - done(); - }); - client.once('error', done); - }); + client.end() + done() + }) + client.once('error', done) + }) it('should provide connack packet with connect event', function (done) { server.once('client', function (serverClient) { - serverClient.connack({returnCode: 0, sessionPresent: true}); + serverClient.connack({returnCode: 0, sessionPresent: true}) server.once('client', function (serverClient) { - serverClient.connack({returnCode: 0, sessionPresent: false}); - }); - }); + serverClient.connack({returnCode: 0, sessionPresent: false}) + }) + }) - var client = connect(); + var client = connect() client.once('connect', function (packet) { - should(packet.sessionPresent).be.equal(true); + should(packet.sessionPresent).be.equal(true) client.once('connect', function (packet) { - should(packet.sessionPresent).be.equal(false); - client.end(); - done(); - }); - }); - }); + should(packet.sessionPresent).be.equal(false) + client.end() + done() + }) + }) + }) it('should mark the client as connected', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - client.end(); + client.end() if (client.connected) { - done(); + done() } else { - done(new Error('Not marked as connected')); + done(new Error('Not marked as connected')) } - }); - }); + }) + }) it('should emit error', function (done) { - var client = connect({clientId: 'invalid'}); + var client = connect({clientId: 'invalid'}) client.once('connect', function () { - done(new Error('Should not emit connect')); - }); + done(new Error('Should not emit connect')) + }) client.once('error', function (/* error */) { // to do // check for error message // and validate it is the expected one - client.end(); - done(); - }); - }); + client.end() + done() + }) + }) it('should have different client ids', function (done) { - var client1 = connect(), - client2 = connect(); + var client1 = connect() + var client2 = connect() - client1.options.clientId.should.not.equal(client2.options.clientId); - client1.end(true); - client2.end(true); - setImmediate(done); - }); - }); + client1.options.clientId.should.not.equal(client2.options.clientId) + client1.end(true) + client2.end(true) + setImmediate(done) + }) + }) describe('handling offline states', function () { - // big question why this does not work on v0.10 - // disabled, as it will hit deprecation soon - if (process.version && 0 !== process.version.indexOf('v0.10')) { - it('should emit offline events once when the client transitions from connected states to disconnected ones', function (done) { - - var client = connect({reconnectPeriod: 20}); + it('should emit offline events once when the client transitions from connected states to disconnected ones', function (done) { + var client = connect({reconnectPeriod: 20}) - client.on('connect', function () { - this.stream.end(); - }); + client.on('connect', function () { + this.stream.end() + }) - client.on('offline', function () { - client.end(true, done); - }); - }); - } + client.on('offline', function () { + client.end(true, done) + }) + }) it('should emit offline events once when the client (at first) can NOT connect to servers', function (done) { // fake a port - var client = connect({ reconnectPeriod: 20, port: 4557 }); + var client = connect({ reconnectPeriod: 20, port: 4557 }) client.on('offline', function () { - client.end(true, done); - }); - }); - }); + client.end(true, done) + }) + }) + }) describe('topic validations when subscribing', function () { - it('should be ok for well-formated topics', function (done) { - var client = connect(); + var client = connect() client.subscribe( [ '+', '+/event', 'event/+', '#', 'event/#', 'system/event/+', @@ -304,1206 +290,1197 @@ module.exports = function (server, config) { 'system/registry/event/new_device', 'system/+/+/new_device' ], function (err) { - client.end(); + client.end() if (err) { - return done(new Error(err)); + return done(new Error(err)) } - done(); + done() } - ); - }); + ) + }) it('should return an error (via callbacks) for topic #/event', function (done) { - var client = connect(); - client.subscribe( ['#/event', 'event#', 'event+'], function (err) { - client.end(); + var client = connect() + client.subscribe(['#/event', 'event#', 'event+'], function (err) { + client.end() if (err) { - return done(); + return done() } - done(new Error('Validations do NOT work')); - }); - }); + done(new Error('Validations do NOT work')) + }) + }) it('should return an error (via callbacks) for topic #/event', function (done) { - var client = connect(); - client.subscribe( '#/event', function (err) { - client.end(); + var client = connect() + client.subscribe('#/event', function (err) { + client.end() if (err) { - return done(); + return done() } - done(new Error('Validations do NOT work')); - }); - }); + done(new Error('Validations do NOT work')) + }) + }) it('should return an error (via callbacks) for topic event#', function (done) { - var client = connect(); - client.subscribe( 'event#', function (err) { - client.end(); + var client = connect() + client.subscribe('event#', function (err) { + client.end() if (err) { - return done(); + return done() } - done(new Error('Validations do NOT work')); - }); - }); + done(new Error('Validations do NOT work')) + }) + }) it('should return an error (via callbacks) for topic system/#/event', function (done) { - var client = connect(); - client.subscribe( 'system/#/event', function (err) { - client.end(); + var client = connect() + client.subscribe('system/#/event', function (err) { + client.end() if (err) { - return done(); + return done() } - done(new Error('Validations do NOT work')); - }); - }); + done(new Error('Validations do NOT work')) + }) + }) it('should return an error (via callbacks) for topic system/+/#/event', function (done) { - var client = connect(); - client.subscribe( 'system/+/#/event', function (err) { - client.end(); + var client = connect() + client.subscribe('system/+/#/event', function (err) { + client.end() if (err) { - return done(); + return done() } - done(new Error('Validations do NOT work')); - }); - }); - - }); + done(new Error('Validations do NOT work')) + }) + }) + }) describe('offline messages', function () { - it('should queue message until connected', function (done) { - var client = connect(); + var client = connect() - client.publish('test', 'test'); - client.subscribe('test'); - client.unsubscribe('test'); - client.queue.length.should.equal(3); + client.publish('test', 'test') + client.subscribe('test') + client.unsubscribe('test') + client.queue.length.should.equal(3) client.once('connect', function () { - client.queue.length.should.equal(0); - client.end(true, done); - }); - }); + client.queue.length.should.equal(0) + client.end(true, done) + }) + }) it('should not queue qos 0 messages if queueQoSZero is false', function (done) { - var client = connect({queueQoSZero: false}); + var client = connect({queueQoSZero: false}) - client.publish('test', 'test', {qos: 0}); - client.queue.length.should.equal(0); - client.end(true, done); - }); + client.publish('test', 'test', {qos: 0}) + client.queue.length.should.equal(0) + client.end(true, done) + }) it('should still queue qos != 0 messages if queueQoSZero is false', function (done) { - var client = connect({queueQoSZero: false}); + var client = connect({queueQoSZero: false}) - client.publish('test', 'test', {qos: 1}); - client.publish('test', 'test', {qos: 2}); - client.subscribe('test'); - client.unsubscribe('test'); - client.queue.length.should.equal(4); - client.end(true, done); - }); + client.publish('test', 'test', {qos: 1}) + client.publish('test', 'test', {qos: 2}) + client.subscribe('test') + client.unsubscribe('test') + client.queue.length.should.equal(4) + client.end(true, done) + }) it('should call cb if an outgoing QoS 0 message is not sent', function (done) { - var client = connect({queueQoSZero: false}); + var client = connect({queueQoSZero: false}) client.publish('test', 'test', {qos: 0}, function () { - client.end(true, done); - }); - }); + client.end(true, done) + }) + }) if (!process.env.TRAVIS) { - it('should delay closing everything up until the queue is depleted', function (done) { - var client = connect(); - - client.subscribe('test'); - client.publish('test', 'test'); - client.end(); - - client.once('message', function () { - done(); - }); - - server.once('client', function (serverClient) { - serverClient.on('subscribe', function () { - serverClient.on('publish', function (packet) { - serverClient.publish(packet); - }); - }); - }); - }); - it('should delay ending up until all inflight messages are delivered', function (done) { - var client = connect(); + var client = connect() client.on('connect', function () { client.subscribe('test', function () { - done(); - }); + done() + }) client.publish('test', 'test', function () { - client.end(); - }); - }); - }); + client.end() + }) + }) + }) it('wait QoS 1 publish messages', function (done) { - var client = connect(); + var client = connect() client.on('connect', function () { - client.subscribe('test'); + client.subscribe('test') client.publish('test', 'test', { qos: 1 }, function () { - client.end(); - }); + client.end() + }) client.on('message', function () { - done(); - }); - }); + done() + }) + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { serverClient.on('publish', function (packet) { - serverClient.publish(packet); - }); - }); - }); - }); + serverClient.publish(packet) + }) + }) + }) + }) it('does not wait acks when force-closing', function (done) { // non-running broker - var client = connect('mqtt://localhost:8993'); + var client = connect('mqtt://localhost:8993') - client.publish('test', 'test', { qos: 1 }); - client.end(true, done); - }); + client.publish('test', 'test', { qos: 1 }) + client.end(true, done) + }) } - }); + }) describe('publishing', function () { it('should publish a message (offline)', function (done) { - var client = connect(), - payload = 'test', - topic = 'test'; + var client = connect() + var payload = 'test' + var topic = 'test' - client.publish(topic, payload); + client.publish(topic, payload) server.once('client', function (serverClient) { serverClient.once('publish', function (packet) { - packet.topic.should.equal(topic); - packet.payload.toString().should.equal(payload); - packet.qos.should.equal(0); - packet.retain.should.equal(false); - client.end(); - done(); - }); - }); - }); + packet.topic.should.equal(topic) + packet.payload.toString().should.equal(payload) + packet.qos.should.equal(0) + packet.retain.should.equal(false) + client.end() + done() + }) + }) + }) it('should publish a message (online)', function (done) { - var client = connect(), - payload = 'test', - topic = 'test'; + var client = connect() + var payload = 'test' + var topic = 'test' client.on('connect', function () { - client.publish(topic, payload); - }); + client.publish(topic, payload) + }) server.once('client', function (serverClient) { serverClient.once('publish', function (packet) { - packet.topic.should.equal(topic); - packet.payload.toString().should.equal(payload); - packet.qos.should.equal(0); - packet.retain.should.equal(false); - client.end(); - done(); - }); - }); - }); + packet.topic.should.equal(topic) + packet.payload.toString().should.equal(payload) + packet.qos.should.equal(0) + packet.retain.should.equal(false) + client.end() + done() + }) + }) + }) it('should emit a packetsend event', function (done) { - var client = connect(), - payload = 'test_payload', - test_topic = 'test_topic'; + var client = connect() + var payload = 'test_payload' + var testTopic = 'testTopic' client.on('packetsend', function (packet) { - if ('publish' === packet.cmd) { - packet.qos.should.equal(0); - packet.topic.should.equal(test_topic); - packet.payload.should.equal(payload); - packet.retain.should.equal(false); - client.end(); - done(); + if (packet.cmd === 'publish') { + packet.qos.should.equal(0) + packet.topic.should.equal(testTopic) + packet.payload.should.equal(payload) + packet.retain.should.equal(false) + client.end() + done() } - }); + }) - client.publish(test_topic, payload); - }); + client.publish(testTopic, payload) + }) it('should accept options', function (done) { - var client = connect(), - payload = 'test', - topic = 'test', - opts = { - retain: true, - qos: 1 - }; + var client = connect() + var payload = 'test' + var topic = 'test' + var opts = { + retain: true, + qos: 1 + } client.once('connect', function () { - client.publish(topic, payload, opts); - }); + client.publish(topic, payload, opts) + }) server.once('client', function (serverClient) { serverClient.once('publish', function (packet) { - packet.topic.should.equal(topic); - packet.payload.toString().should.equal(payload); - packet.qos.should.equal(opts.qos, 'incorrect qos'); - packet.retain.should.equal(opts.retain, 'incorrect ret'); - client.end(); - done(); - }); - }); - }); + packet.topic.should.equal(topic) + packet.payload.toString().should.equal(payload) + packet.qos.should.equal(opts.qos, 'incorrect qos') + packet.retain.should.equal(opts.retain, 'incorrect ret') + client.end() + done() + }) + }) + }) it('should fire a callback (qos 0)', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { client.publish('a', 'b', function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('should fire a callback (qos 1)', function (done) { - var client = connect(), - opts = {qos: 1}; + var client = connect() + var opts = { qos: 1 } client.once('connect', function () { client.publish('a', 'b', opts, function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('should fire a callback (qos 2)', function (done) { - var client = connect(), - opts = {qos: 2}; + var client = connect() + var opts = { qos: 2 } client.once('connect', function () { client.publish('a', 'b', opts, function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('should support UTF-8 characters in topic', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { client.publish('中国', 'hello', function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('should support UTF-8 characters in payload', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { client.publish('hello', '中国', function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('Publish 10 QoS 2 and receive them', function (done) { - var client = connect(), - count = 0; + var client = connect() + var count = 0 client.on('connect', function () { - client.subscribe('test'); - client.publish('test', 'test', { qos: 2 }); - }); + client.subscribe('test') + client.publish('test', 'test', { qos: 2 }) + }) client.on('message', function () { - if (10 <= count) { - client.end(); - done(); + if (count >= 10) { + client.end() + done() } else { - client.publish('test', 'test', { qos: 2 }); + client.publish('test', 'test', { qos: 2 }) } - }); + }) server.once('client', function (serverClient) { serverClient.on('offline', function () { - client.end(); - done('error went offline... didnt see this happen'); - }); + client.end() + done('error went offline... didnt see this happen') + }) serverClient.on('subscribe', function () { serverClient.on('publish', function (packet) { - serverClient.publish(packet); - }); - }); + serverClient.publish(packet) + }) + }) serverClient.on('pubrel', function () { - count++; - }); - }); - }); - }); + count++ + }) + }) + }) + }) describe('unsubscribing', function () { it('should send an unsubscribe packet (offline)', function (done) { - var client = connect(); + var client = connect() - client.unsubscribe('test'); + client.unsubscribe('test') server.once('client', function (serverClient) { serverClient.once('unsubscribe', function (packet) { - packet.unsubscriptions.should.containEql('test'); - client.end(); - done(); - }); - }); - }); + packet.unsubscriptions.should.containEql('test') + client.end() + done() + }) + }) + }) it('should send an unsubscribe packet', function (done) { - var client = connect(), - topic = 'topic'; + var client = connect() + var topic = 'topic' client.once('connect', function () { - client.unsubscribe(topic); - }); + client.unsubscribe(topic) + }) server.once('client', function (serverClient) { serverClient.once('unsubscribe', function (packet) { - packet.unsubscriptions.should.containEql(topic); - client.end(); - done(); - }); - }); - }); + packet.unsubscriptions.should.containEql(topic) + client.end() + done() + }) + }) + }) it('should emit a packetsend event', function (done) { - var client = connect(), - test_topic = 'test_topic'; + var client = connect() + var testTopic = 'testTopic' client.once('connect', function () { - client.subscribe(test_topic); - }); + client.subscribe(testTopic) + }) client.on('packetsend', function (packet) { - if ('subscribe' === packet.cmd) { - client.end(); - done(); + if (packet.cmd === 'subscribe') { + client.end() + done() } - }); - }); + }) + }) it('should emit a packetreceive event', function (done) { - var client = connect(), - test_topic = 'test_topic'; + var client = connect() + var testTopic = 'testTopic' client.once('connect', function () { - client.subscribe(test_topic); - }); + client.subscribe(testTopic) + }) client.on('packetreceive', function (packet) { - if ('suback' === packet.cmd) { - client.end(); - done(); + if (packet.cmd === 'suback') { + client.end() + done() } - }); - }); + }) + }) it('should accept an array of unsubs', function (done) { - var client = connect(), - topics = ['topic1', 'topic2']; + var client = connect() + var topics = ['topic1', 'topic2'] client.once('connect', function () { - client.unsubscribe(topics); - }); + client.unsubscribe(topics) + }) server.once('client', function (serverClient) { serverClient.once('unsubscribe', function (packet) { - packet.unsubscriptions.should.eql(topics); - done(); - }); - }); - }); + packet.unsubscriptions.should.eql(topics) + done() + }) + }) + }) it('should fire a callback on unsuback', function (done) { - var client = connect(), - topic = 'topic'; + var client = connect() + var topic = 'topic' client.once('connect', function () { - client.unsubscribe(topic, done); - }); + client.unsubscribe(topic, done) + }) server.once('client', function (serverClient) { serverClient.once('unsubscribe', function (packet) { - serverClient.unsuback(packet); - client.end(); - }); - }); - }); + serverClient.unsuback(packet) + client.end() + }) + }) + }) it('should unsubscribe from a chinese topic', function (done) { - var client = connect(), - topic = '中国'; + var client = connect() + var topic = '中国' client.once('connect', function () { - client.unsubscribe(topic); - }); + client.unsubscribe(topic) + }) server.once('client', function (serverClient) { serverClient.once('unsubscribe', function (packet) { - packet.unsubscriptions.should.containEql(topic); - client.end(); - done(); - }); - }); - }); - }); + packet.unsubscriptions.should.containEql(topic) + client.end() + done() + }) + }) + }) + }) describe('keepalive', function () { - var clock; + var clock beforeEach(function () { - clock = sinon.useFakeTimers(); - }); + clock = sinon.useFakeTimers() + }) afterEach(function () { - clock.restore(); - }); + clock.restore() + }) it('should checkPing at keepalive interval', function (done) { - var interval = 3, - client = connect({keepalive: interval}); + var interval = 3 + var client = connect({ keepalive: interval }) - client._checkPing = sinon.spy(); + client._checkPing = sinon.spy() client.once('connect', function () { - clock.tick(interval * 1000); - client._checkPing.callCount.should.equal(1); + clock.tick(interval * 1000) + client._checkPing.callCount.should.equal(1) + + clock.tick(interval * 1000) + client._checkPing.callCount.should.equal(2) - clock.tick(interval * 1000); - client._checkPing.callCount.should.equal(2); + clock.tick(interval * 1000) + client._checkPing.callCount.should.equal(3) - clock.tick(interval * 1000); - client._checkPing.callCount.should.equal(3); + client.end() + done() + }) + }) - client.end(); - done(); - }); - }); it('should not checkPing if publishing at a higher rate than keepalive', function (done) { - var intervalMs = 3000, - client = connect({keepalive: intervalMs / 1000}); + var intervalMs = 3000 + var client = connect({keepalive: intervalMs / 1000}) - client._checkPing = sinon.spy(); + client._checkPing = sinon.spy() client.once('connect', function () { - client.publish('foo', 'bar'); - clock.tick(intervalMs - 1); - client.publish('foo', 'bar'); - clock.tick(2); - client._checkPing.callCount.should.equal(0); - client.end(); - done(); - }); - }); + client.publish('foo', 'bar') + clock.tick(intervalMs - 1) + client.publish('foo', 'bar') + clock.tick(2) + client._checkPing.callCount.should.equal(0) + client.end() + done() + }) + }) + it('should checkPing if publishing at a higher rate than keepalive and reschedulePings===false', function (done) { - var intervalMs = 3000, - client = connect({keepalive: intervalMs / 1000,reschedulePings:false}); + var intervalMs = 3000 + var client = connect({ + keepalive: intervalMs / 1000, + reschedulePings: false + }) - client._checkPing = sinon.spy(); + client._checkPing = sinon.spy() client.once('connect', function () { - client.publish('foo', 'bar'); - clock.tick(intervalMs - 1); - client.publish('foo', 'bar'); - clock.tick(2); - client._checkPing.callCount.should.equal(1); - client.end(); - done(); - }); - }); - }); + client.publish('foo', 'bar') + clock.tick(intervalMs - 1) + client.publish('foo', 'bar') + clock.tick(2) + client._checkPing.callCount.should.equal(1) + client.end() + done() + }) + }) + }) describe('pinging', function () { it('should set a ping timer', function (done) { - var client = connect({keepalive: 3}); + var client = connect({keepalive: 3}) client.once('connect', function () { - should.exist(client.pingTimer); - client.end(); - done(); - }); - }); + should.exist(client.pingTimer) + client.end() + done() + }) + }) it('should not set a ping timer keepalive=0', function (done) { - var client = connect({keepalive: 0}); + var client = connect({keepalive: 0}) client.on('connect', function () { - should.not.exist(client.pingTimer); - client.end(); - done(); - }); - }); + should.not.exist(client.pingTimer) + client.end() + done() + }) + }) it('should reconnect if pingresp is not sent', function (done) { - var client = connect({keepalive: 1, reconnectPeriod: 100}); + var client = connect({keepalive: 1, reconnectPeriod: 100}) // Fake no pingresp being send by stubbing the _handlePingresp function - client._handlePingresp = function () {}; + client._handlePingresp = function () {} client.once('connect', function () { client.once('connect', function () { - client.end(); - done(); - }); - }); - }); + client.end() + done() + }) + }) + }) it('should not reconnect if pingresp is successful', function (done) { - var client = connect({keepalive: 100}); + var client = connect({keepalive: 100}) client.once('close', function () { - done(new Error('Client closed connection')); - }); - setTimeout(done, 1000); - }); + done(new Error('Client closed connection')) + }) + setTimeout(done, 1000) + }) it('should defer the next ping when sending a control packet', function (done) { - var client = connect({keepalive: 1}); + var client = connect({keepalive: 1}) client.once('connect', function () { - client._checkPing = sinon.spy(); + client._checkPing = sinon.spy() - client.publish('foo', 'bar'); + client.publish('foo', 'bar') setTimeout(function () { - client._checkPing.callCount.should.equal(0); - client.publish('foo', 'bar'); + client._checkPing.callCount.should.equal(0) + client.publish('foo', 'bar') setTimeout(function () { - client._checkPing.callCount.should.equal(0); - client.publish('foo', 'bar'); + client._checkPing.callCount.should.equal(0) + client.publish('foo', 'bar') setTimeout(function () { - client._checkPing.callCount.should.equal(0); - done(); - }, 75); - }, 75); - }, 75); - }); - }); - }); + client._checkPing.callCount.should.equal(0) + done() + }, 75) + }, 75) + }, 75) + }) + }) + }) describe('subscribing', function () { it('should send a subscribe message (offline)', function (done) { - var client = connect(); + var client = connect() - client.subscribe('test'); + client.subscribe('test') server.once('client', function (serverClient) { serverClient.once('subscribe', function () { - done(); - }); - }); - }); + done() + }) + }) + }) it('should send a subscribe message', function (done) { - var client = connect(), - topic = 'test'; + var client = connect() + var topic = 'test' client.once('connect', function () { - client.subscribe(topic); - }); + client.subscribe(topic) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function (packet) { packet.subscriptions.should.containEql({ topic: topic, qos: 0 - }); - done(); - }); - }); - }); + }) + done() + }) + }) + }) it('should emit a packetsend event', function (done) { - var client = connect(), - test_topic = 'test_topic'; + var client = connect() + var testTopic = 'testTopic' client.once('connect', function () { - client.subscribe(test_topic); - }); + client.subscribe(testTopic) + }) client.on('packetsend', function (packet) { - if ('subscribe' === packet.cmd) { - done(); + if (packet.cmd === 'subscribe') { + done() } - }); - }); + }) + }) it('should emit a packetreceive event', function (done) { - var client = connect(), - test_topic = 'test_topic'; + var client = connect() + var testTopic = 'testTopic' client.once('connect', function () { - client.subscribe(test_topic); - }); + client.subscribe(testTopic) + }) client.on('packetreceive', function (packet) { - if ('suback' === packet.cmd) { - done(); + if (packet.cmd === 'suback') { + done() } - }); - }); + }) + }) it('should accept an array of subscriptions', function (done) { - var client = connect(), - subs = ['test1', 'test2']; + var client = connect() + var subs = ['test1', 'test2'] client.once('connect', function () { - client.subscribe(subs); - }); + client.subscribe(subs) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function (packet) { // i.e. [{topic: 'a', qos: 0}, {topic: 'b', qos: 0}] var expected = subs.map(function (i) { - return {topic: i, qos: 0}; - }); + return {topic: i, qos: 0} + }) - packet.subscriptions.should.eql(expected); - done(); - }); - }); - }); + packet.subscriptions.should.eql(expected) + done() + }) + }) + }) it('should accept an hash of subscriptions', function (done) { - var client = connect(), - topics = {'test1': 0, 'test2': 1}; + var client = connect() + var topics = { + test1: 0, + test2: 1 + } client.once('connect', function () { - client.subscribe(topics); - }); + client.subscribe(topics) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function (packet) { - var k, - expected = []; + var k + var expected = [] for (k in topics) { if (topics.hasOwnProperty(k)) { expected.push({ topic: k, qos: topics[k] - }); + }) } } - packet.subscriptions.should.eql(expected); - done(); - }); - }); - }); + packet.subscriptions.should.eql(expected) + done() + }) + }) + }) it('should accept an options parameter', function (done) { - var client = connect(), - topic = 'test', - opts = {qos: 1}; + var client = connect() + var topic = 'test' + var opts = {qos: 1} client.once('connect', function () { - client.subscribe(topic, opts); - }); + client.subscribe(topic, opts) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function (packet) { - var expected = [{topic: topic, qos: 1}]; + var expected = [{ + topic: topic, + qos: 1 + }] - packet.subscriptions.should.eql(expected); - done(); - }); - }); - }); + packet.subscriptions.should.eql(expected) + done() + }) + }) + }) it('should fire a callback on suback', function (done) { - var client = connect(), - topic = 'test'; + var client = connect() + var topic = 'test' client.once('connect', function () { - client.subscribe(topic, {qos: 2}, function (err, granted) { + client.subscribe(topic, { qos: 2 }, function (err, granted) { if (err) { - done(err); + done(err) } else { - should.exist(granted, 'granted not given'); - granted.should.containEql({topic: 'test', qos: 2}); - done(); + should.exist(granted, 'granted not given') + granted.should.containEql({topic: 'test', qos: 2}) + done() } - }); - }); - }); + }) + }) + }) it('should fire a callback with error if disconnected (options provided)', function (done) { - var client = connect(), - topic = 'test'; + var client = connect() + var topic = 'test' client.once('connect', function () { client.end(true, function () { client.subscribe(topic, {qos: 2}, function (err, granted) { - should.not.exist(granted, 'granted given'); - should.exist(err, 'no error given'); - done(); - }); - }); - }); - }); + should.not.exist(granted, 'granted given') + should.exist(err, 'no error given') + done() + }) + }) + }) + }) + it('should fire a callback with error if disconnected (options not provided)', function (done) { - var client = connect(), - topic = 'test'; + var client = connect() + var topic = 'test' + client.once('connect', function () { client.end(true, function () { client.subscribe(topic, function (err, granted) { - should.not.exist(granted, 'granted given'); - should.exist(err, 'no error given'); - done(); - }); - }); - }); - }); + should.not.exist(granted, 'granted given') + should.exist(err, 'no error given') + done() + }) + }) + }) + }) + it('should subscribe with a chinese topic', function (done) { - var client = connect(), - topic = '中国'; + var client = connect() + var topic = '中国' client.once('connect', function () { - client.subscribe(topic); - }); + client.subscribe(topic) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function (packet) { packet.subscriptions.should.containEql({ topic: topic, qos: 0 - }); - done(); - }); - }); - }); - }); + }) + done() + }) + }) + }) + }) describe('receiving messages', function () { it('should fire the message event', function (done) { - var client = connect(), - testPacket = { - topic: 'test', - payload: 'message', - retain: true, - qos: 1, - messageId: 5 - }; - - client.subscribe(testPacket.topic); + var client = connect() + var testPacket = { + topic: 'test', + payload: 'message', + retain: true, + qos: 1, + messageId: 5 + } + + client.subscribe(testPacket.topic) client.once('message', function (topic, message, packet) { - topic.should.equal(testPacket.topic); - message.toString().should.equal(testPacket.payload); - packet.should.equal(packet); - done(); - }); + topic.should.equal(testPacket.topic) + message.toString().should.equal(testPacket.payload) + packet.should.equal(packet) + done() + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) it('should emit a packetreceive event', function (done) { - var client = connect(), - testPacket = { - topic: 'test', - payload: 'message', - retain: true, - qos: 1, - messageId: 5 - }; - - client.subscribe(testPacket.topic); + var client = connect() + var testPacket = { + topic: 'test', + payload: 'message', + retain: true, + qos: 1, + messageId: 5 + } + + client.subscribe(testPacket.topic) client.on('packetreceive', function (packet) { - if ('publish' === packet.cmd) { - packet.qos.should.equal(1); - packet.topic.should.equal(testPacket.topic); - packet.payload.toString().should.equal(testPacket.payload); - packet.retain.should.equal(true); - done(); + if (packet.cmd === 'publish') { + packet.qos.should.equal(1) + packet.topic.should.equal(testPacket.topic) + packet.payload.toString().should.equal(testPacket.payload) + packet.retain.should.equal(true) + done() } - }); + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) it('should support binary data', function (done) { - var client = connect({ encoding: 'binary' }), - testPacket = { - topic: 'test', - payload: 'message', - retain: true, - qos: 1, - messageId: 5 - }; - - client.subscribe(testPacket.topic); + var client = connect({ encoding: 'binary' }) + var testPacket = { + topic: 'test', + payload: 'message', + retain: true, + qos: 1, + messageId: 5 + } + + client.subscribe(testPacket.topic) client.once('message', function (topic, message, packet) { - topic.should.equal(testPacket.topic); - message.should.be.an.instanceOf(Buffer); - message.toString().should.equal(testPacket.payload); - packet.should.equal(packet); - done(); - }); + topic.should.equal(testPacket.topic) + message.should.be.an.instanceOf(Buffer) + message.toString().should.equal(testPacket.payload) + packet.should.equal(packet) + done() + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) it('should emit a message event (qos=2)', function (done) { - var client = connect(), - testPacket = { - topic: 'test', - payload: 'message', - retain: true, - qos: 2, - messageId: 5 - }; - - server.testPublish = testPacket; - - client.subscribe(testPacket.topic); + var client = connect() + var testPacket = { + topic: 'test', + payload: 'message', + retain: true, + qos: 2, + messageId: 5 + } + + server.testPublish = testPacket + + client.subscribe(testPacket.topic) client.once('message', function (topic, message, packet) { - topic.should.equal(testPacket.topic); - message.toString().should.equal(testPacket.payload); - packet.should.equal(packet); - done(); - }); + topic.should.equal(testPacket.topic) + message.toString().should.equal(testPacket.payload) + packet.should.equal(packet) + done() + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) it('should emit a message event (qos=2) - repeated publish', function (done) { - var client = connect(), - testPacket = { - topic: 'test', - payload: 'message', - retain: true, - qos: 2, - messageId: 5 - }; - - server.testPublish = testPacket; - - client.subscribe(testPacket.topic); + var client = connect() + var testPacket = { + topic: 'test', + payload: 'message', + retain: true, + qos: 2, + messageId: 5 + } + + server.testPublish = testPacket + + client.subscribe(testPacket.topic) client.on('message', function (topic, message, packet) { - topic.should.equal(testPacket.topic); - message.toString().should.equal(testPacket.payload); - packet.should.equal(packet); - done(); - }); + topic.should.equal(testPacket.topic) + message.toString().should.equal(testPacket.payload) + packet.should.equal(packet) + done() + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); + serverClient.publish(testPacket) // twice, should be ignored - serverClient.publish(testPacket); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) it('should support chinese topic', function (done) { - var client = connect({ encoding: 'binary' }), - testPacket = { - topic: '国', - payload: 'message', - retain: true, - qos: 1, - messageId: 5 - }; - - client.subscribe(testPacket.topic); + var client = connect({ encoding: 'binary' }) + var testPacket = { + topic: '国', + payload: 'message', + retain: true, + qos: 1, + messageId: 5 + } + + client.subscribe(testPacket.topic) client.once('message', function (topic, message, packet) { - topic.should.equal(testPacket.topic); - message.should.be.an.instanceOf(Buffer); - message.toString().should.equal(testPacket.payload); - packet.should.equal(packet); - done(); - }); + topic.should.equal(testPacket.topic) + message.should.be.an.instanceOf(Buffer) + message.toString().should.equal(testPacket.payload) + packet.should.equal(packet) + done() + }) server.once('client', function (serverClient) { serverClient.on('subscribe', function () { - serverClient.publish(testPacket); - }); - }); - }); - }); + serverClient.publish(testPacket) + }) + }) + }) + }) describe('qos handling', function () { - it('should follow qos 0 semantics (trivial)', function (done) { - var client = connect(), - test_topic = 'test', - test_message = 'message'; + var client = connect() + var testTopic = 'test' + var testMessage = 'message' client.once('connect', function () { - client.subscribe(test_topic, {qos: 0}); - }); + client.subscribe(testTopic, {qos: 0}) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function () { serverClient.publish({ - topic: test_topic, - payload: test_message, + topic: testTopic, + payload: testMessage, qos: 0, retain: false - }); - done(); - }); - }); - }); + }) + done() + }) + }) + }) it('should follow qos 1 semantics', function (done) { - var client = connect(), - test_topic = 'test', - test_message = 'message', - mid = 50; + var client = connect() + var testTopic = 'test' + var testMessage = 'message' + var mid = 50 client.once('connect', function () { - client.subscribe(test_topic, {qos: 1}); - }); + client.subscribe(testTopic, {qos: 1}) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function () { serverClient.publish({ - topic: test_topic, - payload: test_message, + topic: testTopic, + payload: testMessage, messageId: mid, qos: 1 - }); - }); + }) + }) serverClient.once('puback', function (packet) { - packet.messageId.should.equal(mid); - done(); - }); - }); - }); + packet.messageId.should.equal(mid) + done() + }) + }) + }) it('should follow qos 2 semantics', function (done) { - var client = connect(), - test_topic = 'test', - test_message = 'message', - mid = 253; + var client = connect() + var testTopic = 'test' + var testMessage = 'message' + var mid = 253 client.once('connect', function () { - client.subscribe(test_topic, {qos: 2}); - }); + client.subscribe(testTopic, {qos: 2}) + }) server.once('client', function (serverClient) { serverClient.once('subscribe', function () { serverClient.publish({ - topic: test_topic, - payload: test_message, + topic: testTopic, + payload: testMessage, qos: 2, messageId: mid - }); - }); + }) + }) serverClient.once('pubcomp', function () { - done(); - }); - }); - }); - }); + done() + }) + }) + }) + }) describe('auto reconnect', function () { it('should mark the client disconnecting if #end called', function () { - var client = connect(); + var client = connect() - client.end(); - client.disconnecting.should.eql(true); - }); + client.end() + client.disconnecting.should.eql(true) + }) it('should reconnect after stream disconnect', function (done) { - var client = connect(), - tryReconnect = true; + var client = connect() + var tryReconnect = true client.on('connect', function () { if (tryReconnect) { - client.stream.end(); - tryReconnect = false; + client.stream.end() + tryReconnect = false } else { - done(); + done() } - }); - }); + }) + }) it('should emit \'reconnect\' when reconnecting', function (done) { - var client = connect(), - tryReconnect = true, - reconnectEvent = false; + var client = connect() + var tryReconnect = true + var reconnectEvent = false client.on('reconnect', function () { - reconnectEvent = true; - }); + reconnectEvent = true + }) client.on('connect', function () { if (tryReconnect) { - client.stream.end(); - tryReconnect = false; + client.stream.end() + tryReconnect = false } else { - reconnectEvent.should.equal(true); - done(); + reconnectEvent.should.equal(true) + done() } - }); - }); + }) + }) it('should emit \'offline\' after going offline', function (done) { - var client = connect(), - tryReconnect = true, - offlineEvent = false; + var client = connect() + var tryReconnect = true + var offlineEvent = false client.on('offline', function () { - offlineEvent = true; - }); + offlineEvent = true + }) client.on('connect', function () { if (tryReconnect) { - client.stream.end(); - tryReconnect = false; + client.stream.end() + tryReconnect = false } else { - offlineEvent.should.equal(true); - done(); + offlineEvent.should.equal(true) + done() } - }); - }); + }) + }) it('should not reconnect if it was ended by the user', function (done) { - var client = connect(); + var client = connect() client.on('connect', function () { - client.end(); - done(); // it will raise an exception if called two times - }); - }); + client.end() + done() // it will raise an exception if called two times + }) + }) it('should setup a reconnect timer on disconnect', function (done) { - var client = connect(); + var client = connect() client.once('connect', function () { - should.not.exist(client.reconnectTimer); - client.stream.end(); - }); + should.not.exist(client.reconnectTimer) + client.stream.end() + }) client.once('close', function () { - should.exist(client.reconnectTimer); - done(); - }); - }); + should.exist(client.reconnectTimer) + done() + }) + }) it('should allow specification of a reconnect period', function (done) { - var end, - period = 200, - client = connect({reconnectPeriod: period}), - reconnect = false, - start = Date.now(); + var end + var period = 200 + var client = connect({reconnectPeriod: period}) + var reconnect = false + var start = Date.now() client.on('connect', function () { if (!reconnect) { - client.stream.end(); - reconnect = true; + client.stream.end() + reconnect = true } else { - client.end(); - end = Date.now(); + client.end() + end = Date.now() if (end - start >= period) { // Connected in about 2 seconds, that's good enough - done(); + done() } else { - done(new Error('Strange reconnect period')); + done(new Error('Strange reconnect period')) } } - }); - }); + }) + }) it('should resend in-flight QoS 1 publish messages from the client', function (done) { - var client = connect({reconnectPeriod: 200}), - serverPublished = false, - clientCalledBack = false; + var client = connect({reconnectPeriod: 200}) + var serverPublished = false + var clientCalledBack = false server.once('client', function (serverClient) { serverClient.on('connect', function () { setImmediate(function () { - serverClient.stream.destroy(); - }); - }); + serverClient.stream.destroy() + }) + }) server.once('client', function (serverClientNew) { serverClientNew.on('publish', function () { - serverPublished = true; - check(); - }); - }); - }); + serverPublished = true + check() + }) + }) + }) client.publish('hello', 'world', { qos: 1 }, function () { - clientCalledBack = true; - check(); - }); + clientCalledBack = true + check() + }) function check () { if (serverPublished && clientCalledBack) { - done(); + done() } } - }); + }) it('should resend in-flight QoS 2 publish messages from the client', function (done) { - var client = connect({reconnectPeriod: 200}), - serverPublished = false, - clientCalledBack = false; + var client = connect({reconnectPeriod: 200}) + var serverPublished = false + var clientCalledBack = false server.once('client', function (serverClient) { serverClient.on('publish', function () { setImmediate(function () { - serverClient.stream.destroy(); - }); - }); + serverClient.stream.destroy() + }) + }) server.once('client', function (serverClientNew) { serverClientNew.on('pubrel', function () { - serverPublished = true; - check(); - }); - }); - }); + serverPublished = true + check() + }) + }) + }) client.publish('hello', 'world', { qos: 2 }, function () { - clientCalledBack = true; - check(); - }); + clientCalledBack = true + check() + }) function check () { if (serverPublished && clientCalledBack) { - done(); + done() } } - }); - }); -}; + }) + }) +} diff --git a/test/abstract_store.js b/test/abstract_store.js index 45935261b..28f4dda50 100644 --- a/test/abstract_store.js +++ b/test/abstract_store.js @@ -1,20 +1,20 @@ -'use strict'; +'use strict' -require('should'); +require('should') module.exports = function abstractStoreTest (build) { - var store; + var store beforeEach(function (done) { build(function (err, _store) { - store = _store; - done(err); - }); - }); + store = _store + done(err) + }) + }) afterEach(function (done) { - store.close(done); - }); + store.close(done) + }) it('should put and stream in-flight packets', function (done) { var packet = { @@ -22,17 +22,17 @@ module.exports = function abstractStoreTest (build) { payload: 'world', qos: 1, messageId: 42 - }; + } store.put(packet, function () { store .createStream() .on('data', function (data) { - data.should.eql(packet); - done(); - }); - }); - }); + data.should.eql(packet) + done() + }) + }) + }) it('should support destroying the stream', function (done) { var packet = { @@ -40,14 +40,14 @@ module.exports = function abstractStoreTest (build) { payload: 'world', qos: 1, messageId: 42 - }; + } store.put(packet, function () { - var stream = store.createStream(); - stream.on('close', done); - stream.destroy(); - }); - }); + var stream = store.createStream() + stream.on('close', done) + stream.destroy() + }) + }) it('should add and del in-flight packets', function (done) { var packet = { @@ -55,43 +55,43 @@ module.exports = function abstractStoreTest (build) { payload: 'world', qos: 1, messageId: 42 - }; + } store.put(packet, function () { store.del(packet, function () { store .createStream() .on('data', function () { - done(new Error('this should never happen')); + done(new Error('this should never happen')) }) - .on('end', done); - }); - }); - }); + .on('end', done) + }) + }) + }) it('should replace a packet when doing put with the same messageId', function (done) { var packet1 = { - topic: 'hello', - payload: 'world', - qos: 2, - messageId: 42 - }, - packet2 = { - qos: 2, - messageId: 42 - }; + topic: 'hello', + payload: 'world', + qos: 2, + messageId: 42 + } + var packet2 = { + qos: 2, + messageId: 42 + } store.put(packet1, function () { store.put(packet2, function () { store .createStream() .on('data', function (data) { - data.should.eql(packet2); - done(); - }); - }); - }); - }); + data.should.eql(packet2) + done() + }) + }) + }) + }) it('should return the original packet on del', function (done) { var packet = { @@ -99,18 +99,18 @@ module.exports = function abstractStoreTest (build) { payload: 'world', qos: 1, messageId: 42 - }; + } store.put(packet, function () { store.del({ messageId: 42 }, function (err, deleted) { if (err) { - throw err; + throw err } - deleted.should.eql(packet); - done(); - }); - }); - }); + deleted.should.eql(packet) + done() + }) + }) + }) it('should get a packet with the same messageId', function (done) { var packet = { @@ -118,16 +118,16 @@ module.exports = function abstractStoreTest (build) { payload: 'world', qos: 1, messageId: 42 - }; + } store.put(packet, function () { store.get({ messageId: 42 }, function (err, fromDb) { if (err) { - throw err; + throw err } - fromDb.should.eql(packet); - done(); - }); - }); - }); -}; + fromDb.should.eql(packet) + done() + }) + }) + }) +} diff --git a/test/browser/server.js b/test/browser/server.js index dda963d2c..35c602704 100644 --- a/test/browser/server.js +++ b/test/browser/server.js @@ -1,131 +1,130 @@ -'use strict'; -/*eslint default-case:0*/ -/*eslint guard-for-in:0*/ -var handleClient, - websocket = require('websocket-stream'), - WebSocketServer = require('ws').Server, - Connection = require('mqtt-connection'), - http = require('http'); +'use strict' + +var handleClient +var websocket = require('websocket-stream') +var WebSocketServer = require('ws').Server +var Connection = require('mqtt-connection') +var http = require('http') handleClient = function (client) { - var self = this; + var self = this if (!self.clients) { - self.clients = {}; + self.clients = {} } client.on('connect', function (packet) { - if ('invalid' === packet.clientId) { - client.connack({returnCode: 2}); + if (packet.clientId === 'invalid') { + client.connack({returnCode: 2}) } else { - client.connack({returnCode: 0}); + client.connack({returnCode: 0}) } - self.clients[packet.clientId] = client; - client.subscriptions = []; - }); + self.clients[packet.clientId] = client + client.subscriptions = [] + }) client.on('publish', function (packet) { - var i, k, c, s, publish; + var i, k, c, s, publish switch (packet.qos) { case 0: - break; + break case 1: - client.puback(packet); - break; + client.puback(packet) + break case 2: - client.pubrec(packet); - break; + client.pubrec(packet) + break } for (k in self.clients) { - c = self.clients[k]; - publish = false; + c = self.clients[k] + publish = false for (i = 0; i < c.subscriptions.length; i++) { - s = c.subscriptions[i]; + s = c.subscriptions[i] if (s.test(packet.topic)) { - publish = true; + publish = true } } if (publish) { try { - c.publish({topic: packet.topic, payload: packet.payload}); + c.publish({topic: packet.topic, payload: packet.payload}) } catch (error) { - delete self.clients[k]; + delete self.clients[k] } } } - }); + }) client.on('pubrel', function (packet) { - client.pubcomp(packet); - }); + client.pubcomp(packet) + }) client.on('pubrec', function (packet) { - client.pubrel(packet); - }); + client.pubrel(packet) + }) client.on('pubcomp', function () { // Nothing to be done - }); + }) client.on('subscribe', function (packet) { - var i, qos, topic, reg, - granted = []; - - for (i = 0; i < packet.subscriptions.length; i++) { - qos = packet.subscriptions[i].qos; - topic = packet.subscriptions[i].topic; - reg = new RegExp(topic.replace('+', '[^\/]+').replace('#', '.+') + '$'); - - granted.push(qos); - client.subscriptions.push(reg); + var qos + var topic + var reg + var granted = [] + + for (var i = 0; i < packet.subscriptions.length; i++) { + qos = packet.subscriptions[i].qos + topic = packet.subscriptions[i].topic + reg = new RegExp(topic.replace('+', '[^/]+').replace('#', '.+') + '$') + + granted.push(qos) + client.subscriptions.push(reg) } - client.suback({messageId: packet.messageId, granted: granted}); - }); + client.suback({messageId: packet.messageId, granted: granted}) + }) client.on('unsubscribe', function (packet) { - client.unsuback(packet); - }); + client.unsuback(packet) + }) client.on('pingreq', function () { - client.pingresp(); - }); -}; + client.pingresp() + }) +} function start (startPort, done) { - var server = http.createServer(), - wss = new WebSocketServer({server: server}); + var server = http.createServer() + var wss = new WebSocketServer({server: server}) wss.on('connection', function (ws) { - var stream, connection; - if ('mqttv3.1' !== ws.protocol) { - return ws.end(); + var stream, connection + if (ws.protocol !== 'mqttv3.1') { + return ws.end() } - console.log('MQTT connection'); - - stream = websocket(ws); - connection = new Connection(stream); - handleClient.call(server, connection); - }); - server.listen(startPort, done); + stream = websocket(ws) + connection = new Connection(stream) + handleClient.call(server, connection) + }) + server.listen(startPort, done) server.on('request', function (req, res) { - res.statusCode = 404; - res.end('Not Found'); - }); - return server; + res.statusCode = 404 + res.end('Not Found') + }) + return server } if (require.main === module) { start(process.env.PORT || process.env.ZUUL_PORT, function (err) { if (err) { - console.error(err); - return; + console.error(err) + return } - console.log('tunnelled server started on port', process.env.PORT || process.env.ZUUL_PORT); - }); + console.log('tunnelled server started on port', process.env.PORT || process.env.ZUUL_PORT) + }) } diff --git a/test/browser/test.js b/test/browser/test.js index 59521c8c8..f9c797b7a 100644 --- a/test/browser/test.js +++ b/test/browser/test.js @@ -1,86 +1,81 @@ -'use strict'; -/** - * Testing dependencies - */ +'use strict' -var mqtt = require('../../lib/connect'), - _URL = require('url'), - parsed = _URL.parse(document.URL), - isHttps = 'https:' === parsed.protocol, - port = parsed.port || (isHttps ? 443 : 80), - host = parsed.hostname, - protocol = isHttps ? 'wss' : 'ws'; - -console.log(parsed); +var mqtt = require('../../lib/connect') +var _URL = require('url') +var parsed = _URL.parse(document.URL) +var isHttps = parsed.protocol === 'https:' +var port = parsed.port || (isHttps ? 443 : 80) +var host = parsed.hostname +var protocol = isHttps ? 'wss' : 'ws' function clientTests (buildClient) { - var client; + var client beforeEach(function () { - client = buildClient(); + client = buildClient() client.on('offline', function () { - console.log('client offline'); - }); + console.log('client offline') + }) client.on('connect', function () { - console.log('client connect'); - }); + console.log('client connect') + }) client.on('reconnect', function () { - console.log('client reconnect'); - }); - }); + console.log('client reconnect') + }) + }) afterEach(function (done) { client.once('close', function () { - done(); - }); - client.end(); - }); + done() + }) + client.end() + }) it('should connect', function (done) { client.on('connect', function () { - done(); - }); - }); + done() + }) + }) it('should publish and subscribe', function (done) { client.subscribe('hello', function () { - done(); - }).publish('hello', 'world'); - }); + done() + }).publish('hello', 'world') + }) } describe('MqttClient', function () { - this.timeout(10000); + this.timeout(10000) describe('specifying nothing', function () { clientTests(function () { - return mqtt.connect(); - }); - }); + return mqtt.connect() + }) + }) - if ('localhost' === parsed.host) { + if (parsed.host === 'localhost') { describe('specifying a port', function () { clientTests(function () { - return mqtt.connect({ protocol: protocol, port: port }); - }); - }); + return mqtt.connect({ protocol: protocol, port: port }) + }) + }) } describe('specifying a port and host', function () { clientTests(function () { - return mqtt.connect({ protocol: protocol, port: port, host: host }); - }); - }); + return mqtt.connect({ protocol: protocol, port: port, host: host }) + }) + }) describe('specifying a URL', function () { clientTests(function () { - return mqtt.connect(protocol + '://' + host + ':' + port); - }); - }); + return mqtt.connect(protocol + '://' + host + ':' + port) + }) + }) describe('specifying a URL with a path', function () { clientTests(function () { - return mqtt.connect(protocol + '://' + host + ':' + port + '/mqtt'); - }); - }); -}); + return mqtt.connect(protocol + '://' + host + ':' + port + '/mqtt') + }) + }) +}) diff --git a/test/client.js b/test/client.js index ec639f05d..9786c04db 100644 --- a/test/client.js +++ b/test/client.js @@ -1,265 +1,258 @@ -'use strict'; -/*global setImmediate:true*/ -/*eslint no-path-concat:0*/ -/*eslint default-case:0*/ -/** - * Testing dependencies - */ - -var mqtt = require('..'), - should = require('should'), - abstractClientTests = require('./abstract_client'), - setImmediate = global.setImmediate || function (callback) { - // works in node v0.8 - process.nextTick(callback); - }, - net = require('net'), - eos = require('end-of-stream'), - Server = require('./server'), - port = 9876, - server; +'use strict' + +var mqtt = require('..') +var should = require('should') +var fork = require('child_process').fork +var path = require('path') +var abstractClientTests = require('./abstract_client') +var net = require('net') +var eos = require('end-of-stream') +var Server = require('./server') +var port = 9876 +var server /** * Test server */ function buildServer () { return new Server(function (client) { - client.on('connect', function (packet) { - if ('invalid' === packet.clientId) { - client.connack({returnCode: 2}); + if (packet.clientId === 'invalid') { + client.connack({returnCode: 2}) } else { - client.connack({returnCode: 0}); + client.connack({returnCode: 0}) } - }); + }) client.on('publish', function (packet) { setImmediate(function () { - /*jshint -W027*/ + /* jshint -W027 */ switch (packet.qos) { case 0: - break; + break case 1: - client.puback(packet); - break; + client.puback(packet) + break case 2: - client.pubrec(packet); - break; + client.pubrec(packet) + break } - /*jshint +W027*/ - }); - }); + /* jshint +W027 */ + }) + }) client.on('pubrel', function (packet) { - client.pubcomp(packet); - }); + client.pubcomp(packet) + }) client.on('pubrec', function (packet) { - client.pubrel(packet); - }); + client.pubrel(packet) + }) client.on('pubcomp', function () { // Nothing to be done - }); + }) client.on('subscribe', function (packet) { client.suback({ messageId: packet.messageId, granted: packet.subscriptions.map(function (e) { - return e.qos; + return e.qos }) - }); - }); + }) + }) client.on('unsubscribe', function (packet) { - client.unsuback(packet); - }); + client.unsuback(packet) + }) client.on('pingreq', function () { - client.pingresp(); - }); - }); + client.pingresp() + }) + }) } -server = buildServer().listen(port); - +server = buildServer().listen(port) describe('MqttClient', function () { describe('creating', function () { it('should allow instantiation of MqttClient without the \'new\' operator', function (done) { should(function () { - var client; + var client try { client = mqtt.MqttClient(function () { - throw Error('break'); - }, {}); - client.end(); + throw Error('break') + }, {}) + client.end() } catch (err) { - if ('break' !== err.message) { - throw err; + if (err.message !== 'break') { + throw err } - done(); + done() } - }).not.throw('Object # has no method \'_setupStream\''); - }); - }); + }).not.throw('Object # has no method \'_setupStream\'') + }) + }) - var config = { protocol: 'mqtt', port: port }; - abstractClientTests(server, config); + var config = { protocol: 'mqtt', port: port } + abstractClientTests(server, config) describe('message ids', function () { it('should increment the message id', function () { - var client = mqtt.connect(config), - currentId = client._nextId(); + var client = mqtt.connect(config) + var currentId = client._nextId() - client._nextId().should.equal(currentId + 1); - client.end(); - }); + client._nextId().should.equal(currentId + 1) + client.end() + }) it('should return 1 once the interal counter reached limit', function () { - var client = mqtt.connect(config); - client.nextId = 65535; + var client = mqtt.connect(config) + client.nextId = 65535 - client._nextId().should.equal(65535); - client._nextId().should.equal(1); - client.end(); - }); - }); + client._nextId().should.equal(65535) + client._nextId().should.equal(1) + client.end() + }) + }) describe('reconnecting', function () { it('should attempt to reconnect once server is down', function (done) { - this.timeout(15000); + this.timeout(15000) - var fork = require('child_process').fork, - // better use path.resolve(__dirname, 'helpers', "server_process.js") - // with this you are system path joining aware - innerServer = fork(__dirname + '/helpers/server_process.js'), - client = mqtt.connect({ port: 3000, host: 'localhost', keepalive: 1 }); + var innerServer = fork(path.join(__dirname, 'helpers', 'server_process.js')) + var client = mqtt.connect({ port: 3000, host: 'localhost', keepalive: 1 }) client.once('connect', function () { - innerServer.kill('SIGINT'); // mocks server shutdown + innerServer.kill('SIGINT') // mocks server shutdown client.once('close', function () { - should.exist(client.reconnectTimer); - client.end(); - done(); - }); - }); - }); + should.exist(client.reconnectTimer) + client.end() + done() + }) + }) + }) it('should reconnect to multiple host-ports combination if servers is passed', function (done) { - this.timeout(15000); + this.timeout(15000) - var server2 = buildServer().listen(port + 42); + var server2 = buildServer().listen(port + 42) server2.on('client', function (c) { - c.stream.destroy(); - server2.close(); - }); + c.stream.destroy() + server2.close() + }) server2.on('listening', function () { - - var client = mqtt.connect({ servers: [ - { port: port + 42, host: 'localhost' }, - { port: port, host: 'localhost' } - ], keepalive: 50 }); + var client = mqtt.connect({ + servers: [ + { port: port + 42, host: 'localhost' }, + { port: port, host: 'localhost' } + ], + keepalive: 50 + }) server.once('client', function () { - client.end(); - done(); - }); + client.end() + done() + }) client.once('connect', function () { - client.stream.destroy(); - }); - }); - }); + client.stream.destroy() + }) + }) + }) it('should reconnect if a connack is not received in an interval', function (done) { - this.timeout(2000); + this.timeout(2000) - var server2 = net.createServer().listen(port + 43); + var server2 = net.createServer().listen(port + 43) server2.on('connection', function (c) { eos(c, function () { - server2.close(); - }); - }); + server2.close() + }) + }) server2.on('listening', function () { - - var client = mqtt.connect({ servers: [ - { port: port + 43, host: 'localhost_fake' }, - { port: port, host: 'localhost' } - ], connectTimeout: 500 }); + var client = mqtt.connect({ + servers: [ + { port: port + 43, host: 'localhost_fake' }, + { port: port, host: 'localhost' } + ], + connectTimeout: 500 + }) server.once('client', function () { - client.end(); - done(); - }); + client.end() + done() + }) client.once('connect', function () { - client.stream.destroy(); - }); - }); - }); + client.stream.destroy() + }) + }) + }) it('shoud not be cleared by the connack timer', function (done) { - this.timeout(4000); + this.timeout(4000) - var server2 = net.createServer().listen(port + 44); + var server2 = net.createServer().listen(port + 44) server2.on('connection', function (c) { - c.destroy(); - }); + c.destroy() + }) server2.once('listening', function () { - var reconnects = 0, - connectTimeout = 1000, - reconnectPeriod = 100, - expectedReconnects = Math.floor(connectTimeout / reconnectPeriod), - client = mqtt.connect({ - port: port + 44, - host: 'localhost', - connectTimeout: connectTimeout, - reconnectPeriod: reconnectPeriod }); + var reconnects = 0 + var connectTimeout = 1000 + var reconnectPeriod = 100 + var expectedReconnects = Math.floor(connectTimeout / reconnectPeriod) + var client = mqtt.connect({ + port: port + 44, + host: 'localhost', + connectTimeout: connectTimeout, + reconnectPeriod: reconnectPeriod + }) client.on('reconnect', function () { - reconnects++; + reconnects++ if (reconnects >= expectedReconnects) { - client.end(); - done(); + client.end() + done() } - }); - }); - }); + }) + }) + }) + it('shoud not keep requeueing the first message when offline', function (done) { - this.timeout(2500); + this.timeout(2500) - var server2 = buildServer().listen(port + 45), - client = mqtt.connect({ - port: port + 45, - host: 'localhost', - connectTimeout: 350, - reconnectPeriod: 300 - }); + var server2 = buildServer().listen(port + 45) + var client = mqtt.connect({ + port: port + 45, + host: 'localhost', + connectTimeout: 350, + reconnectPeriod: 300 + }) server2.on('client', function (c) { client.publish('hello', 'world', { qos: 1 }, function () { - c.destroy(); - server2.close(); - client.publish('hello', 'world', { qos: 1 }); - }); - }); + c.destroy() + server2.close() + client.publish('hello', 'world', { qos: 1 }) + }) + }) setTimeout(function () { - if (0 === client.queue.length) { - client.end(true); - done(); + if (client.queue.length === 0) { + client.end(true) + done() } else { - client.end(true); + client.end(true) } - }, 2000); - }); - }); -}); + }, 2000) + }) + }) +}) diff --git a/test/helpers/server.js b/test/helpers/server.js index feca8c503..9750bf1ff 100644 --- a/test/helpers/server.js +++ b/test/helpers/server.js @@ -1,53 +1,42 @@ -'use strict'; -var Server = require('../server'), - fs = require('fs'); +'use strict' + +var Server = require('../server') +var fs = require('fs') module.exports.init_server = function (PORT) { var server = new Server(function (client) { - /* - var i, events = ['connect', 'publish', 'pubrel', 'subscribe', 'disconnect']; - - for (i = 0; i < events.length; i++) { - client.on(events[i], function (packet) { - //console.dir(packet); - }); - } - */ - client.on('connect', function () { - client.connack(0); - }); + client.connack(0) + }) client.on('publish', function (packet) { switch (packet.qos) { case 1: - client.puback({messageId: packet.messageId}); - break; + client.puback({messageId: packet.messageId}) + break case 2: - client.pubrec({messageId: packet.messageId}); - break; + client.pubrec({messageId: packet.messageId}) + break default: - // console.log('errors? QOS=', packet.qos); - break; + break } - - }); + }) client.on('pubrel', function (packet) { - client.pubcomp({messageId: packet.messageId}); - }); + client.pubcomp({messageId: packet.messageId}) + }) client.on('pingreq', function () { - client.pingresp(); - }); + client.pingresp() + }) client.on('disconnect', function () { - client.stream.end(); - }); - }); - server.listen(PORT); - return server; -}; + client.stream.end() + }) + }) + server.listen(PORT) + return server +} module.exports.init_secure_server = function (port, key, cert) { var server = new Server.SecureServer({ @@ -55,9 +44,9 @@ module.exports.init_secure_server = function (port, key, cert) { cert: fs.readFileSync(cert) }, function (client) { client.on('connect', function () { - client.connack({returnCode: 0}); - }); - }); - server.listen(port); - return server; -}; + client.connack({returnCode: 0}) + }) + }) + server.listen(port) + return server +} diff --git a/test/helpers/server_process.js b/test/helpers/server_process.js index 42b0327f8..747dc679f 100644 --- a/test/helpers/server_process.js +++ b/test/helpers/server_process.js @@ -1,10 +1,9 @@ -'use strict'; -/*eslint no-unused-vars:0*/ -var server, - Server = require('../server'); +'use strict' -server = new Server(function (client) { +var Server = require('../server') + +new Server(function (client) { client.on('connect', function () { - client.connack({ returnCode: 0 }); - }); -}).listen(3000, 'localhost'); + client.connack({ returnCode: 0 }) + }) +}).listen(3000, 'localhost') diff --git a/test/mqtt.js b/test/mqtt.js index 6f30dbf2a..66ab691ce 100644 --- a/test/mqtt.js +++ b/test/mqtt.js @@ -1,167 +1,163 @@ -'use strict'; -/*eslint no-path-concat:0*/ -/*eslint no-wrap-func:0*/ -/** - * Testing includes - */ +'use strict' -var fs = require('fs'), - mqtt = require('../'); - -/** - * Unit under test - */ +var fs = require('fs') +var path = require('path') +var mqtt = require('../') describe('mqtt', function () { - describe('#connect', function () { - var sslOpts, sslOpts2; + var sslOpts, sslOpts2 it('should return an MqttClient when connect is called with mqtt:/ url', function () { - var c = mqtt.connect('mqtt://localhost:1883'); + var c = mqtt.connect('mqtt://localhost:1883') - c.should.be.instanceOf(mqtt.MqttClient); - }); + c.should.be.instanceOf(mqtt.MqttClient) + }) it('should return an MqttClient with username option set', function () { - var c = mqtt.connect('mqtt://user:pass@localhost:1883'); + var c = mqtt.connect('mqtt://user:pass@localhost:1883') - c.should.be.instanceOf(mqtt.MqttClient); - c.options.should.have.property('username', 'user'); - c.options.should.have.property('password', 'pass'); - }); + c.should.be.instanceOf(mqtt.MqttClient) + c.options.should.have.property('username', 'user') + c.options.should.have.property('password', 'pass') + }) it('should return an MqttClient with username and password options set', function () { - var c = mqtt.connect('mqtt://user@localhost:1883'); + var c = mqtt.connect('mqtt://user@localhost:1883') - c.should.be.instanceOf(mqtt.MqttClient); - c.options.should.have.property('username', 'user'); - }); + c.should.be.instanceOf(mqtt.MqttClient) + c.options.should.have.property('username', 'user') + }) it('should return an MqttClient with the clientid option set', function () { - var c = mqtt.connect('mqtt://user@localhost:1883?clientId=123'); + var c = mqtt.connect('mqtt://user@localhost:1883?clientId=123') - c.should.be.instanceOf(mqtt.MqttClient); - c.options.should.have.property('clientId', '123'); - }); + c.should.be.instanceOf(mqtt.MqttClient) + c.options.should.have.property('clientId', '123') + }) it('should return an MqttClient when connect is called with tcp:/ url', function () { - var c = mqtt.connect('tcp://localhost'); + var c = mqtt.connect('tcp://localhost') - c.should.be.instanceOf(mqtt.MqttClient); - }); + c.should.be.instanceOf(mqtt.MqttClient) + }) it('should return an MqttClient with correct host when called with a host and port', function () { - var c = mqtt.connect('tcp://user:pass@localhost:1883'); + var c = mqtt.connect('tcp://user:pass@localhost:1883') - c.options.should.have.property('hostname', 'localhost'); - c.options.should.have.property('port', '1883'); - }); + c.options.should.have.property('hostname', 'localhost') + c.options.should.have.property('port', '1883') + }) sslOpts = { - keyPath: __dirname + '/helpers/private-key.pem', - certPath: __dirname + '/helpers/public-cert.pem', - caPaths: [__dirname + '/helpers/public-cert.pem'] - }; + keyPath: path.join(__dirname, 'helpers', 'private-key.pem'), + certPath: path.join(__dirname, 'helpers', 'public-cert.pem'), + caPaths: [path.join(__dirname, 'helpers', 'public-cert.pem')] + } it('should return an MqttClient when connect is called with mqtts:/ url', function () { - var c = mqtt.connect('mqtts://localhost', sslOpts); + var c = mqtt.connect('mqtts://localhost', sslOpts) - c.options.should.have.property('protocol', 'mqtts'); + c.options.should.have.property('protocol', 'mqtts') - c.on('error', function () {}); + c.on('error', function () {}) - c.should.be.instanceOf(mqtt.MqttClient); - }); + c.should.be.instanceOf(mqtt.MqttClient) + }) it('should return an MqttClient when connect is called with ssl:/ url', function () { - var c = mqtt.connect('ssl://localhost', sslOpts); + var c = mqtt.connect('ssl://localhost', sslOpts) - c.options.should.have.property('protocol', 'ssl'); + c.options.should.have.property('protocol', 'ssl') - c.on('error', function () {}); + c.on('error', function () {}) - c.should.be.instanceOf(mqtt.MqttClient); - }); + c.should.be.instanceOf(mqtt.MqttClient) + }) it('should return an MqttClient when connect is called with ws:/ url', function () { - var c = mqtt.connect('ws://localhost', sslOpts); + var c = mqtt.connect('ws://localhost', sslOpts) - c.options.should.have.property('protocol', 'ws'); + c.options.should.have.property('protocol', 'ws') - c.on('error', function () {}); + c.on('error', function () {}) - c.should.be.instanceOf(mqtt.MqttClient); - }); + c.should.be.instanceOf(mqtt.MqttClient) + }) it('should return an MqttClient when connect is called with wss:/ url', function () { - var c = mqtt.connect('wss://localhost', sslOpts); + var c = mqtt.connect('wss://localhost', sslOpts) + + c.options.should.have.property('protocol', 'wss') - c.options.should.have.property('protocol', 'wss'); + c.on('error', function () {}) - c.on('error', function () {}); + c.should.be.instanceOf(mqtt.MqttClient) + }) - c.should.be.instanceOf(mqtt.MqttClient); - }); sslOpts2 = { - key: fs.readFileSync(__dirname + '/helpers/private-key.pem'), - cert: fs.readFileSync(__dirname + '/helpers/public-cert.pem'), - ca: [fs.readFileSync(__dirname + '/helpers/public-cert.pem')] - }; - /*jshint -W068*/ + key: fs.readFileSync(path.join(__dirname, 'helpers', 'private-key.pem')), + cert: fs.readFileSync(path.join(__dirname, 'helpers', 'public-cert.pem')), + ca: [fs.readFileSync(path.join(__dirname, 'helpers', 'public-cert.pem'))] + } + it('should throw an error when it is called with cert and key set but no protocol specified', function () { // to do rewrite wrap function (function () { - var c = mqtt.connect(sslOpts2); - c.end(); - }).should.throw('Missing secure protocol key'); - }); + var c = mqtt.connect(sslOpts2) + c.end() + }).should.throw('Missing secure protocol key') + }) + it('should throw an error when it is called with cert and key set and protocol other than allowed: mqtt,mqtts,ws,wss', function () { (function () { - sslOpts2.protocol = 'UNKNOWNPROTOCOL'; - var c = mqtt.connect(sslOpts2); - c.end(); - }).should.throw(); - }); - /*jshint +W068*/ + sslOpts2.protocol = 'UNKNOWNPROTOCOL' + var c = mqtt.connect(sslOpts2) + c.end() + }).should.throw() + }) + it('should return a MqttClient with mqtts set when connect is called key and cert set and protocol mqtt', function () { - sslOpts2.protocol = 'mqtt'; - var c = mqtt.connect(sslOpts2); + sslOpts2.protocol = 'mqtt' + var c = mqtt.connect(sslOpts2) + + c.options.should.have.property('protocol', 'mqtts') - c.options.should.have.property('protocol', 'mqtts'); + c.on('error', function () {}) - c.on('error', function () {}); + c.should.be.instanceOf(mqtt.MqttClient) + }) - c.should.be.instanceOf(mqtt.MqttClient); - }); it('should return a MqttClient with mqtts set when connect is called key and cert set and protocol mqtts', function () { - sslOpts2.protocol = 'mqtts'; - var c = mqtt.connect(sslOpts2); + sslOpts2.protocol = 'mqtts' + var c = mqtt.connect(sslOpts2) - c.options.should.have.property('protocol', 'mqtts'); + c.options.should.have.property('protocol', 'mqtts') - c.on('error', function () {}); + c.on('error', function () {}) + + c.should.be.instanceOf(mqtt.MqttClient) + }) - c.should.be.instanceOf(mqtt.MqttClient); - }); it('should return a MqttClient with wss set when connect is called key and cert set and protocol ws', function () { - sslOpts2.protocol = 'ws'; - var c = mqtt.connect(sslOpts2); + sslOpts2.protocol = 'ws' + var c = mqtt.connect(sslOpts2) + + c.options.should.have.property('protocol', 'wss') - c.options.should.have.property('protocol', 'wss'); + c.on('error', function () {}) - c.on('error', function () {}); + c.should.be.instanceOf(mqtt.MqttClient) + }) - c.should.be.instanceOf(mqtt.MqttClient); - }); it('should return a MqttClient with wss set when connect is called key and cert set and protocol wss', function () { - sslOpts2.protocol = 'wss'; - var c = mqtt.connect(sslOpts2); + sslOpts2.protocol = 'wss' + var c = mqtt.connect(sslOpts2) - c.options.should.have.property('protocol', 'wss'); + c.options.should.have.property('protocol', 'wss') - c.on('error', function () {}); + c.on('error', function () {}) - c.should.be.instanceOf(mqtt.MqttClient); - }); - }); -}); + c.should.be.instanceOf(mqtt.MqttClient) + }) + }) +}) diff --git a/test/secure_client.js b/test/secure_client.js index 88ba531be..d4cb7ad47 100644 --- a/test/secure_client.js +++ b/test/secure_client.js @@ -1,112 +1,97 @@ -'use strict'; -/*global setImmediate:true*/ -/*eslint no-path-concat:0*/ -/** - * Testing dependencies - */ -var mqtt = require('..'), - abstractClientTests = require('./abstract_client'), - fs = require('fs'), - setImmediate = global.setImmediate || function (callback) { - // works in node v0.8 - process.nextTick(callback); - }, - // testing options - port = 9899, - // better use path.resolve(__dirname, 'helpers', "tls-key.pem") - // with this you are system path joining aware - KEY = __dirname + '/helpers/tls-key.pem', - CERT = __dirname + '/helpers/tls-cert.pem', - WRONG_CERT = __dirname + '/helpers/wrong-cert.pem', - Server = require('./server'), - server; - -/** - * Test server - */ -server = new Server.SecureServer({ +'use strict' + +var mqtt = require('..') +var path = require('path') +var abstractClientTests = require('./abstract_client') +var fs = require('fs') +var port = 9899 +var KEY = path.join(__dirname, 'helpers', 'tls-key.pem') +var CERT = path.join(__dirname, 'helpers', 'tls-cert.pem') +var WRONG_CERT = path.join(__dirname, 'helpers', 'wrong-cert.pem') +var Server = require('./server') + +var server = new Server.SecureServer({ key: fs.readFileSync(KEY), cert: fs.readFileSync(CERT) }, function (client) { client.on('connect', function (packet) { - if ('invalid' === packet.clientId) { - client.connack({returnCode: 2}); + if (packet.clientId === 'invalid') { + client.connack({returnCode: 2}) } else { - server.emit('connect', client); - client.connack({returnCode: 0}); + server.emit('connect', client) + client.connack({returnCode: 0}) } - }); + }) client.on('publish', function (packet) { setImmediate(function () { - /*jshint -W027*/ - /*eslint default-case:0*/ + /* jshint -W027 */ + /* eslint default-case:0 */ switch (packet.qos) { case 0: - break; + break case 1: - client.puback(packet); - break; + client.puback(packet) + break case 2: - client.pubrec(packet); - break; + client.pubrec(packet) + break } - /*jshint +W027*/ - }); - }); + /* jshint +W027 */ + }) + }) client.on('pubrel', function (packet) { - client.pubcomp(packet); - }); + client.pubcomp(packet) + }) client.on('pubrec', function (packet) { - client.pubrel(packet); - }); + client.pubrel(packet) + }) client.on('pubcomp', function () { // Nothing to be done - }); + }) client.on('subscribe', function (packet) { client.suback({ messageId: packet.messageId, granted: packet.subscriptions.map(function (e) { - return e.qos; + return e.qos }) - }); - }); + }) + }) client.on('unsubscribe', function (packet) { - client.unsuback(packet); - }); + client.unsuback(packet) + }) client.on('pingreq', function () { - client.pingresp(); - }); -}).listen(port); + client.pingresp() + }) +}).listen(port) describe('MqttSecureClient', function () { - var config = { protocol: 'mqtts', port: port, rejectUnauthorized: false }; - abstractClientTests(server, config); + var config = { protocol: 'mqtts', port: port, rejectUnauthorized: false } + abstractClientTests(server, config) describe('with secure parameters', function () { - it('should validate successfully the CA', function (done) { var client = mqtt.connect({ protocol: 'mqtts', port: port, ca: [fs.readFileSync(CERT)], rejectUnauthorized: true - }); + }) client.on('error', function (err) { - done(err); - }); + done(err) + }) server.once('connect', function () { - done(); - }); - }); + done() + }) + }) it('should validate unsuccessfully the CA', function (done) { var client = mqtt.connect({ @@ -114,14 +99,14 @@ describe('MqttSecureClient', function () { port: port, ca: [fs.readFileSync(WRONG_CERT)], rejectUnauthorized: true - }); + }) client.once('error', function () { - done(); - client.end(); - client.on('error', function () {}); - }); - }); + done() + client.end() + client.on('error', function () {}) + }) + }) it('should emit close on TLS error', function (done) { var client = mqtt.connect({ @@ -129,14 +114,14 @@ describe('MqttSecureClient', function () { port: port, ca: [fs.readFileSync(WRONG_CERT)], rejectUnauthorized: true - }); + }) - client.on('error', function () {}); + client.on('error', function () {}) // TODO node v0.8.x emits multiple close events client.once('close', function () { - done(); - }); - }); - }); -}); + done() + }) + }) + }) +}) diff --git a/test/server.js b/test/server.js index acaa95cb3..455d84c50 100644 --- a/test/server.js +++ b/test/server.js @@ -1,18 +1,15 @@ -'use strict'; -/** - * Requires - */ -var net = require('net'), - tls = require('tls'), - util = require('util'), - Connection = require('mqtt-connection'), - MqttServer, MqttSecureServer; +'use strict' + +var net = require('net') +var tls = require('tls') +var util = require('util') +var Connection = require('mqtt-connection') +var MqttServer +var MqttSecureServer function setupConnection (duplex) { - /*jshint validthis: true*/ - var connection = new Connection(duplex); - this.emit('client', connection); - /*jshint validthis: false*/ + var connection = new Connection(duplex) + this.emit('client', connection) } /* @@ -22,20 +19,20 @@ function setupConnection (duplex) { */ MqttServer = module.exports = function Server (listener) { if (!(this instanceof Server)) { - return new Server(listener); + return new Server(listener) } - net.Server.call(this); + net.Server.call(this) - this.on('connection', setupConnection); + this.on('connection', setupConnection) if (listener) { - this.on('client', listener); + this.on('client', listener) } - return this; -}; -util.inherits(MqttServer, net.Server); + return this +} +util.inherits(MqttServer, net.Server) /** * MqttSecureServer @@ -46,23 +43,23 @@ util.inherits(MqttServer, net.Server); MqttSecureServer = module.exports.SecureServer = function SecureServer (opts, listener) { if (!(this instanceof SecureServer)) { - return new SecureServer(opts, listener); + return new SecureServer(opts, listener) } // new MqttSecureServer(function(){}) - if ('function' === typeof opts) { - listener = opts; - opts = {}; + if (typeof opts === 'function') { + listener = opts + opts = {} } - tls.Server.call(this, opts); + tls.Server.call(this, opts) if (listener) { - this.on('client', listener); + this.on('client', listener) } - this.on('secureConnection', setupConnection); + this.on('secureConnection', setupConnection) - return this; - }; -util.inherits(MqttSecureServer, tls.Server); + return this + } +util.inherits(MqttSecureServer, tls.Server) diff --git a/test/store.js b/test/store.js index 5c00acd69..1489b2138 100644 --- a/test/store.js +++ b/test/store.js @@ -1,9 +1,10 @@ -'use strict'; -var Store = require('../lib/store'), - abstractTest = require('../test/abstract_store'); +'use strict' + +var Store = require('../lib/store') +var abstractTest = require('../test/abstract_store') describe('in-memory store', function () { abstractTest(function (done) { - done(null, new Store()); - }); -}); + done(null, new Store()) + }) +}) diff --git a/test/util.js b/test/util.js index 07b92bf39..813bbd904 100644 --- a/test/util.js +++ b/test/util.js @@ -1,16 +1,13 @@ -'use strict'; -/*global setImmediate:true*/ -var through = require('through2'), - setImmediate = global.setImmediate || function (callback) { - setTimeout(callback, 0); - }; +'use strict' + +var through = require('through2') module.exports.testStream = function () { return through(function (buf, enc, cb) { - var that = this; + var that = this setImmediate(function () { - that.push(buf); - cb(); - }); - }); -}; + that.push(buf) + cb() + }) + }) +} diff --git a/test/websocket_client.js b/test/websocket_client.js index aee7b0343..33e950f07 100644 --- a/test/websocket_client.js +++ b/test/websocket_client.js @@ -1,125 +1,114 @@ -'use strict'; -/** - * Testing dependencies - */ -/*global setImmediate:true*/ -var http = require('http'), - websocket = require('websocket-stream'), - WebSocketServer = require('ws').Server, - Connection = require('mqtt-connection'), - abstractClientTests = require('./abstract_client'), - mqtt = require('../'), - xtend = require('xtend'), - setImmediate = global.setImmediate || function (callback) { - // works in node v0.8 - process.nextTick(callback); - }, - port = 9999, - server = http.createServer(); - +'use strict' + +var http = require('http') +var websocket = require('websocket-stream') +var WebSocketServer = require('ws').Server +var Connection = require('mqtt-connection') +var abstractClientTests = require('./abstract_client') +var mqtt = require('../') +var xtend = require('xtend') +var port = 9999 +var server = http.createServer() function attachWebsocketServer (wsServer) { - var wss = new WebSocketServer({server: wsServer}); + var wss = new WebSocketServer({server: wsServer}) wss.on('connection', function (ws) { - var stream = websocket(ws), - connection = new Connection(stream); + var stream = websocket(ws) + var connection = new Connection(stream) - wsServer.emit('client', connection); - }); + wsServer.emit('client', connection) + }) - return wsServer; + return wsServer } -attachWebsocketServer(server); +attachWebsocketServer(server) server.on('client', function (client) { client.on('connect', function (packet) { - if ('invalid' === packet.clientId) { - client.connack({returnCode: 2}); + if (packet.clientId === 'invalid') { + client.connack({ returnCode: 2 }) } else { - server.emit('connect', client); - client.connack({returnCode: 0}); + server.emit('connect', client) + client.connack({returnCode: 0}) } - }); + }) client.on('publish', function (packet) { setImmediate(function () { - /*jshint -W027*/ - /*eslint default-case:0*/ switch (packet.qos) { case 0: - break; + break case 1: - client.puback(packet); - break; + client.puback(packet) + break case 2: - client.pubrec(packet); - break; + client.pubrec(packet) + break } - /*jshint +W027*/ - }); - }); + }) + }) client.on('pubrel', function (packet) { - client.pubcomp(packet); - }); + client.pubcomp(packet) + }) client.on('pubrec', function (packet) { - client.pubrel(packet); - }); + client.pubrel(packet) + }) client.on('pubcomp', function () { // Nothing to be done - }); + }) client.on('subscribe', function (packet) { client.suback({ messageId: packet.messageId, granted: packet.subscriptions.map(function (e) { - return e.qos; + return e.qos }) - }); - }); + }) + }) client.on('unsubscribe', function (packet) { - client.unsuback(packet); - }); + client.unsuback(packet) + }) client.on('pingreq', function () { - client.pingresp(); - }); -}).listen(port); + client.pingresp() + }) +}).listen(port) describe('Websocket Client', function () { - var config = { protocol: 'ws', port: port }; + var config = { protocol: 'ws', port: port } it('should use mqtt as the protocol by default', function (done) { server.once('client', function (client) { - client.stream.socket.protocol.should.equal('mqtt'); - }); + client.stream.socket.protocol.should.equal('mqtt') + }) - var opts = xtend(config, {}); + var opts = xtend(config, {}) mqtt.connect(opts).on('connect', function () { - this.end(true, done); - }); - }); + this.end(true, done) + }) + }) it('should use mqttv3.1 as the protocol if using v3.1', function (done) { server.once('client', function (client) { - client.stream.socket.protocol.should.equal('mqttv3.1'); - }); + client.stream.socket.protocol.should.equal('mqttv3.1') + }) var opts = xtend(config, { protocolId: 'MQIsdp', protocolVersion: 3 - }); + }) mqtt.connect(opts).on('connect', function () { - this.end(true, done); - }); - }); + this.end(true, done) + }) + }) - abstractClientTests(server, config); -}); + abstractClientTests(server, config) +})