763 lines
18 KiB
JavaScript
763 lines
18 KiB
JavaScript
'use strict'
|
|
|
|
const { test } = require('tap')
|
|
const http = require('http')
|
|
const ws = require('websocket-stream')
|
|
const mqtt = require('mqtt')
|
|
const { setup, connect, delay } = require('./helper')
|
|
const aedes = require('../')
|
|
|
|
;[{ ver: 3, id: 'MQIsdp' }, { ver: 4, id: 'MQTT' }].forEach(function (ele) {
|
|
test('connect and connack (minimal)', function (t) {
|
|
t.plan(2)
|
|
|
|
const s = setup()
|
|
t.teardown(s.broker.close.bind(s.broker))
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: ele.id,
|
|
protocolVersion: ele.ver,
|
|
clean: true,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
})
|
|
|
|
s.outStream.on('data', function (packet) {
|
|
t.same(packet, {
|
|
cmd: 'connack',
|
|
returnCode: 0,
|
|
length: 2,
|
|
qos: 0,
|
|
retain: false,
|
|
dup: false,
|
|
topic: null,
|
|
payload: null,
|
|
sessionPresent: false
|
|
}, 'successful connack')
|
|
t.equal(s.client.version, ele.ver)
|
|
})
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.2-2]
|
|
test('reject client requested for unacceptable protocol version', function (t) {
|
|
t.plan(4)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQIsdp',
|
|
protocolVersion: 5,
|
|
clean: true,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 1, 'unacceptable protocol version')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
broker.on('clientError', function (client, err) {
|
|
t.fail('should not raise clientError error')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'unacceptable protocol version')
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.2-1], Guarded in mqtt-packet
|
|
test('reject client requested for unsupported protocol version', function (t) {
|
|
t.plan(3)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 2,
|
|
clean: true,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.fail('no data sent')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(client.version, null)
|
|
t.equal(err.message, 'Invalid protocol version')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
})
|
|
|
|
test('reject clients that exceed the keepalive limit', function (t) {
|
|
t.plan(3)
|
|
|
|
const broker = aedes({
|
|
keepaliveLimit: 100
|
|
})
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
keepalive: 150
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
console.log(packet)
|
|
t.same(packet, {
|
|
cmd: 'connack',
|
|
returnCode: 6,
|
|
length: 2,
|
|
qos: 0,
|
|
retain: false,
|
|
dup: false,
|
|
topic: null,
|
|
payload: null,
|
|
sessionPresent: false
|
|
}, 'unsuccessful connack, keep alive limit exceeded')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'keep alive limit exceeded')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
})
|
|
|
|
// Guarded in mqtt-packet
|
|
test('reject clients with no clientId running on MQTT 3.1.0', function (t) {
|
|
t.plan(3)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQIsdp',
|
|
protocolVersion: 3,
|
|
clean: true,
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.fail('no data sent')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(client.version, null)
|
|
t.equal(err.message, 'clientId must be supplied before 3.1.1')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.3-7], Guarded in mqtt-packet
|
|
test('reject clients without clientid and clean=false on MQTT 3.1.1', function (t) {
|
|
t.plan(2)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: false,
|
|
clientId: '',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.fail('no data sent')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'clientId must be given if cleanSession set to 0')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
})
|
|
|
|
test('clients without clientid and clean=true on MQTT 3.1.1 will get a generated clientId', function (t) {
|
|
t.plan(5)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 0)
|
|
t.equal(broker.connectedClients, 1)
|
|
t.equal(s.client.version, 4)
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.error(err, 'no error')
|
|
})
|
|
broker.on('client', function (client) {
|
|
t.ok(client.id.startsWith('aedes_'))
|
|
})
|
|
})
|
|
|
|
test('client connect error while fetching subscriptions', function (t) {
|
|
t.plan(2)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
broker.persistence.subscriptionsByClient = function (c, cb) {
|
|
cb(new Error('error'), [], c)
|
|
}
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: false,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
})
|
|
|
|
broker.on('clientError', function (client, err) {
|
|
t.equal(client.version, 4)
|
|
t.pass('throws error')
|
|
})
|
|
})
|
|
|
|
test('client connect clear outgoing', function (t) {
|
|
t.plan(1)
|
|
|
|
const clientId = 'abcde'
|
|
const brokerId = 'pippo'
|
|
|
|
const broker = aedes({ id: brokerId })
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const subs = [{ clientId }]
|
|
const packet = {
|
|
cmd: 'publish',
|
|
topic: 'hello',
|
|
payload: Buffer.from('world'),
|
|
qos: 1,
|
|
brokerId,
|
|
brokerCounter: 2,
|
|
retain: true,
|
|
messageId: 42,
|
|
dup: false
|
|
}
|
|
|
|
broker.persistence.outgoingEnqueueCombi(subs, packet, function () {
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId,
|
|
keepalive: 0
|
|
})
|
|
|
|
broker.on('clientReady', function (client) {
|
|
broker.persistence.outgoingUpdate(client, packet, function (err) {
|
|
t.equal('no such packet', err.message, 'packet not found')
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('clients with zero-byte clientid and clean=true on MQTT 3.1.1 will get a generated clientId', function (t) {
|
|
t.plan(5)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: '',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 0)
|
|
t.equal(broker.connectedClients, 1)
|
|
t.equal(s.client.version, 4)
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.error(err, 'no error')
|
|
})
|
|
broker.on('client', function (client) {
|
|
t.ok(client.id.startsWith('aedes_'))
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.3-7]
|
|
test('reject clients with > 23 clientId length in MQTT 3.1.0', function (t) {
|
|
t.plan(7)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
const conn = s.client.conn
|
|
const end = conn.end
|
|
|
|
conn.end = function () {
|
|
t.fail('should not call `conn.end()`')
|
|
end()
|
|
}
|
|
|
|
function drain () {
|
|
t.pass('should empty connection request queue')
|
|
}
|
|
|
|
conn._writableState.getBuffer = () => [{ callback: drain }, { callback: drain }]
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQIsdp',
|
|
protocolVersion: 3,
|
|
clean: true,
|
|
clientId: 'abcdefghijklmnopqrstuvwxyz',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 2, 'identifier rejected')
|
|
t.equal(broker.connectedClients, 0)
|
|
t.equal(s.client.version, null)
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'identifier rejected')
|
|
})
|
|
})
|
|
|
|
test('connect clients with > 23 clientId length using aedes maxClientsIdLength option in MQTT 3.1.0', function (t) {
|
|
t.plan(4)
|
|
|
|
const broker = aedes({ maxClientsIdLength: 26 })
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 3,
|
|
clean: true,
|
|
clientId: 'abcdefghijklmnopqrstuvwxyz',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 0)
|
|
t.equal(broker.connectedClients, 1)
|
|
t.equal(s.client.version, 3)
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.error(err, 'no error')
|
|
})
|
|
})
|
|
|
|
test('connect with > 23 clientId length in MQTT 3.1.1', function (t) {
|
|
t.plan(4)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'abcdefghijklmnopqrstuvwxyz',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.equal(packet.cmd, 'connack')
|
|
t.equal(packet.returnCode, 0)
|
|
t.equal(broker.connectedClients, 1)
|
|
t.equal(s.client.version, 4)
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.error(err, 'no error')
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.0-1]
|
|
test('the first Packet MUST be a CONNECT Packet', function (t) {
|
|
t.plan(2)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const packet = {
|
|
cmd: 'publish',
|
|
topic: 'hello',
|
|
payload: Buffer.from('world'),
|
|
qos: 0,
|
|
retain: false
|
|
}
|
|
const s = setup(broker)
|
|
s.inStream.write(packet)
|
|
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'Invalid protocol')
|
|
})
|
|
setImmediate(() => {
|
|
t.ok(s.conn.destroyed, 'close connection if first packet is not a CONNECT')
|
|
s.conn.destroy()
|
|
})
|
|
})
|
|
|
|
// [MQTT-3.1.0-2]
|
|
test('second CONNECT Packet sent from a Client as a protocol violation and disconnect the Client', function (t) {
|
|
t.plan(4)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const packet = {
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
}
|
|
broker.on('clientError', function (client, err) {
|
|
t.equal(err.message, 'Invalid protocol')
|
|
})
|
|
const s = connect(setup(broker), { clientId: 'abcde' })
|
|
s.broker.on('clientReady', function () {
|
|
t.ok(broker.clients.abcde.connected)
|
|
// destory client when there is a 2nd cmd:connect, even the clientId is dfferent
|
|
s.inStream.write(packet)
|
|
setImmediate(() => {
|
|
t.equal(broker.clients.abcde, undefined, 'client instance is removed')
|
|
t.ok(s.conn.destroyed, 'close connection if packet is a CONNECT after network is established')
|
|
})
|
|
})
|
|
})
|
|
|
|
test('connect handler calls done when preConnect throws error', function (t) {
|
|
t.plan(1)
|
|
|
|
const broker = aedes({
|
|
preConnect: function (client, packet, done) {
|
|
done(Error('error in preconnect'))
|
|
}
|
|
})
|
|
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
const handleConnect = require('../lib/handlers/connect')
|
|
|
|
handleConnect(s.client, {}, function done (err) {
|
|
t.equal(err.message, 'error in preconnect', 'calls done with error')
|
|
})
|
|
})
|
|
|
|
test('handler calls done when disconnect or unknown packet cmd is received', function (t) {
|
|
t.plan(2)
|
|
|
|
const broker = aedes()
|
|
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
const handle = require('../lib/handlers/index')
|
|
|
|
handle(s.client, { cmd: 'disconnect' }, function done () {
|
|
t.pass('calls done when disconnect cmd is received')
|
|
})
|
|
|
|
handle(s.client, { cmd: 'fsfadgragae' }, function done () {
|
|
t.pass('calls done when unknown cmd is received')
|
|
})
|
|
})
|
|
|
|
test('reject second CONNECT Packet sent while first CONNECT still in preConnect stage', function (t) {
|
|
t.plan(2)
|
|
|
|
const packet1 = {
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'my-client-1',
|
|
keepalive: 0
|
|
}
|
|
const packet2 = {
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'my-client-2',
|
|
keepalive: 0
|
|
}
|
|
|
|
let i = 0
|
|
const broker = aedes({
|
|
preConnect: function (client, packet, done) {
|
|
const ms = i++ === 0 ? 2000 : 500
|
|
setTimeout(function () {
|
|
done(null, true)
|
|
}, ms)
|
|
}
|
|
})
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.info.clientId, 'my-client-2')
|
|
t.equal(err.message, 'Invalid protocol')
|
|
})
|
|
|
|
const msg = async (s, ms, msg) => {
|
|
await delay(ms)
|
|
s.inStream.write(msg)
|
|
}
|
|
|
|
;(async () => {
|
|
await Promise.all([msg(s, 100, packet1), msg(s, 200, packet2)])
|
|
})().catch(
|
|
(error) => {
|
|
t.fail(error)
|
|
}
|
|
)
|
|
})
|
|
|
|
// [MQTT-3.1.2-1], Guarded in mqtt-packet
|
|
test('reject clients with wrong protocol name', function (t) {
|
|
t.plan(2)
|
|
|
|
const broker = aedes()
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT_hello',
|
|
protocolVersion: 3,
|
|
clean: true,
|
|
clientId: 'my-client',
|
|
keepalive: 0
|
|
})
|
|
s.outStream.on('data', function (packet) {
|
|
t.fail('no data sent')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
t.equal(err.message, 'Invalid protocolId')
|
|
t.equal(broker.connectedClients, 0)
|
|
})
|
|
})
|
|
|
|
test('After first CONNECT Packet, others are queued until \'connect\' event', function (t) {
|
|
t.plan(2)
|
|
|
|
const queueLimit = 50
|
|
const broker = aedes({ queueLimit })
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const publishP = {
|
|
cmd: 'publish',
|
|
topic: 'hello',
|
|
payload: Buffer.from('world'),
|
|
qos: 0,
|
|
retain: false
|
|
}
|
|
|
|
const connectP = {
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'abcde',
|
|
keepalive: 0
|
|
}
|
|
|
|
const s = setup(broker)
|
|
s.inStream.write(connectP)
|
|
|
|
process.once('warning', e => t.fail('Memory leak detected'))
|
|
|
|
for (let i = 0; i < queueLimit; i++) {
|
|
s.inStream.write(publishP)
|
|
}
|
|
|
|
broker.on('client', function (client) {
|
|
t.equal(client._parser._queue.length, queueLimit, 'Packets have been queued')
|
|
|
|
client.once('connected', () => {
|
|
t.equal(client._parser._queue, null, 'Queue is empty')
|
|
s.conn.destroy()
|
|
})
|
|
})
|
|
})
|
|
|
|
test('Test queue limit', function (t) {
|
|
t.plan(1)
|
|
|
|
const queueLimit = 50
|
|
const broker = aedes({ queueLimit })
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const publishP = {
|
|
cmd: 'publish',
|
|
topic: 'hello',
|
|
payload: Buffer.from('world'),
|
|
qos: 0,
|
|
retain: false
|
|
}
|
|
|
|
const connectP = {
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'abcde',
|
|
keepalive: 0
|
|
}
|
|
|
|
const s = setup(broker)
|
|
s.inStream.write(connectP)
|
|
|
|
process.once('warning', e => t.fail('Memory leak detected'))
|
|
|
|
for (let i = 0; i < queueLimit + 1; i++) {
|
|
s.inStream.write(publishP)
|
|
}
|
|
|
|
broker.on('connectionError', function (conn, err) {
|
|
t.equal(err.message, 'Client queue limit reached', 'Queue error is thrown')
|
|
s.conn.destroy()
|
|
})
|
|
})
|
|
|
|
;[['fail with no error msg', 3, null, false], ['succeed with no error msg', 9, null, true], ['fail with error msg', 6, new Error('connection banned'), false], ['succeed with error msg', 6, new Error('connection banned'), true]].forEach(function (ele, idx) {
|
|
const title = ele[0]
|
|
const plan = ele[1]
|
|
const err = ele[2]
|
|
const ok = ele[3]
|
|
test('preConnect handler - ' + title, function (t) {
|
|
t.plan(plan)
|
|
|
|
const broker = aedes({
|
|
preConnect: function (client, packet, done) {
|
|
t.ok(client.connecting)
|
|
t.notOk(client.connected)
|
|
t.equal(client.version, null)
|
|
return done(err, ok)
|
|
}
|
|
})
|
|
t.teardown(broker.close.bind(broker))
|
|
|
|
const s = setup(broker)
|
|
|
|
s.inStream.write({
|
|
cmd: 'connect',
|
|
protocolId: 'MQTT',
|
|
protocolVersion: 4,
|
|
clean: true,
|
|
clientId: 'my-client-' + idx,
|
|
keepalive: 0
|
|
})
|
|
broker.on('client', function (client) {
|
|
if (ok && !err) {
|
|
t.ok(client.connecting)
|
|
t.notOk(client.connected)
|
|
t.pass('register client ok')
|
|
} else {
|
|
t.fail('no reach here')
|
|
}
|
|
})
|
|
broker.on('clientReady', function (client) {
|
|
t.notOk(client.connecting)
|
|
t.ok(client.connected)
|
|
t.pass('connect ok')
|
|
})
|
|
broker.on('clientError', function (client, err) {
|
|
t.fail('no client error')
|
|
})
|
|
broker.on('connectionError', function (client, err) {
|
|
if (err) {
|
|
t.notOk(client.connecting)
|
|
t.notOk(client.connected)
|
|
t.equal(err.message, 'connection banned')
|
|
} else {
|
|
t.fail('no connection error')
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
// websocket-stream based connections
|
|
test('websocket clients have access to the request object', function (t) {
|
|
t.plan(3)
|
|
|
|
const port = 4883
|
|
const broker = aedes()
|
|
broker.on('client', function (client) {
|
|
if (client.req) {
|
|
t.pass('client request object present')
|
|
if (client.req.headers) {
|
|
t.equal('sample', client.req.headers['x-test-protocol'])
|
|
}
|
|
} else {
|
|
t.fail('no request object present')
|
|
}
|
|
})
|
|
|
|
const server = http.createServer()
|
|
ws.createServer({
|
|
server
|
|
}, broker.handle)
|
|
|
|
server.listen(port, function (err) {
|
|
t.error(err, 'no error')
|
|
})
|
|
|
|
const client = mqtt.connect(`ws://localhost:${port}`, {
|
|
wsOptions: {
|
|
headers: {
|
|
'X-Test-Protocol': 'sample'
|
|
}
|
|
}
|
|
})
|
|
|
|
t.teardown(() => {
|
|
client.end(true)
|
|
broker.close()
|
|
server.close()
|
|
})
|
|
})
|