moduleMqtt.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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. },
  59. mutations: {
  60. //添加设备
  61. addDevice(state, device) {
  62. state.deviceList.push(device)
  63. },
  64. //设置当前选择的设备
  65. setCurrentDevice(state, device) {
  66. //state.currentDevice = device
  67. Vue.set(state, 'currentDevice', device)
  68. },
  69. //移除设备
  70. removeDevice(state, device) {
  71. let index = state.deviceList.indexOf(device)
  72. state.deviceList.slice(index, 1)
  73. },
  74. //连接mqtt服务器 clientId为wx_加上用户的uid
  75. connect(state, clientId) {
  76. console.log(`connect clientId = ${clientId}`);
  77. options.clientId = clientId
  78. state.mqttClient = mqtt.connect(url, options)
  79. },
  80. //token失效,退出登录,需要清除数据
  81. release(state) {
  82. state.deviceList = []
  83. state.currentDevice = null
  84. state.mqttClient = null
  85. },
  86. //更新设备信息
  87. updateDevice(state, data) {
  88. Vue.set(state.deviceList, data.index, data.device)
  89. },
  90. //更新播放信息
  91. updatePlayInfo(state, playinfo) {
  92. state.playInfo = playinfo
  93. }
  94. },
  95. actions: {
  96. //添加设备
  97. addDevice({ state, dispatch, commit, getters }, data) {
  98. let clientId = (data.clientId) ? data.clientId : options.clientId
  99. let device = data.device
  100. console.log(`deviceList = ${state.deviceList} device = ${device}`);
  101. //判断设备是否存在deviceList中
  102. let findDevice = state.deviceList.find((item) => {
  103. return item.uuid === device.uuid
  104. })
  105. if (findDevice == null) {
  106. if (state.deviceList.length === 0) {
  107. //设置当前的设备为添加的设备
  108. commit('setCurrentDevice', device)
  109. }
  110. //添加设备
  111. state.deviceList.push(device)
  112. //如果已经连接
  113. if (getters.connected) {
  114. //订阅设备是否在线
  115. subscribeDevicesStatus(dispatch, [device])
  116. //if (state.currentDevice && state.currentDevice.uuid === device.uuid) {
  117. //订阅当前设备的消息
  118. //subscribeCurrDevice(dispatch, state.currentDevice)
  119. //}
  120. } else {//如果没有连接
  121. //连接服务器
  122. dispatch('connect', clientId)
  123. }
  124. }
  125. },
  126. //删除设备
  127. removeDevice({ state, dispatch, commit, getters }, device) {
  128. //判断设备是否存在deviceList中
  129. let findDevice = state.deviceList.find((item) => {
  130. return item.uuid === device.uuid
  131. })
  132. if (findDevice) {
  133. //取消此设备的订阅
  134. let topic = `/${device.uuid}/status/onoffline`
  135. dispatch('unsubscribe', topic)
  136. topic = `/${device.uuid}/status/pub_response`
  137. dispatch('unsubscribe', topic)
  138. //在设备列表中删除此设备
  139. commit('removeDevice', findDevice)
  140. //如果删除的是选中的设备
  141. if (currentDevice && state.currentDevice.uuid == device.uuid) {
  142. //清除当前选中的设备 todo 还是自动选中在线的设备
  143. commit('setCurrentDevice', null)
  144. }
  145. if (state.deviceList.length === 0) {//所有的设备都已经删除,关闭连接
  146. dispatch('disconnect')
  147. }
  148. }
  149. },
  150. //连接设备
  151. connect({ state, dispatch, commit, getters }, clientId) {
  152. if (state.mqttClient == null) {
  153. //连接服务器
  154. commit('connect', clientId)
  155. //连接成功回调
  156. state.mqttClient.on("connect", function () {
  157. console.log("connect success!");
  158. //订阅设备是否在线
  159. subscribeDevicesStatus(dispatch, state.deviceList)
  160. //订阅当前设备的消息
  161. //subscribeCurrDevice(dispatch, state.currentDevice)
  162. });
  163. //异常回调
  164. state.mqttClient.on("error", function (err) {
  165. console.log(err);
  166. });
  167. state.mqttClient.on('offline', function () {
  168. console.log(`offline callback`);
  169. })
  170. state.mqttClient.on('end', function () {
  171. console.log(`end callback`);
  172. })
  173. //网络断开的回调
  174. state.mqttClient.on('close', function () {
  175. console.log(`close callback`);
  176. })
  177. //收到消息的回调
  178. state.mqttClient.on('message', function (topic, message) {
  179. console.log(`message = ${message.toString()}`);
  180. //解析收到的消息
  181. messageParse({ state, dispatch, commit, getters }, topic, message)
  182. //这是测试的
  183. state.msgList.push({
  184. topic: topic.toString(),
  185. msg: message.toString(),
  186. });
  187. })
  188. } else {
  189. if (!state.mqttClient.connected) {
  190. console.log("reconnect");
  191. state.mqttClient.reconnect()
  192. //重连成功的回调
  193. state.mqttClient.on("reconnect", function () {
  194. console.log("reconnect success!");
  195. });
  196. }
  197. }
  198. },
  199. //断开mqtt的连接
  200. disconnect({ state, commit }, isRelease) {
  201. console.log('disconnect')
  202. if (state.mqttClient) {
  203. state.mqttClient.end(false, () => {
  204. console.log(`state.mqttClient.connected = ${state.mqttClient.connected}`);
  205. })
  206. }
  207. if (isRelease) {
  208. //清除数据
  209. commit('release')
  210. }
  211. },
  212. //发布消息
  213. publishMsg({ state, dispatch, getters }, msg) {
  214. let uuid = msg.uuid
  215. let type = msg.mqttType;
  216. let other = msg.other;
  217. if (!getters.connected) {
  218. return new Promise((resolve, reject) => {
  219. reject('连接已断开')
  220. });
  221. } else {
  222. let index = indexOfUuid(state.deviceList,uuid)
  223. if (index >= 0) {
  224. let device = state.deviceList[index];
  225. if(device.online){
  226. let topic = `/${uuid}/user/sub_control`;
  227. let json = {
  228. 'DstDeviceName': uuid,
  229. 'SrcDeviceName': options.clientId,
  230. 'type': type,
  231. }
  232. if (other) {
  233. json.other = other
  234. }
  235. let payload = JSON.stringify(json)
  236. console.log(`publishWithType topic = ${topic} payload = ${payload}`);
  237. return dispatch('publish', { topic, payload })
  238. }else{
  239. return new Promise((resolve, reject) => {
  240. reject('设备已经离线')
  241. });
  242. }
  243. }else{
  244. return new Promise((resolve, reject) => {
  245. reject('没有此设备')
  246. });
  247. }
  248. }
  249. },
  250. //发布消息
  251. publishWithType({ state, dispatch, getters }, payload) {
  252. //console.log(payload);
  253. //console.log(options);
  254. let type = payload.mqttType;
  255. let other = payload.other;
  256. if (!getters.connected) {
  257. return new Promise((resolve, reject) => {
  258. reject('连接已断开')
  259. });
  260. } else if (!(state.currentDevice && state.currentDevice.online)) {
  261. return new Promise((resolve, reject) => {
  262. reject('设备已经离线')
  263. });
  264. } else {
  265. let topic = `/${state.currentDevice.uuid}/user/sub_control`;
  266. //console.log(payload);
  267. //console.log(payload.mqttType);
  268. let json = {
  269. 'DstDeviceName': state.currentDevice.uuid,
  270. 'SrcDeviceName': options.clientId,
  271. 'type': type,
  272. }
  273. if (other) {
  274. json.other = other
  275. }
  276. let payload = JSON.stringify(json)
  277. console.log(`publishWithType topic = ${topic} payload = ${payload}`);
  278. return dispatch('publish', { topic, payload })
  279. }
  280. },
  281. //发布消息
  282. publish({ state, commit, getters }, message) {
  283. console.log('publish');
  284. console.log(message);
  285. return new Promise((resolve, reject) => {
  286. if (getters.connected) {
  287. //发布消息
  288. state.mqttClient.publish(message.topic, message.payload, (err) => {
  289. if (err) {
  290. console.warn(err);
  291. reject(err)
  292. } else {
  293. resolve()
  294. }
  295. })
  296. } else {
  297. reject("mqttClient is not connected")
  298. }
  299. })
  300. },
  301. //订阅消息
  302. subscribe({ state, commit, getters }, topic) {
  303. console.log(`subscribe topic = ${topic}`);
  304. return new Promise((resolve, reject) => {
  305. if (getters.connected) {
  306. //发布消息
  307. state.mqttClient.subscribe(topic, (err) => {
  308. if (err) {
  309. console.log(err);
  310. reject(err)
  311. } else {
  312. resolve()
  313. }
  314. })
  315. } else {
  316. reject("mqttClient is not connected")
  317. }
  318. })
  319. },
  320. //解除订阅消息
  321. unsubscribe({ state, commit, getters }, topic) {
  322. console.log(`unsubscribe topic = ${topic}`);
  323. return new Promise((resolve, reject) => {
  324. if (getters.connected) {
  325. //发布消息
  326. state.mqttClient.unsubscribe(topic, (err) => {
  327. if (err) {
  328. console.log(err);
  329. reject(err)
  330. } else {
  331. resolve()
  332. }
  333. })
  334. } else {
  335. reject("mqttClient is not connected")
  336. }
  337. })
  338. }
  339. }
  340. }