websocket在vue中的使用

一、websocket

websocket是什么?为什么要用websocket?

websocket是一种网络通信呢协议,同http、https协议,是客户端与服务端通信用的,websocket创建在 TCP 上、通过HTTP/1.1 协议的101状态码进行握手。

为什么要用websocket?试想以下场景:
你妈妈在厨房做饭,你饿得不行,想马上吃到,但是妈妈不着急,她做完饭可能刷个锅洗个碗,你想在第一时间吃到饭,就得知道饭做好的消息,排油烟机声音太大得开门才能听到。

用http连接:
你(进厨房):妈妈饭好了吗?
妈妈:没好呢,再等会儿吧。
你(5分钟后又进厨房):妈妈饭好了吗?
妈妈(🙄️):急什么急,你急你做!
你(又5分钟又进厨房):妈妈饭好了吗……
妈妈:好了好了好了,催催催,饿死鬼!

用websocket连接:
你在卧室愉快玩手机(和妈妈约定饭做好后主动告诉你)
妈妈(第一时间):饭好了,出来端吧。
你:好嘞,来啦!

妈妈是服务端,你是客户端,想要服务端有新消息主动发给客户端,就要使用1、http连接,setInterval轮询请求接口获取消息或2、websocket连接,服务端主动发送消息。

二、使用websocket

这里使用了websocket结合vue的一个插件vue-native-websocket,地址:https://github.com/nathantsoi/vue-native-websocket,优点可以自动重连,缺点是找不到暴露的重连api reconnect,也可能我笨没找到😭

main.js中引用

import websocket from 'vue-native-websocket';

Vue.use(websocket, '', {
  connectManually: true, // 手动连接
  format: 'json', // json格式
  reconnection: true, // 是否自动重连
  reconnectionAttempts: 5, // 自动重连次数
  reconnectionDelay: 2000, // 重连间隔时间
});

index.vue

data() {
	return {
		paramA: "aa",
		paramB: 123,
		food: "",
		drink: "",
		num: 2, // 两碗饭
	}
}mounted() {
	this.initWebSocket();
},
sockets: {
	// 连接成功
	onopen() {
		console.log("socket success");
	},
	// 接收消息
	onmessage(e) {
		console.log("===data", JSON.parse(e.data));
		// 服务端传过来的值
		let { event, data } = JSON.parse(e.data);
		// 妈妈:饭好了事件
		if(event === "FOOD_DONE") {
			this.getFood(data);
		};
	},
	// 连接报错
	onerror() {},
	// 关闭连接
	onclose() {
		console.log("socket close");
	},
},
destroyed() {
	// 销毁websocket
    this.$disconnect();
},
methods: {
	initWebSocket({
		this.$connect(`//${location.host}/game/api/websocket/food/${this.paramA}/1/${this.paramB}`);
	}getFood(data) {
		this.food = data.food || "";
		this.drink = data.drink || "";
	},
	// 吃饭事件,把吃了几碗饭告诉妈妈
	// ws中ws.send实现,注意JSON.stringify转下格式或其他服务端要的格式
	haveFood() {
		this.$socket.sendObj({
			event: "HAVE_FOOD",
			data: this.num
		});
	}
},

三、心跳

还是妈妈在做饭,你在卧室玩手机,妈妈做饭做着做着去洗衣服了(妈妈:???),你饿得不行,还在等妈妈喊你吃饭,但是过了好久也没收到消息,这种情况我们就需要提前约定好,你们需要定期沟通:

你:妈妈还在厨房吗1?
妈妈:在呢1。
你(收到1固定时间后):妈妈还在厨房吗2?
妈妈:在呢2。
……

这种连接机制叫心跳,服务端和客户端互相发消息确认连接状态。如果网络断开了,服务端并没有发送onclose信息,客户端就会一直等待,此时就需要心跳机制,确认websocket连接状态,保证websocket的良好连接。

index.vue
心脏跳动pingping pongpong❤️

data() {
	return {
		ping: 0,
		pong: 0,
		pingTimer: null,
	}
},
sockets: {
	// 连接成功
	onopen() {
		console.log("socket success");
		// 每30s向服务端发ping+1参数,服务端返回pong参数+1,再对比确认连接状态
		this.pingTimer = setInterval(() => {
			if(this.ping === this.pong) {
				this.ping += 1;
				this.$socket.sendObj({
					event: "PING",
					data: this.ping
				});
			} else {
				this.reconnectPing();
			}
		}, 30000)
	},
	// 接收消息
	onmessage(e) {
		console.log("===data", JSON.parse(e.data));
		// 服务端传过来的值
		let { event, data } = JSON.parse(e.data);
		// 妈妈:饭好了事件;心跳:在做饭呢
		if(event === "FOOD_DONE") {
			this.getFood(data);
		};
		if(event === "PONG") {
			this.onPong(data);
		}
	},
	// 关闭连接
	onclose() {
		console.log("socket close");
		clearInterval(this.pingTimer);
        this.pingTimer = null;
	},
},
methods: {
	onPong(data) {
      this.pong = data;
    },
    reconnectPing() {
    	// 这个插件没找到this.$socket.reconnect方法呢,项目中判断次数后返回首页了,建议重连
    }
},

四、websocket优缺点

优点:
相对于http/https效率高,自动更新服务端数据无需页面刷新,耗费资源少,速度快。
缺点:
多条数据传输都依赖一条websocket连接,要保证连接的稳定性、错误处理、心跳机制的稳定性;对前后端尤其是后端开发同学要求更高,需要理清发送消息的时间,发送的事件及数据,也要保证ws的稳定性。

推荐

WebSocket 教程by 阮一峰

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值