vue实时数据流处理 1、创建webscoket接口

了解过的都知道,webscoket是可以让服务器直接像浏览器推送数据,实现 实时传输,
看看先官网原生实例:

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>菜鸟教程(runoob.com)</title>
    
      <script type="text/javascript">
         function WebSocketTest()
         {
            if ("WebSocket" in window)
            {
               alert("您的浏览器支持 WebSocket!");
               
               // 打开一个 web socket
               var ws = new WebSocket("ws://localhost:9998/echo");
                
               ws.onopen = function()
               {
                  // Web Socket 已连接上,使用 send() 方法发送数据
                  ws.send("发送数据");
                  alert("数据发送中...");
               };
                
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                  alert("数据已接收...");
               };
                
               ws.onclose = function()
               { 
                  // 关闭 websocket
                  alert("连接已关闭..."); 
               };
            }
            
            else
            {
               // 浏览器不支持 WebSocket
               alert("您的浏览器不支持 WebSocket!");
            }
         }
      </script>
        
   </head>
   <body>
   
      <div id="sse">
         <a href="javascript:WebSocketTest()">运行 WebSocket</a>
      </div>
      
   </body>
</html>

要点就是var ws = new WebSocket(“ws://localhost:9998/echo”);创建一个实例,括号里是ws接口地址,根据后端给你的接口为准,这里给的案例还有些不足之处,就是没有做心跳检测,心跳监测就是监测到通道关闭断开连接,重新申请创建连接,下面是优化过的

<template>
	<!-- <div class="socket1">
		<el-card class="box-card">
			<div slot="header" class="clearfix">
				<span>WebSocket</span>
				<el-button style="float: right; padding: 3px 0" type="text" @click="webSocketSend(textarea)">发送</el-button>
				<el-button style="float: right; padding: 3px 0" type="text" @click="webSocketClose(textarea)">停止发送</el-button>
			</div>
			<div>
				<p>{{ msgData }}</p>
			</div>
			<el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="textarea"></el-input>
		</el-card>
	</div> -->
	<div class="content-left">
		<div class="title">
			<p class="title-text">原始数据流</p>
			<i class="title-icon"></i>
		</div>
		<ul class="data">
			<li class="data-text">{{ msgData }}</li>
		</ul>
	</div>
</template>

<script>
export default {
	data() {
		return {
			webSock: null,//创建 webscoket对象
			reconnectData: null,
			lockReconnect: false, //避免重复连接,因为onerror之后会立即触发 onclose
			timeout: 600000, //心跳时间参数  1小时一次心跳检测
			timeoutObj: null, //心跳检测函数执行后的参数 1代表执行成功
			serverTimeoutObj: null, //等待服务端响应函数执行后的参数 1代表执行成功
			textarea: '', //输入框 文字
			msgData: ''//ws接口推送的数据
		};
	},
	created() {
		if (typeof WebSocket === 'undefined') {
			console.log('您的浏览器不支持WebSocket');
		} else {
			console.log('您的浏览器支持WebSocket')
			this.initWebSocket();
		}
	},
	mounted() {

	},
	updated() {

	},
	methods: {
		// WebSockets参数初始化
		initWebSocket() {
			console.log('WebSocket启动中......');
	this.webSock = new WebSocket('ws://192.168.0.238:10086/ws/');
			this.webSock.onopen = this.webSocketOpen; //连接成功
			// WebSocket.onopen属性定义一个事件处理程序,当WebSocket 的连接状态readyState 变为1时调用;这意味着当前连接已经准备好发送和接受数据。这个事件处理程序通过 事件(建立连接时)触发。
			this.webSock.onmessage = this.webSocketAcceptMessage; //广播成功
			// WebSocket.onmessage 属性是一个当收到来自服务器的消息时被调用的 EventHandler。它由一个MessageEvent调用
			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请求返回的数据流,要说明的是,我这里后端返给我的数据格式是unicode码,我用eval()方法进行转码, 看实际情况去处理数据
		},
		//发送数据到服务端
		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);
		}
	},
	destroyed() {
		this.lockReconnect = true;
		this.webSock.close(); //离开路由之后断开websocket连接
		clearTimeout(this.reconnectData); //离开清除 timeout
		clearTimeout(this.timeoutObj); //离开清除 timeout
		clearTimeout(this.serverTimeoutObj); //离开清除 timeout
	}
};
</script>
<style>
.text {
	font-size: 14px;
}

.item {
	margin-bottom: 18px;
}

.clearfix:before,
.clearfix:after {
	display: table;
	content: '';
}
.clearfix:after {
	clear: both;
}

.box-card {
	width: 480px;
}
/* 滚动条样式 */
::-webkit-scrollbar {
	width: 5px;
	height: 5px;
}

::-webkit-scrollbar-track-piece {
	background-color: rgba(0, 0, 0, 0.2);
	-webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:vertical {
	height: 5px;
	background-color: rgba(125, 125, 125, 0.7);
	-webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:horizontal {
	width: 5px;
	background-color: rgba(125, 125, 125, 0.7);
	-webkit-border-radius: 6px;
}
.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;
}
.data {
	width: 86%;
	height: 535px;
	margin: auto;
	background: #383195;
	overflow: auto;
	list-style: none;
}
.data-text {
	padding-left: 10px;
	padding-right: 10px;
	box-sizing: border-box;
	font-size: 14px;
	margin-top: 5px;
	color: #ffffff;
}
</style>


版权声明:本文为GongWei_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。