Vue 项目中使用WebSocket 消息推送

一、功能需求

1.这是我在后台管理项目中使用到的,主要的作用是搞一个消息提醒的功能。
2.主要有右上角的提示和有下角的消息弹框。
3.主要实现的功能是如果用户有未读的消息,那么首次登录就弹框,如果用户关闭了页面,那么再次刷新页面的时候,也不再弹框,意思就是一个账户没有退出之前,也没有实时消息推送的时候,只弹一次框。
4.如果用户点击了未读消息,那么就会将此条消息置位历史(已读)。
页面展示:
在这里插入图片描述

二、页面代码

备注:我的是后台管理系统(用的是vue-element-admin),第一次写websocket,所以我写在了src->layout->AppMain.vue文件下面:

<template><section class="app-main"><Message-remind :message-list="messageList" /><transition name="fade-transform" mode="out-in"><keep-alive :include="cachedViews"><router-view :key="key" /></keep-alive></transition></section>
</template><script>import MessageRemind from '@/components/MessageRemind/index.vue'import { getToken, getSid } from "@/utils/auth"; // get token from cookieexport default {name: 'AppMain',components: {MessageRemind},watch: {'$store.state.user': {handler: function (newValue, oldValue) {// 如果没有token,则表明退出了登录if (!newValue.token) {this.closeWebSocket();}},immediate: true,deep: true}},data() {return {// socket参数socket: null,timeout: 60 * 1000, // 45秒一次心跳timeoutObj: null, // 心跳心跳倒计时serverTimeoutObj: null, // 心跳倒计时timeoutnum: null, // 断开 重连倒计时lockReconnect: false, // 防止websocket: null,messageList: {}};},created() {const hasToken = getToken();const sid = getSid();if (hasToken) {this.initWebSocket(hasToken, sid)}},computed: {cachedViews() {return this.$store.state.tagsView.cachedViews},key() {return this.$route.path}},mounted() {// console.log(this.$store.state.tagsView.cachedViews)},methods: {initWebSocket(token, sid) {// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于httpsthis.websocket = new WebSocket(process.env.VUE_APP_WEB_SOCKET_BASE_API + '?uiticket=' + token + '&sid=' + sid);this.websocket.onopen = this.websocketonopen;this.websocket.onerror = this.websocketonerror;this.websocket.onmessage = this.setOnmessageMessage;this.websocket.onclose = this.websocketclose;// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。// window.onbeforeunload = that.onbeforeunload},start() {//清除延时器this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(() => {if (this.websocket && this.websocket.readyState == 1) {this.websocket.send('{"messageType": 99}');//发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数} else {this.reconnect();}//定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接this.serverTimeoutObj = setTimeout(() => {this.websocket.close();}, this.timeout)}, this.timeout)},reset() { // 重置心跳// 清除时间clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);// 重启心跳this.start();},// 重新连接reconnect() {if (this.lockReconnect) returnthis.lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多this.timeoutnum && clearTimeout(this.timeoutnum);this.timeoutnum = setTimeout(() => {this.initWebSocket();this.lockReconnect = false;}, 5000)},async setOnmessageMessage(event) {this.messageList = JSON.parse(event.data)if (this.messageList.data.messageType === 999) {this.websocket.send('{"messageType": 99}');}this.$store.dispatch('user/steMessageMenu', this.messageList)this.reset();// 自定义全局监听事件window.dispatchEvent(new CustomEvent('onmessageWS', {detail: {data: event.data}}))//发现消息进入    开始处理前端触发逻辑// if (event.data === 'success' || event.data === 'heartBath') return},websocketonopen(e) {// console.log('onopen', {e});//开启心跳this.start();console.log("WebSocket连接成功!!!" + new Date() + "----" + this.websocket.readyState);},websocketonerror(e) {// console.log('websocketonerror', {e});console.log("WebSocket连接发生错误" + e);},websocketclose(e) {this.websocket.close();clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);console.log("WebSocket连接关闭");},websocketsend(messsage) {this.websocket.send(messsage)},closeWebSocket() { // 关闭websocketthis.websocket.close()},},}
</script><style lang="scss" scoped>@import "~@/styles/global-height.scss";.app-main {/* 50= navbar  50  */// min-height: calc(100vh - #{$navbar+'px'});width: 100%;position: relative;overflow: hidden;display: flex;flex-direction: column;flex: 1;}.fixed-header+.app-main {padding-top: #{$navbar+'px'};}.hasTagsView {.app-main {// min-height: calc(100vh - #{$appMain+'px'});}.fixed-header+.app-main {padding-top: 90px;}}.copy {text-align: center;height: 30px;line-height: 30px;font-size: 13px;color: #666;background: #fff;width: 100%;box-shadow: 0 0 10px #dfe4ed;}
</style><style lang="scss">// fix css style bug in open el-dialog.el-popup-parent--hidden {.fixed-header {padding-right: 15px;}}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3321.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

valgrind检测内存泄漏、越界访问、野指针访问实验

前言 本次测试包括&#xff0c;检测无误的代码&#xff0c;检测内存泄漏&#xff0c;检测访问越界&#xff0c;检测野指针&#xff0c;检测访问已经释放(已经被free)的内存。 一 安装valgrind sudo apt install valgrind 二 无错误 #include <stdio.h> #include <…

GitHub+PicGo制作个人图床

目录 一、前言 二、新建Github仓库 ​编辑 三、生成token 四、配置PicGo 五、上传图片 六、新版的PicGo出了很多新功能大家可以探索一下。​编辑 一、前言 PicGo是一个用于快速上传图片并获取图片 URL 链接的工具:Releases Molunerfinn/PicGo GitHub GitHub是一个在…

pytorch动态调整学习率torch.optim.lr_scheduler import MultiStepLR

from torch.optim.lr_scheduler import MultiStepLR 简单来说&#xff0c;就是分阶段调整学习率&#xff0e; 用法&#xff1a; model ANet(classes5) #加载模型 optimizer optim.SGD(params model.parameters(), lr0.05) #优化方法使用SGD#在指定的epoch值&#x…

“因构建 而可见”,亚马逊云科技中国峰会助力企业数字化转型升级

过去十年&#xff0c;数字化转型的浪潮携带着机遇和挑战席卷而来&#xff0c;几乎每个企业都在做数字化转型&#xff0c;开始向大数据、人工智能等新技术寻求生产力的突破。但随着数字化转型深入&#xff0c;很多企业开始感受到数字化投入的成本压力&#xff0c;加之新技术正带…

使用npm install -g @vue/cli 命令安装最新的脚手架与Vue版本不匹配的问题

使用npm install -g vue/cli 命令安装最新的脚手架 创建项目时不要选择Vue版本&#xff0c;让它默认选择&#xff08;默认选择 Vue2&#xff09;否则会出现 vue版本和脚手架版本vue-cli 不兼容的问题&#xff08;怪哉&#xff09; 脚手架兼容vue2 不兼容vue3 &#xff1f; 不理…

DAY34——贪心part3

1. class Solution {public int largestSumAfterKNegations(int[] nums, int K) {// 将数组按照绝对值大小从大到小排序&#xff0c;注意要按照绝对值的大小nums IntStream.of(nums).boxed().sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1)).mapToInt(Integer::intValue)…

机器学习——概率与统计

参考资料&#xff1a; 《机器学习》周志华https://zhuanlan.zhihu.com/p/27056207 1 马尔可夫链 1.1 定义 直观含义&#xff1a;在已知现在的条件下&#xff0c;过去与未来相互独立。 1.2 马尔可夫模型 根据定义&#xff0c;A 必为方阵 其中&#xff0c; p i j ( n ) P {…

MaskFormer:将语义分割和实例分割作为同一任务进行训练

目标检测和实例分割是计算机视觉的基本任务&#xff0c;在从自动驾驶到医学成像的无数应用中发挥着关键作用。目标检测的传统方法中通常利用边界框技术进行对象定位&#xff0c;然后利用逐像素分类为这些本地化实例分配类。但是当处理同一类的重叠对象时&#xff0c;或者在每个…

信号链噪声分析11

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 如今的射频(RF)系统变得越来越复杂。高度的复杂性要求所有系统指标&#xff08;例如严格的 链接和噪声预算&#xff09;达到最佳性能。确保整个信号链的正确设计至关重要。而信…

sql内外连接图示

student表数据&#xff1a; idname34name22golitter66kerwin123yh12golemon score表数据&#xff1a; idscore34802298663345100 内连接 1、内连接:俗称左右拼接连接&#xff1b; 2、内连接特点&#xff1a;满足连接条件的才会出现在结果里面&#xff1b; SELECT 查询字段…

Spring 事务和事务传播机制

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录 Spring 中事务的实现Spring 编程式事务Spring 声明式事务Transactional 作⽤范围Transactional 参数说明Spring 事务隔离级别…

x264 deblock filter 代码解读

在x264源码里&#xff0c;void x264_frame_deblock_row( x264_t *h, int mb_y )函数中定义了如下的宏片段&#xff0c;这段代码旨在完成对MB的deblocking 操作&#xff0c;其中针对edge 取不同的值的时候&#xff0c;有的做deblocking&#xff0c; 有的不做&#xff0c;看这部分…