vue实时数据流处理 3、处理ws接口推送的数据流太大,导致浏览器崩溃
上两遍写完之后,实现了实时数据流的效果,但是最大的问题出现了,就是数据流太快,浏览器在接收了一千多条的数据之后就崩溃了,那只能优化了,前期查了很多资料以及解决方法,比如:分页处理,将数据推送进数组 进行切割分页,再渲染出来,这样是处理了大数据,但是不是我想要实现的数据流效果,后面想了下,能不能用瀑布流的思路去解决呢? 然后就开始实现,结果真的就完美的解决了我的问题,这里我偷了个懒,用的是eleme
·
上两篇文章写完之后,实现了实时数据流的效果,但是最大的问题出现了,就是数据流太快,浏览器在接收了一千多条的数据之后就崩溃了,那只能优化了,前期查了很多资料以及解决方法,比如:分页处理,将数据推送进数组 进行切割分页,再渲染出来,这样是处理了大数据,但是不是我想要实现的数据流效果(如果想要用分页实现我的效果我的思路就是:设置两个盒子,布局是上下布局,一个盒子接收新数据,一个是旧数据,然后给盒子设置动画插入一条数据就向上 top移动相应的像素,个人觉得这样实现需要很强的逻辑处理能力,而且较麻烦),后面想了下,能不能用瀑布流的思路去解决呢? 然后就开始实现,结果真的就完美的解决了我的问题,这里我偷了个懒,用的是elementUi 的无限滚动去实现数据流的效果,
因为不知道怎么发动态效果,只能放张图片了,效果就是,这些预约消息会实时更新,向上移动。
<template>
<div class="content-left">
<div class="title">
<p class="title-text">原始数据流</p>
<i class="title-icon"></i>
</div>
<ul class="infinite-list content-left-data" v-infinite-scroll="load" style="overflow:auto">
<li v-for="(i, index) in count" :key="index" id="content-left-data-text" class="content-left-data-text infinite-list-item">{{ i }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
arr: [],//接收数据流的数组
count: 0,//实现无限滚动的数组
webSock: null,
rawHtml: '<p class="data-text">{{msgData}}</p>',
reconnectData: null,
lockReconnect: false, //避免重复连接,因为onerror之后会立即触发 onclose
timeout: 600000, //心跳时间参数 1小时一次心跳检测
timeoutObj: null, //心跳检测函数执行后的参数 1代表执行成功
serverTimeoutObj: null, //等待服务端响应函数执行后的参数 1代表执行成功
textarea: '', //输入框 文字
msgData: ''
};
},
created() {
if (typeof WebSocket === 'undefined') {
console.log('您的浏览器不支持WebSocket');
} else {
// console.log('您的浏览器支持WebSocket')
this.initWebSocket();
}
},
mounted() {
this.scrollToBottom();
},
updated() {
this.scrollToBottom(); //每次页面渲染完之后滚动条在最底部
},
methods: {
// WebSockets参数初始化
initWebSocket() {
console.log('WebSocket启动中......');
//WebSocket服务器地址
let wsurl = 'ws://192.168.0.228:10086/ws/';
this.webSock = new WebSocket(wsurl);
this.webSock.onopen = this.webSocketOpen; //连接成功
this.webSock.onmessage = this.webSocketAcceptMessage; //广播成功
this.webSock.onerror = this.webSocketError; //连接断开,失败
this.webSock.onclose = this.webSocketClose; //连接关闭
},
//初始化WebSocket
webSocketOpen() {
console.log('连接成功');
this.heartBeat();
}, //连接成功
webSocketError() {
console.log('连接失败');
this.reconnect();
}, //连接失败
webSocketClose() {
console.log('断开连接');
this.reconnect();
},
//接受webSocket消息
webSocketAcceptMessage(res) {
this.heartBeat(); //收到消息会刷新心跳检测,如果一直收到消息,就推迟心跳发送
this.msgData = eval("'" + res.data + "'"); //ws请求返回的数据流
this.arr.push(msgData);//将数据添加进数组
},
//发送数据到服务端
webSocketSend(data) {
this.webSock.send(JSON.stringify(data));
},
//重新连接 WebSocket服务
reconnect() {
if (this.lockReconnect) {
//连接失败和关闭之后都会触发,通过lockReconnect控制只连接了一个webSocket
return;
}
this.lockReconnect = true;
//clearTimeout() 方法可取消由 setTimeout() 方法设置的定时操作。
// clearTimeout() 方法的参数必须是由 setTimeout() 返回的 ID 值。
this.reconnectData && clearTimeout(this.reconnectData);
// setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式
//5s后调用initWebSocket()
//这个函数执行成功 reconnectData会变为1 也就是true
this.reconnectData = setTimeout(() => {
this.initWebSocket();
this.lockReconnect = false;
}, 5000);
},
//心跳检测
heartBeat() {
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(() => {
this.webSocketSend({ type: '心跳检测' }); //根据后台要求发送
this.serverTimeoutObj = setTimeout(() => {
this.webSock.close(); //如果10秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
}, 10000);
}, this.timeout);
},
//使滚动条固定在底部
scrollToBottom: function() {
this.$nextTick(() => {
//Vue 在更新 DOM 时是异步执行的,为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。
var container = this.$el.querySelector('.data'); //返回父元素的第一个匹配的子元素
container.scrollTop = container.scrollHeight;
});
},
load() {
//数据流 element-ui无限滚动函数
this.count = this.arr;
// console.log(this.count)
}
},
destroyed() {
this.lockReconnect = true;
this.webSock.close(); //离开路由之后断开websocket连接
clearTimeout(this.reconnectData); //离开清除 timeout
clearTimeout(this.timeoutObj); //离开清除 timeout
clearTimeout(this.serverTimeoutObj); //离开清除 timeout
}
};
</script>
<style>
.content-left {
width: 375px;
height: 625px;
background: url(../../../static/leftpage.png) no-repeat;
background-size: 100% 100%;
box-shadow: 0 0 40px 0 rgba(98, 103, 211, 0.3);
}
.title {
display: flex;
justify-content: flex-start;
align-items: center;
width: 100%;
margin-left: 32px;
line-height: 65px;
}
.title-text {
letter-spacing: 5px;
color: #f1f1fe;
font-size: 20px;
}
.title-icon {
display: block;
width: 54px;
height: 17px;
background: url(../../../static/titleicon.png) no-repeat;
background-size: 100% 100%;
margin-left: 12px;
}
.content-left-data {
width: 86%;
height: 535px;
padding-bottom: 5px;
box-sizing: border-box;
margin: auto;
background: #383195;
}
.content-left-data-text {
width: 100%;
padding-left: 10px;
padding-right: 10px;
box-sizing: border-box;
font-size: 14px;
margin-top: 5px;
color: #ac7fff;
}
</style>
注意我这里使用了背景图片,记得取消,或者换成背景就好,不然会路径报错
好了,这样终于实现我想要的实时数据流效果了。还有就是具体情况具体分析,我这只是处理过大数据流的一种思路,如果有更好的实现方法可以告诉我,大家互相学习一下,如果有帮助到解决问题,麻烦给个赞,谢谢~
更多推荐
已为社区贡献21条内容
所有评论(0)