Skip to content

Instantly share code, notes, and snippets.

@lloydzhou
Created December 9, 2021 04:09
Show Gist options
  • Save lloydzhou/4dbd6aa345d3ae10451912d5d74beeb8 to your computer and use it in GitHub Desktop.
Save lloydzhou/4dbd6aa345d3ae10451912d5d74beeb8 to your computer and use it in GitHub Desktop.
/**
* 1. 创建websocket连接,后端会生成对应的channel<user_id, task_id>,前端是一个固定的url
* 2. 监听创建成功事件
* 2.1 如果创建成功就将任务<source_url, title, author>通过创建好的websocket发送到服务端
* 2.2 如果创建失败,直接reject
* 3. 监听接收消息事件
* 3.1 如果收到转换成功的url,代表后端的整个转换任务成功,将url resove出去
* 3.2 收到其他任务进度消息,可以忽略
*/
export const submitTask = (
source_url: string,
title: string,
author: string,
avatar: string = '',
site: string = '',
timeout: number = 60000
) => {
let socket;
let timer;
let interval;
return new Promise((resolve, reject) => {
let percent;
let maxStep = 5;
// 最后一个步骤是等微信的回调,这个回调时间可能会比较长
// 就直接多增加一个步骤,这样相当于最后一步的时长是其他步骤的两倍
let step = 0;
// 这里如果传了onProgress就调用外部的如果没有就使用toast
// TODO 增加一个maxStep字段,收到一个消息step自增,
// 并且计算当前的百分比
const progress = (t) => {
percent = (timeout - t) / timeout;
const second = Math.floor(t / 1000);
console.log('taskProgress', t, timeout, percent, percent * 100, second);
eventCenter.trigger('taksProgress', percent * 100, second);
// Taro.showToast({
// title: `转换中,预计还需${second}秒`,
// icon: 'none'
// });
if (t < 1000) {
// 超时后主动断掉连接
reject({ errMsg: 'timeout' });
} else {
timer = setTimeout(() => progress(t - 1000), 1000);
}
};
progress(timeout);
socket = wx.connectSocket({
url: socketUrl,
header: {
'X-Session-Id': getSid()
},
success: function(res) {
console.log('connectSocket success', res);
},
fail: function(err) {
console.error('connectSocket error', err);
reject(err);
}
});
socket.onOpen(() => {
console.log('链接成功!');
if (site == 'wechat') {
maxStep = 3;
}
interval = setInterval(() => {
socket.send({
data: 'PING',
success: (res) => {
console.log('send PING');
}
});
}, 1000);
socket.send({
data: JSON.stringify({
source_url,
title,
author,
avatar,
site
}),
success: function(res) {
console.log('submitTask success', res);
eventCenter.trigger('taksProgressModal', true);
},
fail: function(err) {
console.error('submitTask error', err);
reject(err);
}
});
});
socket.onMessage((res) => {
const { data } = res;
console.log('get message', res, data);
try {
const message = JSON.parse(data);
if (message.code != 0) {
console.log('recevied error message', message);
reject(message);
} else {
console.log('recevied success message', message);
// 接收到消息的时候,如果发现当前进度percent小于按照步骤的进度
// 就强制的更新一下按照时间的进度(更新方式就是覆盖timer计时器)
const p = step / maxStep;
if (p > percent) {
const t = Math.floor(timeout * p);
if (timer) {
clearTimeout(timer);
}
// 立即更新一下进度
timer = setTimeout(() => progress(timeout - t), 0);
}
step = step + 1;
// 只有返回成功的url了才resolve
if (message.url) {
resolve(message);
}
}
} catch (e) {
console.log('parse message error', e);
}
});
socket.onError((err) => {
console.log('socket error', err);
reject(err);
});
socket.onClose((res) => {
console.log('socket close', res);
reject(res);
});
}).finally(() => {
try {
setTimeout(() => socket.close(), 50);
} catch (e) {
console.error('fail to close socket', socket, e);
}
if (timer) {
clearTimeout(timer);
}
if (interval) {
clearInterval(interval);
}
eventCenter.trigger('taksProgressModal', false);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment