moduleMqtt.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. import mqtt from '../../common/mqtt.js'
  2. import Vue from 'vue'
  3. import { messageParse, indexOfUuid } from './mqttParse.js'
  4. //import mqtt from 'mqtt/dist/mqtt.js'
  5. const options = {
  6. clientId: "wx_" + parseInt(Math.random() * 100 + 800, 10),
  7. keepalive: 28, //每28秒发送一次心跳
  8. connectTimeout: 15 * 1000, //连接超时的时间
  9. };
  10. let url = 'wss://mqtt.test.radio1964.com'
  11. // #ifdef MP-WEIXIN
  12. url = 'wxs://mqtt.test.radio1964.com'
  13. // #endif
  14. //订阅设备在线状态
  15. function subscribeDevicesStatus(dispatch, deviceList) {
  16. deviceList.forEach((value) => {
  17. let topic = `/${value.uuid}/status/onoffline`
  18. dispatch('subscribe', topic)
  19. })
  20. }
  21. //订阅消息
  22. // function subscribeCurrDevice(dispatch, device) {
  23. // if (device) {
  24. // let topic = `/${device.uuid}/user/pub_response`
  25. // dispatch('subscribe', topic)
  26. // }
  27. // }
  28. export default {
  29. namespaced: true,
  30. state: {
  31. //当前选择的设备
  32. currentDevice: null,
  33. //用户设备列表
  34. deviceList: [],
  35. //mqtt客户端
  36. mqttClient: null,
  37. //收到的消息的历史记录
  38. msgList: [],
  39. //设备的播放信息
  40. playInfo: {
  41. title: "",
  42. artist: "",
  43. albumURI: "",
  44. songInfoID: "",
  45. songAlbumID: "",
  46. Duration: 0,
  47. channel: 1,
  48. audioType: 1,
  49. PlayState: 3,
  50. PlayMode: 0
  51. }
  52. },
  53. getters: {
  54. //mqtt连接状态
  55. connected: state => {
  56. return state.mqttClient && state.mqttClient.connected
  57. },
  58. //更具index找到对应的设备
  59. getDeviceByIndex: (state) => (index) => {
  60. if (index < 0 || index >= state.deviceList.length) {
  61. return null
  62. } else {
  63. return state.deviceList[index]
  64. }
  65. },
  66. //根据uuid找到对应的设备
  67. getDeviceById: (state) => (uuid) => {
  68. return state.deviceList.find(todo => todo.uuid === uuid)
  69. }
  70. },
  71. mutations: {
  72. //添加设备
  73. addDevice(state, device) {
  74. state.deviceList.push(device)
  75. },
  76. //设置当前选择的设备
  77. setCurrentDevice(state, device) {
  78. //state.currentDevice = device
  79. Vue.set(state, 'currentDevice', device)
  80. },
  81. //移除设备
  82. removeDevice(state, device) {
  83. let index = state.deviceList.indexOf(device)
  84. state.deviceList.slice(index, 1)
  85. },
  86. //连接mqtt服务器 clientId为wx_加上用户的uid
  87. connect(state, clientId) {
  88. console.log(`connect clientId = ${clientId}`);
  89. options.clientId = clientId
  90. state.mqttClient = mqtt.connect(url, options)
  91. },
  92. //token失效,退出登录,需要清除数据
  93. release(state) {
  94. state.deviceList = []
  95. state.currentDevice = null
  96. state.mqttClient = null
  97. },
  98. //更新设备信息
  99. updateDevice(state, data) {
  100. Vue.set(state.deviceList, data.index, data.device)
  101. },
  102. //更新播放信息
  103. updatePlayInfo(state, playinfo) {
  104. state.playInfo = playinfo
  105. }
  106. },
  107. actions: {
  108. //添加设备
  109. addDevice({ state, dispatch, commit, getters }, data) {
  110. let clientId = (data.clientId) ? data.clientId : options.clientId
  111. let device = data.device
  112. console.log(`deviceList = ${state.deviceList} device = ${device}`);
  113. //判断设备是否存在deviceList中
  114. let findDevice = state.deviceList.find((item) => {
  115. return item.uuid === device.uuid
  116. })
  117. if (findDevice == null) {
  118. if (state.deviceList.length === 0) {
  119. //设置当前的设备为添加的设备
  120. commit('setCurrentDevice', device)
  121. }
  122. //添加设备
  123. state.deviceList.push(device)
  124. //如果已经连接
  125. if (getters.connected) {
  126. //订阅设备是否在线
  127. subscribeDevicesStatus(dispatch, [device])
  128. //if (state.currentDevice && state.currentDevice.uuid === device.uuid) {
  129. //订阅当前设备的消息
  130. //subscribeCurrDevice(dispatch, state.currentDevice)
  131. //}
  132. } else { //如果没有连接
  133. //连接服务器
  134. dispatch('connect', clientId)
  135. }
  136. }
  137. },
  138. //删除设备
  139. removeDevice({ state, dispatch, commit, getters }, device) {
  140. //判断设备是否存在deviceList中
  141. let findDevice = state.deviceList.find((item) => {
  142. return item.uuid === device.uuid
  143. })
  144. if (findDevice) {
  145. //取消此设备的订阅
  146. let topic = `/${device.uuid}/status/onoffline`
  147. dispatch('unsubscribe', topic)
  148. topic = `/${device.uuid}/status/pub_response`
  149. dispatch('unsubscribe', topic)
  150. //在设备列表中删除此设备
  151. commit('removeDevice', findDevice)
  152. //如果删除的是选中的设备
  153. if (currentDevice && state.currentDevice.uuid == device.uuid) {
  154. //清除当前选中的设备 todo 还是自动选中在线的设备
  155. commit('setCurrentDevice', null)
  156. }
  157. if (state.deviceList.length === 0) { //所有的设备都已经删除,关闭连接
  158. dispatch('disconnect')
  159. }
  160. }
  161. },
  162. //连接设备
  163. connect({ state, dispatch, commit, getters }, clientId) {
  164. if (state.mqttClient == null) {
  165. //连接服务器
  166. commit('connect', clientId)
  167. //连接成功回调
  168. state.mqttClient.on("connect", function() {
  169. console.log("connect success!");
  170. //订阅设备是否在线
  171. subscribeDevicesStatus(dispatch, state.deviceList)
  172. //订阅当前设备的消息
  173. //subscribeCurrDevice(dispatch, state.currentDevice)
  174. });
  175. //异常回调
  176. state.mqttClient.on("error", function(err) {
  177. console.log(err);
  178. });
  179. state.mqttClient.on('offline', function() {
  180. console.log(`offline callback`);
  181. })
  182. state.mqttClient.on('end', function() {
  183. console.log(`end callback`);
  184. })
  185. //网络断开的回调
  186. state.mqttClient.on('close', function() {
  187. console.log(`close callback`);
  188. })
  189. //收到消息的回调
  190. state.mqttClient.on('message', function(topic, message) {
  191. console.log(`message = ${message.toString()}`);
  192. //解析收到的消息
  193. messageParse({ state, dispatch, commit, getters }, topic, message)
  194. //这是测试的
  195. state.msgList.push({
  196. topic: topic.toString(),
  197. msg: message.toString(),
  198. });
  199. })
  200. } else {
  201. if (!state.mqttClient.connected) {
  202. console.log("reconnect");
  203. state.mqttClient.reconnect()
  204. //重连成功的回调
  205. state.mqttClient.on("reconnect", function() {
  206. console.log("reconnect success!");
  207. });
  208. }
  209. }
  210. },
  211. //断开mqtt的连接
  212. disconnect({ state, commit }, isRelease) {
  213. console.log('disconnect')
  214. if (state.mqttClient) {
  215. state.mqttClient.end(false, () => {
  216. console.log(`state.mqttClient.connected = ${state.mqttClient.connected}`);
  217. })
  218. }
  219. if (isRelease) {
  220. //清除数据
  221. commit('release')
  222. }
  223. },
  224. //发布消息
  225. publishMsg({ state, dispatch, getters }, msg) {
  226. let uuid = msg.uuid
  227. let type = msg.mqttType;
  228. let other = msg.other;
  229. if (!getters.connected) {
  230. return new Promise((resolve, reject) => {
  231. reject('连接已断开')
  232. });
  233. } else {
  234. let index = indexOfUuid(state.deviceList, uuid)
  235. if (index >= 0) {
  236. let device = state.deviceList[index];
  237. if (device.online) {
  238. let topic = `/${uuid}/user/sub_control`;
  239. let json = {
  240. 'DstDeviceName': uuid,
  241. 'SrcDeviceName': options.clientId,
  242. 'type': type,
  243. }
  244. if (other) {
  245. json.other = other
  246. }
  247. let payload = JSON.stringify(json)
  248. console.log(`publishWithType topic = ${topic} payload = ${payload}`);
  249. return dispatch('publish', { topic, payload })
  250. } else {
  251. return new Promise((resolve, reject) => {
  252. reject('设备已经离线')
  253. });
  254. }
  255. } else {
  256. return new Promise((resolve, reject) => {
  257. reject('没有此设备')
  258. });
  259. }
  260. }
  261. },
  262. //发布消息
  263. publishWithType({ state, dispatch, getters }, payload) {
  264. //console.log(payload);
  265. //console.log(options);
  266. let type = payload.mqttType;
  267. let other = payload.other;
  268. if (!getters.connected) {
  269. return new Promise((resolve, reject) => {
  270. reject('连接已断开')
  271. });
  272. } else if (!(state.currentDevice && state.currentDevice.online)) {
  273. return new Promise((resolve, reject) => {
  274. reject('设备已经离线')
  275. });
  276. } else {
  277. let topic = `/${state.currentDevice.uuid}/user/sub_control`;
  278. //console.log(payload);
  279. //console.log(payload.mqttType);
  280. let json = {
  281. 'DstDeviceName': state.currentDevice.uuid,
  282. 'SrcDeviceName': options.clientId,
  283. 'type': type,
  284. }
  285. if (other) {
  286. json.other = other
  287. }
  288. let payload = JSON.stringify(json)
  289. console.log(`publishWithType topic = ${topic} payload = ${payload}`);
  290. return dispatch('publish', { topic, payload })
  291. }
  292. },
  293. //发布消息
  294. publish({ state, commit, getters }, message) {
  295. console.log('publish');
  296. console.log(message);
  297. return new Promise((resolve, reject) => {
  298. if (getters.connected) {
  299. //发布消息
  300. state.mqttClient.publish(message.topic, message.payload, (err) => {
  301. if (err) {
  302. console.warn(err);
  303. reject(err)
  304. } else {
  305. resolve()
  306. }
  307. })
  308. } else {
  309. reject("mqttClient is not connected")
  310. }
  311. })
  312. },
  313. //订阅消息
  314. subscribe({ state, commit, getters }, topic) {
  315. console.log(`subscribe topic = ${topic}`);
  316. return new Promise((resolve, reject) => {
  317. if (getters.connected) {
  318. //发布消息
  319. state.mqttClient.subscribe(topic, (err) => {
  320. if (err) {
  321. console.log(err);
  322. reject(err)
  323. } else {
  324. resolve()
  325. }
  326. })
  327. } else {
  328. reject("mqttClient is not connected")
  329. }
  330. })
  331. },
  332. //解除订阅消息
  333. unsubscribe({ state, commit, getters }, topic) {
  334. console.log(`unsubscribe topic = ${topic}`);
  335. return new Promise((resolve, reject) => {
  336. if (getters.connected) {
  337. //发布消息
  338. state.mqttClient.unsubscribe(topic, (err) => {
  339. if (err) {
  340. console.log(err);
  341. reject(err)
  342. } else {
  343. resolve()
  344. }
  345. })
  346. } else {
  347. reject("mqttClient is not connected")
  348. }
  349. })
  350. }
  351. }
  352. }