moduleMqtt.js 9.4 KB

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