1、封装socketjs
import store from '@/store'class socketIO { constructor() { this.socketTask = null this.is_open_socket = false //避免重复连接 this.is_show_Loading = false // 为空就为1 admin this.url = store.state.baseUrl.socketUrl + (store.state.user.userinfo.personId || '1') //连接地址 this.connectNum = 1 // 重连次数 this.followFlake = true // traderDetailIndex == true 重连 //心跳检测 this.timeout = 15000 //多少秒执行检测 this.heartbeatInterval = null // this.reconnectTimeOut = null // } // 进入这个页面的时候创建websocket连接【整个页面随时使用】 connectSocketInit() { this.socketTask = uni.connectSocket({ url: this.url, success: () => { // 返回实例 return this.socketTask }, fail:(err)=>{ console.log(err) } }); this.socketTask.onOpen((res) => { console.log('连接成功'); if(this.connectNum>1){ if(store.state.baseUrl.socketUrl.indexOf('10.43')>-1){ store.commit('SET_SOCKET_URL','outIp') }else{ store.commit('SET_SOCKET_URL','inIp') } this.url = store.state.baseUrl.socketUrl + (store.state.user.userinfo.personId || '1') //连接地址(必须要,否则请求的地址还是没变) } this.connectNum = 1 clearInterval(this.reconnectTimeOut) clearInterval(this.heartbeatInterval) this.is_open_socket = true; // this.is_show_Loading = true; uni.hideLoading() this.start(); // 注:只有连接正常打开中 ,才能正常收到消息 this.socketTask?.onMessage((res) => { // 字符串转json const {data} = res const index = data.indexOf('alarm') || data.indexOf('confirm') // 两种类型:alarm 和 confirm if(index > -1 ){ const arr = JSON.parse(data.slice(data.indexOf('['))) uni.$emit('socket', arr[1]) } }); }) // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接 uni.onSocketError((res) => { console.log('连接打开失败url',store.state.baseUrl.socketUrl); if(store.state.baseUrl.socketUrl.indexOf('10.43')>-1){ store.commit('SET_SOCKET_URL','outIp') }else{ store.commit('SET_SOCKET_URL','inIp') } this.url = store.state.baseUrl.socketUrl + (store.state.user.userinfo.personId || '1') //连接地址(必须要,否则请求的地址还是没变) this.socketTask = null this.is_open_socket = false; // this.is_show_Loading = false; clearInterval(this.heartbeatInterval) clearInterval(this.reconnectTimeOut) // uni.$off('getPositonsOrder') // if (this.connectNum < 6000) { this.reconnect(); this.connectNum += 1 // } else { // uni.$emit('connectError'); // this.connectNum = 1 // } }); // 这里仅是事件监听【如果socket关闭了会执行】 this.socketTask.onClose(() => { console.log("已经被关闭了-------") clearInterval(this.heartbeatInterval) clearInterval(this.reconnectTimeOut) this.is_open_socket = false; // this.is_show_Loading = false; this.socketTask = null // uni.$off('getPositonsOrder') if (this.connectNum < 6) { // this.reconnect(); } else { uni.$emit('connectError'); this.connectNum = 1 } }) } // 主动关闭socket连接 Close() { if (!this.is_open_socket) { return } this.socketTask.close({ }); } //发送消息 send(data) { // console.log("data---------->", data); // 注:只有连接正常打开中 ,才能正常成功发送消息 if (this.socketTask) { this.socketTask.send({ data: '', async success() { // console.log("消息发送成功"); }, }); } } //开启心跳检测 start() { this.heartbeatInterval = setInterval(() => { this.send(''); }, this.timeout) } //重新连接 reconnect() { //停止发送心跳 clearInterval(this.heartbeatInterval) //如果不是人为关闭的话,进行重连 if (!this.is_open_socket && this.followFlake) { this.reconnectTimeOut = setInterval(() => { this.connectSocketInit(this.data); }, 3000) } } } module.exports = socketIO
2、页面使用
<template> <view> <view class="notification" v-show="show"> <view class="flex align-center justify-between title"> <view class="flex align-center"> <image src="./images/alarm.svg" class="icon"></image> <text class="margin-left-sm text-lg text-bold">{{title}}</text> </view> <uni-icons type="closeempty" size="20" @click="show = false"></uni-icons> </view> <view class="padding-top-sm"> <div>{{alarmContent}}</div> <img @click="previewImage(content)" :src="content" mode="widthFix" alt="" style="width: 100%;" /> </view> </view> <!-- 确认报警弹框 --> <u-modal title="告警确认处理" :show="confirmShow" :showCancelButton='false' :showConfirmButton='false' > <view class="my_confirm" v-if="confirmDataInfo"> <view class="confirm_info"> <view>规则类型:<span>{{confirmDataInfo.ruleTypeName || ''}}</span></view> <view>确认内容:<span>{{confirmDataInfo.confirmContent}}</span></view> <view>规则名:<span>【{{confirmDataInfo.ruleName}}】{{confirmDataInfo.alarmValue}}</span></view> <view>推送类型:<span>{{confirmDataInfo.pushTypeName}}</span></view> </view> <view class="operate_btns"> <u-button text="误报" size="small" type="warning" @click="dealWithConfirm(0)" ></u-button> <u-button text="正确报警" size="small" type="success" @click="dealWithConfirm(1)" ></u-button> <u-button text="正确报警并执行控制指令" type="primary" size="small" @click="dealWithConfirm(2)" ></u-button> </view> </view> </u-modal> </view> </template> <script> import { generalOptions1 } from '@/utils/options.js' import {handleConfirm} from '@/api/alarm/alarm.js' function base64ToFile (base64Str, fileName, callback) { // 去除base64前缀 var index=base64Str.indexOf(',') var base64Str=base64Str.slice(index+1,base64Str.length) plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){ fs.root.getFile(fileName,{create:true},function(entry){ var fullPath = entry.fullPath; let platform = uni.getSystemInfoSync().platform if(platform == 'android'){ var Base64 = plus.android.importClass("android.util.Base64"); var FileOutputStream = plus.android.importClass("java.io.FileOutputStream"); try{ var out = new FileOutputStream(fullPath); // 此处Base64.decode有长度限制,如果不能满足需求,可以考虑换成官方原生插件市场的【Base64转文件】 var bytes = Base64.decode(base64Str, Base64.DEFAULT); out.write(bytes); out.close(); // 回调 callback && callback(entry.toLocalURL()); }catch(e){ console.log(e.message); } }else if(platform == 'ios'){ var NSData = plus.ios.importClass('NSData'); var nsData = new NSData(); nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0); if (nsData) { nsData.plusCallMethod({writeToFile: fullPath,atomically:true}); plus.ios.deleteObject(nsData); } // 回调 callback && callback(entry.toLocalURL()); } }) }) } export default { data () { return { show: false, title:'', alarmContent:'', content:'', baseUrl:'', confirmShow:false, confirmDataInfo:{}, ruleType: generalOptions1(['维修规则', '生产规则', '故障规则']),//规则类型 pushType: generalOptions1(['视频', '告警内容', '视角算法动图', '视角算法文字']), } }, mounted(){ uni.$on('socket', this.getalarm) // 监听socket alarm uni.$on('socket', this.getconfirm) // 监听socket confirm }, methods:{ getalarm({receive,record,voiceBase64}) { this.title = record?.ruleName || ''; this.alarmContent = record?.pushContent || ''; this.content = record?.algorithmImg[0] || ''; // 告警图片 if(record){ this.show = true base64ToFile(voiceBase64,(new Date()).valueOf() + '.mp3',(res)=>{ let music = uni.createInnerAudioContext(); music.src = res; music.volume = 1; // 音量 if(this.content){ // 动图出来了再播放声音 music.play(); //执行播放 } music.onEnded(() => { //播放结束 music.pause() music.destroy() }) }) } }, getconfirm({confirm}){ if(confirm.createTime){ let pushType = []; this.pushType?.map(item=>{ if(confirm.pushType.indexOf(item.value)>-1){ pushType.push(item.label) } }) this.$set(confirm,'pushTypeName',pushType?.join(',')); this.$set(confirm,'ruleTypeName',this.ruleType?.filter(item=> item.value == confirm.ruleType)[0]['label']); this.confirmDataInfo = this.deepClone(confirm); this.confirmShow = true; } }, // 告警确认处理 dealWithConfirm(_type){ let params = { alarmRecordNo: this.confirmDataInfo.alarmRecordNo, confirmStatus: _type } handleConfirm(params).then(res=>{ this.$modal.msg(res.message); this.confirmShow = false; this.confirmDataInfo = {}; }) } } } </script> <style scoped lang="scss"> .notification{ background: #ffffff; border-radius: 6rpx; position: fixed; z-index: 1000; width: 90vw; left: 5vw; top:5rpx; box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 3px 1px; padding: 20rpx; .icon{ width: 64rpx; height: 64rpx; } .title{ padding-bottom: 20rpx; border-bottom: 1px #ebeef5 solid; } } .confirm_info{ width: 100%; margin-bottom: 50rpx; font-size: 28rpx; color: #666; &>view{ margin-bottom: 26rpx; & span{ color: #000; font-size: 30rpx; margin-left: 20rpx; } } } .operate_btns{ display: grid; grid-template-columns: auto auto 290rpx; grid-template-rows: auto; grid-gap: 20rpx; } </style>
标签:uniapp,封装,socket,confirm,socketTask,uni,data,store From: https://www.cnblogs.com/LindaBlog/p/18318248