实现一个比赛现在的实时成绩大屏 后端利用eqt发送信息给前端 拿到数据后实时展示
前端利用webscoket 实现 接收到不同的数据跳转不同的页面
1.WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议(独立的、创建在 TCP 上的)
2.功能:使客户端和服务器之间数据交换变得更加简单,允许服务端主动向客户端推送数据
3.如何交互?
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
4. 为何会出现这个websocket协议?
网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询使浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,这样会浪费很多的带宽等资源。
5. 特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
import { mapMutations } from "vuex";
export default {
data() {
return {
ws: null, //建立的连接
lockReconnect: false, //是否真正建立连接
timeout: 30 * 1000, //30秒一次心跳
timeoutObj: null, //心跳心跳倒计时
serverTimeoutObj: null, //心跳倒计时
timeoutnum: null, //断开 重连倒计时
isUpdateView: true,
};
},
created() {
this.initWebpack();
},
methods: {
...mapMutations([
"changeOperate",
"changeEqtMessage",
"getTopThree",
"getGameTitle",
"getRoundName",
"changeInfo",
]),
initWebpack() {
this.ws = new WebSocket(window.url);
this.ws.onopen = this.onopen;
this.ws.onmessage = this.onmessage;
this.ws.onclose = this.onclose;
this.ws.onerror = this.onerror;
},
reconnect() {
//重新连接
let that = this;
if (that.lockReconnect) {
return;
}
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
that.timeoutnum && clearTimeout(that.timeoutnum);
that.timeoutnum = setTimeout(() => {
//新连接
that.initWebpack();
that.lockReconnect = false;
}, 5000);
},
reset() {
//重置心跳
let that = this;
//清除时间
clearTimeout(that.timeoutObj);
clearTimeout(that.serverTimeoutObj);
//重启心跳
that.start();
},
start() {
//开启心跳
let self = this;
self.timeoutObj && clearTimeout(self.timeoutObj);
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
self.timeoutObj = setTimeout(() => {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log(self.ws.readyState);
if (self.ws.readyState == 1) {
//如果连接正常
self.ws.send("heartCheck");
} else {
//否则重连
self.reconnect();
}
self.serverTimeoutObj = setTimeout(() => {
//超时关闭
self.ws.close();
}, self.timeout);
}, self.timeout);
},
onopen() {
console.log("open");
//开启心跳
this.start();
},
onmessage(evt) {
//收到服务器信息,心跳重置
this.reset();
if (!this.isUpdateView) {
this.isUpdateView = true;
return;
}
const DATA = JSON.parse(evt.data);
this.getGameTitle(DATA.Game);
this.getRoundName(DATA.RoundName);
DATA.Operate && this.changeOperate(DATA.Operate);
this.changeEqtMessage(DATA.Data);
if (DATA.PageCode === 6) {
this.$router.push("/result");
this.getTopThree(DATA.TopThere);
DATA.SelectCurrentRow && this.changeInfo(DATA.SelectCurrentRow);
}
if (DATA.PageCode === 1) {
this.$router.push("/image");
} else if (DATA.PageCode === 2) {
this.$router.push("/startOrder");
} else if (DATA.PageCode === 3) {
this.$router.push("/judgeList");
} else if (DATA.PageCode === 4) {
this.$router.push("/gradeList");
} else if (DATA.PageCode === 5) {
this.$router.push("/rankingList");
} else if (DATA.PageCode === 7) {
this.$router.push("/welcome");
} else if (DATA.PageCode === 8) {
this.$router.push("/todaySchedule");
} else if (DATA.PageCode === 9) {
this.$router.push("/tomorrowSchedule");
}
},
onclose(e) {
console.log(
"websocket 断开: " + e.code + " " + e.reason + " " + e.wasClean
);
this.isUpdateView = false;
//重连
this.reconnect();
},
onerror() {
console.log("出现错误");
//重连
this.reconnect();
},
},
};
</script>