概述心跳与重连能显著提升弱网下的可靠性。本文展示进度持久化与重连后的续传。心跳与续传function openDB(name) { return new Promise((resolve, reject) => { const r = indexedDB.open(name, 1); r.onupgradeneeded = () => { const db = r.result; if (!db.objectStoreNames.contains('ws')) db.createObjectStore('ws'); }; r.onsuccess = () => resolve(r.result); r.onerror = () => reject(r.error); }); }

async function saveIndex(name, idx) { const db = await openDB('wsup'); const tx = db.transaction('ws','readwrite'); tx.objectStore('ws').put(idx, name); await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = () => rej(tx.error); }); db.close(); }

async function loadIndex(name) { const db = await openDB('wsup'); const tx = db.transaction('ws','readonly'); const req = tx.objectStore('ws').get(name); const v = await new Promise((res, rej) => { req.onsuccess = () => res(req.result||0); req.onerror = () => rej(req.error); }); db.close(); return v; }

async function connect(url, onOpen) {

const ws = new WebSocket(url);

ws.binaryType = 'arraybuffer';

await new Promise(res => { ws.onopen = res; });

const timer = setInterval(() => ws.readyState === 1 && ws.send(JSON.stringify({ type:'ping' })), 5000);

ws.onclose = () => clearInterval(timer);

onOpen(ws);

}

async function resumeUpload(url, file, size = 512*1024) {

const name = file.name; const startIdx = await loadIndex(name);

await connect(url, async ws => {

let i = 0; for (let o=0;o<file.size;o+=size) {

const b = file.slice(o, o+size); const ab = await b.arrayBuffer();

if (i < startIdx) { i++; continue; }

const head = new TextEncoder().encode(JSON.stringify({ type:'chunk', index:i, name }));

const merged = new Uint8Array(head.length + ab.byteLength);

merged.set(head, 0); merged.set(new Uint8Array(ab), head.length);

ws.send(merged); i++;

ws.onmessage = async e => { const m = JSON.parse(new TextDecoder().decode(new Uint8Array(e.data))); if (m.type === 'ack') await saveIndex(name, m.index+1); };

}

});

}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部