前端网络监控与断网重链

更新日期: 2020-01-22阅读: 2k标签: 网络

业务背景

最近在做大屏数据可视化项目得时候,在思考项目交付和运行情况得时候,考虑到了需要在公司大屏显示器上面展示,突然想到了项目可能面临断网及其网速慢得情况下得一下展示问题,因此作为专栏进行这两个问题得讲解


问题一 WebSocket 在网络终端和重新联网后自动链接

**知识点: ** 理解WebSocket心跳及重连机制

在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件。这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。所以就需要一种机制来检测客户端和服务端是否处于正常的链接状态。因此就有了websocket的心跳了。还有心跳,说明还活着,没有心跳说明已经挂掉了。

  • 为什么叫心跳包呢? 它就像心跳一样每隔固定的时间发一次,来告诉服务器,我还活着。
  • 心跳机制是?

心跳机制是每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了。需要重连~

那么需要怎么去实现它呢?如下所有代码

let ws = null,
	wsUrl = "ws://xxx/rest/api/websocket",
    lockReconnect = false,
    tt = null,
    that = this;
	function MonitorWebSocket(wsUrl){
		this.timeout = 3000;
		this.timeoutObj = null;
		this.serverTimeoutObj= null;
		
		try {
			ws = new WebSocket(wsUrl);
			this.init(wsUrl);
		} catch(e) {
			console.log('catch');
			this.reconnect(wsUrl);
		}
	}
	MonitorWebSocket.prototype.init = function (wsUrl) {
		ws.onopen = () => {
			 //心跳检测重置
			that.navigatorStatus()
			// console.log("client:打开连接-心跳检测开启");
    		this.heartCheckStart();
		};
		ws.onmessage = e => {
			// 拿到任何消息都说明当前连接是正常的
			// console.info('onmessage---->接收到消息');
			this.heartCheckStart();
			that.list = JSON.parse(e.data).data;
			that.list.todayData && that.$emit("changePointStatus",that.list.todayData)	
		};
		ws.onclose = params => {
			// console.log('链接关闭');
    		this.reconnect(wsUrl);
		};
		ws.onerror = function(e) {
			// console.log('发生异常了');
    		this.reconnect(wsUrl);
		};
	}
	MonitorWebSocket.prototype.reconnect = function(wsUrl) {
		if(lockReconnect) {
			return;
		};
		lockReconnect = true;
		//没连接上会一直重连,设置延迟避免请求过多
		tt && clearTimeout(tt);
		tt = setTimeout(function () {
			(function(){
				// console.info("重新连接")
				new MonitorWebSocket(wsUrl);
			})()
			lockReconnect = false;
		}, 5000);
	}
	MonitorWebSocket.prototype.heartCheckStart = function() {
		// console.log('心跳检测开始');
		this.timeoutObj && clearTimeout(this.timeoutObj);
		this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
		this.timeoutObj = setTimeout(function(){
			//这里发送一个心跳,后端收到后,返回一个心跳消息,
			// console.log('启动心跳');
			ws.send("test");
			this.serverTimeoutObj = setTimeout(function() {
				ws.close();
			}, this.timeout);

		}, this.timeout)
	}
	let linkMarket = new MonitorWebSocket(wsUrl);

归纳与总结

实现心跳检测的思路是:每隔一段固定的时间,向服务器端发送一个ping数据,如果在正常的情况下,服务器会返回一个pong给客户端,如果客户端通过 onmessage事件能监听到的话,说明请求正常,这里我们使用了一个定时器,每隔3秒的情况下,如果是网络断开的情况下,在指定的时间内服务器端并没有返回心跳响应消息,因此服务器端断开了,因此这个时候我们使用ws.close关闭连接,在一段时间后(在不同的浏览器下,时间是不一样的,firefox响应更快), 可以通过 onclose事件监听到。因此在onclose事件内,我们可以调用 reconnect事件进行重连操作。


问题二 如何创建一个Javascript页面来检测用户的互联网速度并在页面上显示它?

**知识点: ** 网速测试方法得核心思想

不管通过什么方式,一般都是通过下载一个文件,然后用文件的大小除以所耗时间,就是你的本地网络速度了。

这里介绍的是一个最常被使用的,又是最简单的方法。

let speed = {
	status: 3,
},
that = this;
function Network () {
	this.speedInterval = null;
	this.networkInterval = null;
	this.reNetworkInterval = null;
	this.time = 5000;
	this.speedStauts = null;
	this.getConnectState = function() {
		return navigator.onLine ? 1 : 0;
	}
	this.getSpeedStauts = function(){
	return this.speedStauts;
	}
}
// 网络速度检测
Network.prototype.startSpeed = function (){
	window.clearInterval(this.speedInterval);
	this.speedInterval = null;
	let that = this;
	if(this.getConnectState() == 1){
		this.speedInterval = window.setInterval(function(){
			let start = new Date().getTime();
			if(that.getConnectState() == 1){
				let img = document.getElementById("networkSpeedImage");
				try{
				img.src = "http://www.baidu.com/img/baidu_jgylogo3.gif?_t=" + new Date().getTime();
				img.onload = function(){
					let end = new Date().getTime();
					let delta = end - start;
					console.info("delta====>",delta)
					if (delta > 200) {
					console.info("凑活")
					speed.status= 1;
					} else if (delta > 100) {
					speed.status = 2;
					} else {
					speed.status = 3;
					}             
					console.info("statusSpeed====>",speed.status)             
				}
				} catch {
					speed.status = 0;
					console.info("网络断开")
				}
			}else {
				speed.status = 0;
				console.info("网络断开2")
			}
		},this.time)
	}else {
		speed.status = 0;
		console.info("网络断开1")
	}
}
let netWork = new Network();


总结

通过创建img对象,设置onload监听回调,然后指定src, 一旦指定src,图片资源就会加载,完成时onload回调就会调用,我们可以根据时机分别标记start和end。

前端判断网速的方法及其优缺点

  • img加载测速:借助img对象加载测算网速。优点:没有跨域带来的问题。缺点:(1)要自己测文件大小并提供参数fileSize,(2)文件必须为图片 (3)文件大小不能灵活控制
  • Ajax测速: 通过Ajax测算网速。 优点: (1)不用提供文件大小参数,因为可以从response首部获得(2)测试的文件不一定要是图片,且数据量能灵活控制。缺点:跨域问题
  • downlink测速: 通过navigator.connection.downlink读取网速。优点:不需要任何参数。缺点:1.兼容性很有问题,2.带宽查询不是实时的,具有分钟级别的时间间隔 已上都是可以三中方法都可以实现,大家可以考虑个子得项目进行合理得选择

链接: https://fly63.com/article/detial/7565

浅谈对soket的理解

网络上的两个程序通过一个双向的通信链实现数据的交换,这个链接的一端就成为Socket,它是进程通信的一种,即调用这个网络库的api函数实现分布在不同主机相关进程之间的数据交换

kubernetes之Flannel网络插件部署

Kubernetes系统上Pod网络的实现依赖于第三方插件,而Flannel是由CoreOS主推的目前比较主流的容器网络解决方案,CNI插件有两种功能:网络配置和网络策略,由于flannel比较简单,并不支持网络策略

JS 测试网络速度与网络延迟

通过js加载一张1x1的极小图片,测试出图片加载的所用的时长。如果换一个几百KB的图片,则可心用来计算下载网速 ,第一次加载图像时,它将比后续加载花费更长的时间,即使我们确保图像没有被缓存。

2019最新网络赚钱方法有哪些?推荐几种靠谱赚钱方式!

2019年已经是互联网发展的成熟期了,随着网络的不断发展,以及手机应用的普及,几乎人人都已经会使用网络工具。但是又有多少人知道网络赚钱这个小众的赚钱方式呢?

Angular网络请求

在Angular网络请求是一个最常见的应用之一,下列我将以 ng-alain 项目为基础描述 Angular 网络请求。注:示例中代码都以简化的形式出现。

全面分析前端的网络请求方式

大多数情况下,在前端发起一个网络请求我们只需关注下面几点:传入基本参数(url,请求方式),请求参数、请求参数类型,设置请求获取响应的方式

由Web Beacon-网络臭虫引发的思考

为何在百度搜索之后,一些网站总能够推荐我刚刚搜索过的东西?百度会记录你的搜索信息,同时会在你本地保存一个标识本地的cookie,而当你打开第三方网站时,第三方网站嵌入了百度广告的JS代码

Deepfake_深度神经网络换脸

Deepfake从技术的角度而言,这是深度图像生成模型的一次非常成功的应用,这两年虽然涌现出了很多图像生成模型方面的论文,但大都是能算是Demo,没有多少的实用价值,除非在特定领域(比如医学上)

从狭义SDN到广义SDN,网络自动化趋势下的SDN

SDN的概念主要体现的是技术架构视角,强调的是实现网络设备的软件硬件解耦、网络系统的控制面与转发面解耦,以及整体全面的可编程性。SDN的优势在于它是基于系统全局信息进行网络转发等的策略决策的

计算机网络常见问题

为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!