背景信息:
在前台调用后台接口的时候,我们偶尔会遇到以下的需求场景:
前台发送http请求,后台需要做耗时非常久的大量数据的逻辑处理(如作者遇到的匹配excel上传得到的数据),此时http请求会出现超时或失败的情况。
那么,这个时候,前台需要拿到这个请求的返回结果值去做一些页面逻辑处理时,应该怎么办呢?
这个时候,有两种做法:
一:让后台将需要的结果值放在一张业务表中,前台设置定时器,定时去请求这个业务表数据;
弊端:定时器占用后台资源较多;
二:使用socket协议;
解释
什么是socket协议呢?简单说,就是可以保持长连接的接口;它将服务端与客户端做了混合,即服务端与客户端都可以扮演服务端或客户端的角色;
这里使用前端代码简单解释socket用法:
(后台也需要做相应的处理)
var socket;
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
console.log("您的浏览器支持WebSocket");
//实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接
let random = Math.random()
socket = new WebSocket("ws://192.168.3.97:8007/gt/websocket/"+random);
// socket = new WebSocket("${basePath}websocket/${cid}".replace("http","ws"));
//打开事件
socket.onopen = function() {
//socket建立连接成功
console.log("Socket 已打开");
//发送http请求等前端操作
axios.get('/ge/mate/testMate/'+random)
.then(function (response) {
console.log('++++++++ 请求成功 +++++++++')
console.log(response)
}).catch(function (error) {
console.log('++++++++ 请求失败 +++++++++')
console.log(error)
});
};
//获得消息事件,得到socket协议返回值
socket.onmessage = function(msg) {
console.log('+++++获得消息:msg.data+++++');
console.log(msg.data);
//发现消息进入 开始处理前端触发逻辑
if(msg.data == true || msg.data == 'true'){
socket.onclose()
}
};
//关闭事件
socket.onclose = function() {
console.log("Socket已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("Socket发生了错误");
//此时可以尝试刷新页面
}
//离开页面时,关闭socket
//jquery1.8中已经被废弃,3.0中已经移除
// $(window).unload(function(){
// socket.close();
//});
注意:
在案例中,使用了random随机数,意义是,需要告知后台,当前是哪一个用户打开的socket,同时结束时,后台需要关闭哪一个socket;
同时,发送http请求时,也要带上相应的随机数值;后台在对接口处理时,也要加上相应的随机数;
此方法,可以避免多个用户请求同一个接口时,出现串数据的情况;
对比
下方对比一下,http协议和socket协议的区别:
(放一张网上截图)