IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue使用WebSocket实现实时报警弹窗 -> 正文阅读

[JavaScript知识库]vue使用WebSocket实现实时报警弹窗

使用WebSocket实现实时报警,实现当接收到报警时弹出弹窗显示报警内容和发错报警声音。

<template>
    <section class="app-main">
        <!-- 报警时的声音 controls -->
        <audio
            loop="true"
            ebkit-playsinline="true"
            playsinline="true"
            ref="myAudio"
            src="../../assets/alarm.mp3"
        ></audio>
    </section>
</template>

<script>
import { mapGetters } from 'vuex'
import { parseTime } from '@/utils/index'
import { getToken } from '@/utils/auth'
export default {
    name: 'AppMain',
    components: {
    },
    watch: {
        alarmTime(after) {
            // console.log('alarmTime', after)
            clearInterval(this.timer)
            if (after > 0) {
                this.setAudio()
            } else {
                this.myAudio.pause() // 暂停
                clearInterval(this.timer)
                this.$store.commit('user/SET_ALARMTIME', 0)
            }
        }
    },
    computed: {
        ...mapGetters(['pcAlarmVoice', 'catchComponents']),
        key() {
            return this.$route.path
        }
    },
    data() {
        return {
            websock: null,
            infoText: '',
            showInfo: false,
            lockReconnect: false,
            alarmBox: [],
            alarmBG: ['', 'bgCC6966', 'bg969696', 'bgCC6966 ', 'bg969696', 'bgCC6966', 'bgCC6966', 'bgCC6966'],
            alarmTime: 0,
            timer: null, // 声音报警定时器
            myAudio: null, // 报警声音控件
            alarmType: ['', '超限报警', '超限预警', '断电报警 ', '离线报警', '设备异常', '上线通知', '来电通知'],
            time1: null // 连接的延时器
        }
    },
    created() {},
    mounted() {
        // http://192.168.31.240:8081/user/test?d=test02m202100001&i=1
        // console.log('进入页面')
        this.initWebSocket()
        this.myAudio = this.$refs.myAudio
    },
    methods: {
        setAudio() {
            if (this.myAudio.paused) {
                this.myAudio.play() // 播放
            }
            this.timer = setInterval(() => {
                this.alarmTime--
            }, 1000)
        },
        initWebSocket: function () {
            // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
            // 用户token
            let bindContent = getToken()
            if (bindContent === 'undefined' || !bindContent) {
                bindContent = ''
            }
            let url = ''
            if (process.env.NODE_ENV === 'production') {
                // 生产环境
                // url = 'wss://192.168.31.46:30008/?bindType=2&bindContent=' + bindContent // 正试服
                url = 'ws://192.168.31.46:30008/?bindType=2&bindContent=' + bindContent // 正试服
            } else if (process.env.NODE_ENV === 'staging') {
                url = 'ws://ws.lenglh.cn:30008/?bindType=2&bindContent=' + bindContent // 测试服
            } else {
                // development 开发环境
                // url = 'ws://192.168.31.240:30008/?bindType=2&bindContent=' + bindContent
                url = 'ws://192.168.31.46:30008/?bindType=2&bindContent=' + bindContent
                return false
            }
            // console.log('初始化websocket', url)
            // this.websock = new WebSocket('ws://192.168.31.240:30008/?bindType=2&bindContent=' + bindContent)
            this.websock = new WebSocket(url)
            this.websock.onopen = this.websocketOnopen
            this.websock.onerror = this.websocketOnerror
            this.websock.onmessage = this.websocketOnmessage
            this.websock.onclose = this.websocketOnclose
        },
        websocketOnopen: function () {
            console.log('页面WebSocket连接成功')
            //心跳检测重置
            // this.heartCheck.reset().start()
        },
        // 连接失败后的回调函数
        websocketOnerror: function (e) {
            console.log('WebSocket连接发生错误', e)
            this.reconnect()
        },
        // 当从服务器接受到信息时的回调函数
        websocketOnmessage: function (e) {
            // console.log('监听关闭' + e)
            console.log('-----接收消息-------')

            // 收到消息,添加报警声音(先判断声音报警是否开启)
            if (this.pcAlarmVoice) {
                this.alarmTime = 5
                // console.log('先判断声音报警是否开启');
                this.$store.commit('user/SET_ALARMTIME', this.alarmTime)
            }

            const h = this.$createElement // 创建文本节点

            let alarmData = JSON.parse(e.data).bindContent
            alarmData.alarmTime = parseTime(alarmData.alarmTime)
            if (this.$route.path === '/screen') {
                alarmData.alarmBG = this.alarmBG[alarmData.alarmType]
                alarmData.alarmBTN=this.alarmBG[alarmData.alarmType]+'btn'
            } else {
                alarmData.alarmBG = ''
                alarmData.alarmBTN = ''
            }
            alarmData.alarmType = this.alarmType[alarmData.alarmType]
            alarmData.groupName = alarmData.groupName ? alarmData.groupName : '未分配'
            let title = alarmData.deviceName + '(' + alarmData.deviceSerial + ')'

            // 当前弹窗要插入数组的下标
            let index = this.alarmBox.length

            if (index === 3) {
                this.alarmBox[0].close()
                this.alarmBox.pop()
            }

            let messageHTML = null
            // 判断是否有传感器
            if (alarmData.channelName) {
                messageHTML = h(
                    'div',
                    {
                        class: 'alarm-box'
                    },
                    [
                        h('p', this.$t('device.d409') + ':' + alarmData.alarmType),
                        h('p', this.$t('device.d746') + ':' + alarmData.channelName),
                        h('p', this.$t('monitor.m15') + ':' + alarmData.groupName),
                        h('p', this.$t('device.d497') + ':' + alarmData.alarmTime),
                        h('p', this.$t('user.u258') + ':' + alarmData.alarmContent.cn),
                        h(
                            'div',
                            {
                                class: 'btn-box'
                            },
                            [
                                h(
                                    'button',
                                    {
                                        class: 'btn el-button--primary ' + alarmData.alarmBTN,
                                        on: {
                                            click: () => this.notifyClick(alarmData) // 按钮的点击事件
                                        }
                                    },
                                    '查看详情'
                                )
                            ]
                        )
                    ]
                )
            } else {
                messageHTML = h(
                    'div',
                    {
                        class: 'alarm-box'
                    },
                    [
                        h('p', this.$t('device.d409') + ':' + alarmData.alarmType),
                        h('p', this.$t('user.u489') + ':' + alarmData.objectName),
                        h('p', this.$t('device.d497') + ':' + alarmData.alarmTime),
                        h('p', this.$t('user.u258') + ':' + alarmData.alarmContent.cn),
                        h(
                            'div',
                            {
                                class: 'btn-box'
                            },
                            [
                                h(
                                    'button',
                                    {
                                        class: 'btn el-button--primary ' + alarmData.alarmBTN,
                                        on: {
                                            click: () => this.notifyClick(alarmData) // 按钮的点击事件
                                        }
                                    },
                                    this.$t('global.detailBtn') // '查看详情'
                                )
                            ]
                        )
                    ]
                )
            }
            this.open(title, messageHTML, index, alarmData.alarmBG)
        },
        open(title, messageHTML, index, bg) {
            console.log('当前页面', this.$route, bg)
            let customClass = 'alarm-notify'
            if (this.$route.path === '/screen') {
                customClass = 'alarm-notify screen-box ' + bg
            }
            this.alarmBox[index] = this.$notify({
                title: title,
                dangerouslyUseHTMLString: true,
                duration: 5000, // 自动关闭的时间
                // duration: 0, // 不自动关闭
                customClass: customClass,
                // position: 'bottom-right',
                message: messageHTML
            })
        },
        // 查看详情
        notifyClick(alarmData) {
            this.$store.dispatch('app/setReqId', alarmData.deviceId)
            this.$router.push({ name: 'monitoringDeviceDetail' })
        },
        websocketOnclose: function (e) {
            // console.log('connection closed (' + e.code + ')')
            this.reconnect()
        },
        websocketSend(text) {
            // 数据发送
            try {
                this.websock.send(text)
            } catch (err) {
                // console.log('send failed (' + err.code + ')')
            }
        },
        reconnect() {
            let context = this
            if (context.lockReconnect) return
            context.lockReconnect = true
            //没连接上会一直重连,设置延迟避免请求过多
            clearTimeout(this.time1)
            this.time1 = setTimeout(function () {
                // console.info('尝试重连...')
                context.initWebSocket()
                context.lockReconnect = false
            }, 5000)
        }
    },
    beforeDestroy() {
        // this.websock.close()
        // console.log('页面关闭websocket');
    }
}
</script>

<style scoped lang="scss">
.app-main {
    /*50 = navbar  */
    min-height: calc(100vh - 60px);
    width: 100%;
    position: relative;
}
.fixed-header + .app-main {
    padding-top: 50px;
}

.info {
    position: relative;
    width: 100%;
    padding: 10px;
}

::v-deep .el-notification__group {
    width: 100% !important;
}
</style>

<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
    .fixed-header {
        padding-right: 15px;
    }
}

.alarm-notify {
    width: 400px;
    .el-notification__group {
        width: 100%;

        .alarm-box {
            > p {
                line-height: 1.4;
                margin-top: 10px;
            }
        }
    }
}

.screen-box {
    // background-color: #103064;
    // border: 1px solid #2154b2;
    opacity: 95%;
    .el-notification__title {
        color: #fff !important;
    }
    p {
        color: #fff !important;
    }
}

.bgCC6966 {
    background-color: #cc6966;
    border: 1px solid #cc2e29;
}

.bgCC6966btn {
    background-color: #ffffff !important;
    color: #cc6966 !important;
}

.bg969696 {
    background-color: #969696;
    border: 1px solid #ffffff;
}

.bg969696btn {
    background-color: #ffffff !important;
    color: #323232 !important;
}

.btn {
    box-sizing: border-box;
    height: 35px;
    border-radius: 4px;
    border: none;
}

.btn-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    margin-top: 20px;
}
// -----------------------
.isOn {
    width: 28px;
    height: 28px;
    -webkit-animation: rotating 1.2s linear infinite;
    animation: rotating 1.2s linear infinite;
}
@keyframes rotating {
    from {
        -webkit-transform: rotate(0);
    }
    to {
        -webkit-transform: rotate(360deg);
    }
}
@-webkit-keyframes rotating {
    from {
        -webkit-transform: rotate(0);
    }
    to {
        -webkit-transform: rotate(360deg);
    }
}
.isOff {
    width: 28px;
    height: 28px;
}
</style>

注:

  • 使用this.$t('')是项目做了中英文翻译
  • 使用this.$createElement创建弹窗的html片段是因为要求使用返回的数据的值做显示,使用原始html片段不能实现,而使用模板字符串的html片段时不能执行方法,最终使用vue的this.$createElement实现项目需求。

最终弹窗效果:
在这里插入图片描述
点击详情即可跳转页面

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:06:01  更:2022-05-07 11:07:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:46:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码