项目中遇到的问题
1、文件上传
背景:
项目基于jquery
,文件列表中有文件上传功能,点击上传按钮,弹出模态框,在模态框的形式选择文件,进行上传。
遇到的问题:
- 无法关闭模态框,进而无法切换页面,无法进行其他操作(关闭模态框,无法查看文件上传的进度)
- 大文件上传时,中间如果失败了,需要重头开始上传,使用不友好
解决方法:
- 将模态框改为普通弹框,显示在页面最上方,可以进行拖拽、放大和缩小
在盒子里拖拽:
$( "#draggable3" ).draggable({ containment: "#containment-wrapper", scroll: false });
在父元素内拖拽:
$( "#draggable5" ).draggable({ containment: "parent" });
- 对大文件进行切片上传和断点续传,见文件上传笔记
- 后期将
juqery
改为vue
,单页面应用,切换页面,不回影响上传弹框
2、websocket
背景: 开发一个站内信的功能,要求要实时通讯,选择使用 websocket
进行前后端通信。
步骤:
- 实例化一个 WebSocket:
new WebSocket(url)
,url 中,如果是 http 协议就使用 ws,如果是 https 就使用 wss - 使用
onopen
方法建立连接 - 通过
onmessage
获取后端传给前端的数据 - 通过
send
给后端传递数据 - 通过
onerror
onclose
去做其他的一些处理
问题: 经测试,某些情况下连接会断开
解决: 使用心跳检查,协定好前后端传递的数据、前后端穿数据的时间间隔、连接最大次数
- 每隔一定的时间,前端给后端传递一个协定好的字段,如
ping
- 后端接收到这个字段后,给前端返回一个协定好的字段,如
pong
- 在上面的过程中,如果超过指定的时间,后端还没有返回需要的字段,前端就要尝试重新连接
- 如果超过最大的连接次数,就不在进行重连,否则接续尝试连接,直到连上为止
connectWebSocket () {
if(window.webSocket == undefined || window.webSocket == null) {
// socket 地址
var url = 'ws://' + websocketUrl + account;
// 实例化 WebSocket 对象
window.webSocket = new WebSocket(url);
// 建立 WebSocket 连接
window.webSocket.onopen = () => {
_that.longstart(); // 成功建立连接后,创建心跳检测
};
// 前端获取到后端通过 onmessage 返回到数据
window.webSocket.onmessage = (evt) => {
_that.longstart(); //心跳重置
}
// 监听连接失败
window.webSocket.onerror = () => {
this.websocketonerror("webSocket.onerror")
};
// 监听连接关闭
window.webSocket.onclose = () => {
this.websocketonerror("webSocket.onclose")
}
} else {
this.retryNum ++;
window.webSocket = null
this.websocketonerror() //连接失败时,进行重连
}
}
websocketonerror() {
this.retryNum <= 6 && this.connectWebSocket(); //失败、关闭重连
},
// 心跳检测
longstart() {
//1、通过关闭定时器和倒计时进行重置心跳
this.retryNum = 0;
clearInterval(this.timeoutObj)
clearTimeout(this.serverTimeoutObj);
// 2、每隔10s向后端发送一条商议好的数据
this.timeoutObj = setInterval(()=>{
if(this.retryNum <= 6) { //只允许重试6
// console.log('监测心跳')
let data='{"body": "pong","direct":"request"}'
window.webSocket && window.webSocket.send(data);
// 3、发送数据 5s后没有接收到返回的数据进行关闭websocket重连
this.serverTimeoutObj = setTimeout(()=>{
this.lockReconnect = true;
this.retryNum ++;
// console.log("后台挂掉,没有心跳了....,重试了"+this.retryNum+"次");
if(window.webSocket) {
window.webSocket.close();
}
}, 5000);
} else {
clearInterval(this.timeoutObj)
clearTimeout(this.serverTimeoutObj);
}
},10000)
},
destroySocket() {
if (window.webSocket) {
window.webSocket.close(); // 离开路由之后断开websocket连接
}
clearInterval(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
}