websocket_client.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. 'use strict'
  2. var http = require('http')
  3. var websocket = require('websocket-stream')
  4. var WebSocketServer = require('ws').Server
  5. var Connection = require('mqtt-connection')
  6. var abstractClientTests = require('./abstract_client')
  7. var mqtt = require('../')
  8. var xtend = require('xtend')
  9. var assert = require('assert')
  10. var port = 9999
  11. var server = http.createServer()
  12. function attachWebsocketServer (wsServer) {
  13. var wss = new WebSocketServer({server: wsServer, perMessageDeflate: false})
  14. wss.on('connection', function (ws) {
  15. var stream = websocket(ws)
  16. var connection = new Connection(stream)
  17. wsServer.emit('client', connection)
  18. stream.on('error', function () {})
  19. connection.on('error', function () {})
  20. })
  21. return wsServer
  22. }
  23. attachWebsocketServer(server)
  24. server.on('client', function (client) {
  25. client.on('connect', function (packet) {
  26. if (packet.clientId === 'invalid') {
  27. client.connack({ returnCode: 2 })
  28. } else {
  29. server.emit('connect', client)
  30. client.connack({returnCode: 0})
  31. }
  32. })
  33. client.on('publish', function (packet) {
  34. setImmediate(function () {
  35. switch (packet.qos) {
  36. case 0:
  37. break
  38. case 1:
  39. client.puback(packet)
  40. break
  41. case 2:
  42. client.pubrec(packet)
  43. break
  44. }
  45. })
  46. })
  47. client.on('pubrel', function (packet) {
  48. client.pubcomp(packet)
  49. })
  50. client.on('pubrec', function (packet) {
  51. client.pubrel(packet)
  52. })
  53. client.on('pubcomp', function () {
  54. // Nothing to be done
  55. })
  56. client.on('subscribe', function (packet) {
  57. client.suback({
  58. messageId: packet.messageId,
  59. granted: packet.subscriptions.map(function (e) {
  60. return e.qos
  61. })
  62. })
  63. })
  64. client.on('unsubscribe', function (packet) {
  65. client.unsuback(packet)
  66. })
  67. client.on('pingreq', function () {
  68. client.pingresp()
  69. })
  70. }).listen(port)
  71. describe('Websocket Client', function () {
  72. var baseConfig = { protocol: 'ws', port: port }
  73. function makeOptions (custom) {
  74. // xtend returns a new object. Does not mutate arguments
  75. return xtend(baseConfig, custom || {})
  76. }
  77. it('should use mqtt as the protocol by default', function (done) {
  78. server.once('client', function (client) {
  79. client.stream.socket.protocol.should.equal('mqtt')
  80. })
  81. mqtt.connect(makeOptions()).on('connect', function () {
  82. this.end(true, done)
  83. })
  84. })
  85. it('should be able transform the url (for e.g. to sign it)', function (done) {
  86. var baseUrl = 'ws://localhost:9999/mqtt'
  87. var sig = '?AUTH=token'
  88. var expected = baseUrl + sig
  89. var actual
  90. var opts = makeOptions({
  91. path: '/mqtt',
  92. transformWsUrl: function (url, opt, client) {
  93. assert.equal(url, baseUrl)
  94. assert.strictEqual(opt, opts)
  95. assert.strictEqual(client.options, opts)
  96. assert.strictEqual(typeof opt.transformWsUrl, 'function')
  97. assert(client instanceof mqtt.MqttClient)
  98. url += sig
  99. actual = url
  100. return url
  101. }})
  102. mqtt.connect(opts)
  103. .on('connect', function () {
  104. assert.equal(this.stream.socket.url, expected)
  105. assert.equal(actual, expected)
  106. this.end(true, done)
  107. })
  108. })
  109. it('should use mqttv3.1 as the protocol if using v3.1', function (done) {
  110. server.once('client', function (client) {
  111. client.stream.socket.protocol.should.equal('mqttv3.1')
  112. })
  113. var opts = makeOptions({
  114. protocolId: 'MQIsdp',
  115. protocolVersion: 3
  116. })
  117. mqtt.connect(opts).on('connect', function () {
  118. this.end(true, done)
  119. })
  120. })
  121. abstractClientTests(server, makeOptions())
  122. })