index.js 3.9 KB

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