index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. 'use strict'
  2. var MqttClient = require('../client')
  3. var Store = require('../store')
  4. var url = require('url')
  5. var xtend = require('xtend')
  6. var protocols = {}
  7. if (process.title !== 'browser') {
  8. protocols.mqtt = require('./tcp')
  9. protocols.tcp = require('./tcp')
  10. protocols.ssl = require('./tls')
  11. protocols.tls = require('./tls')
  12. protocols.mqtts = require('./tls')
  13. } else {
  14. protocols.wx = require('./wx')
  15. protocols.wxs = require('./wx')
  16. }
  17. protocols.ws = require('./ws')
  18. protocols.wss = require('./ws')
  19. /**
  20. * Parse the auth attribute and merge username and password in the options object.
  21. *
  22. * @param {Object} [opts] option object
  23. */
  24. function parseAuthOptions (opts) {
  25. var matches
  26. if (opts.auth) {
  27. matches = opts.auth.match(/^(.+):(.+)$/)
  28. if (matches) {
  29. opts.username = matches[1]
  30. opts.password = matches[2]
  31. } else {
  32. opts.username = opts.auth
  33. }
  34. }
  35. }
  36. /**
  37. * connect - connect to an MQTT broker.
  38. *
  39. * @param {String} [brokerUrl] - url of the broker, optional
  40. * @param {Object} opts - see MqttClient#constructor
  41. */
  42. function connect (brokerUrl, opts) {
  43. if ((typeof brokerUrl === 'object') && !opts) {
  44. opts = brokerUrl
  45. brokerUrl = null
  46. }
  47. opts = opts || {}
  48. if (brokerUrl) {
  49. var parsed = url.parse(brokerUrl, true)
  50. if (parsed.port != null) {
  51. parsed.port = Number(parsed.port)
  52. }
  53. opts = xtend(parsed, opts)
  54. if (opts.protocol === null) {
  55. throw new Error('Missing protocol')
  56. }
  57. opts.protocol = opts.protocol.replace(/:$/, '')
  58. }
  59. // merge in the auth options if supplied
  60. parseAuthOptions(opts)
  61. // support clientId passed in the query string of the url
  62. if (opts.query && typeof opts.query.clientId === 'string') {
  63. opts.clientId = opts.query.clientId
  64. }
  65. if (opts.cert && opts.key) {
  66. if (opts.protocol) {
  67. if (['mqtts', 'wss', 'wxs'].indexOf(opts.protocol) === -1) {
  68. switch (opts.protocol) {
  69. case 'mqtt':
  70. opts.protocol = 'mqtts'
  71. break
  72. case 'ws':
  73. opts.protocol = 'wss'
  74. break
  75. case 'wx':
  76. opts.protocol = 'wxs'
  77. break
  78. default:
  79. throw new Error('Unknown protocol for secure connection: "' + opts.protocol + '"!')
  80. }
  81. }
  82. } else {
  83. // don't know what protocol he want to use, mqtts or wss
  84. throw new Error('Missing secure protocol key')
  85. }
  86. }
  87. if (!protocols[opts.protocol]) {
  88. var isSecure = ['mqtts', 'wss'].indexOf(opts.protocol) !== -1
  89. opts.protocol = [
  90. 'mqtt',
  91. 'mqtts',
  92. 'ws',
  93. 'wss',
  94. 'wx',
  95. 'wxs'
  96. ].filter(function (key, index) {
  97. if (isSecure && index % 2 === 0) {
  98. // Skip insecure protocols when requesting a secure one.
  99. return false
  100. }
  101. return (typeof protocols[key] === 'function')
  102. })[0]
  103. }
  104. if (opts.clean === false && !opts.clientId) {
  105. throw new Error('Missing clientId for unclean clients')
  106. }
  107. if (opts.protocol) {
  108. opts.defaultProtocol = opts.protocol
  109. }
  110. function wrapper (client) {
  111. if (opts.servers) {
  112. if (!client._reconnectCount || client._reconnectCount === opts.servers.length) {
  113. client._reconnectCount = 0
  114. }
  115. opts.host = opts.servers[client._reconnectCount].host
  116. opts.port = opts.servers[client._reconnectCount].port
  117. opts.protocol = (!opts.servers[client._reconnectCount].protocol ? opts.defaultProtocol : opts.servers[client._reconnectCount].protocol)
  118. opts.hostname = opts.host
  119. client._reconnectCount++
  120. }
  121. return protocols[opts.protocol](client, opts)
  122. }
  123. return new MqttClient(wrapper, opts)
  124. }
  125. module.exports = connect
  126. module.exports.connect = connect
  127. module.exports.MqttClient = MqttClient
  128. module.exports.Store = Store