概述WebSocket 提供低延迟双向通道。本文给出二进制分块上传与确认协商,并结合 IndexedDB 保存进度以实现断线恢复。分块上传与确认function supportsWS() { return typeof WebSocket === 'function'; }

async function* chunkFile(file, size) {

let o = 0;

while (o < file.size) {

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

const ab = await b.arrayBuffer();

yield new Uint8Array(ab);

o += size;

}

}

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

if (!supportsWS()) throw new Error('ws not supported');

const ws = new WebSocket(url);

await new Promise(resolve => { ws.binaryType = 'arraybuffer'; ws.onopen = resolve; });

let idx = await loadProgress(file.name);

ws.onmessage = async e => {

const msg = JSON.parse(new TextDecoder().decode(new Uint8Array(e.data)));

if (msg.type === 'ack') { idx = idx + 1; await saveProgress(file.name, idx); }

};

let i = 0;

for await (const chunk of chunkFile(file, size)) {

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

const payload = JSON.stringify({ type: 'chunk', index: i, name: file.name });

const head = new TextEncoder().encode(payload);

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

merged.set(head, 0);

merged.set(chunk, head.length);

ws.send(merged);

i++;

}

}

进度持久化function openDB(name) {

return new Promise((resolve, reject) => {

const r = indexedDB.open(name, 1);

r.onupgradeneeded = () => { const db = r.result; if (!db.objectStoreNames.contains('up')) db.createObjectStore('up'); };

r.onsuccess = () => resolve(r.result);

r.onerror = () => reject(r.error);

});

}

async function saveProgress(key, value) {

const db = await openDB('wsup');

const tx = db.transaction('up', 'readwrite');

tx.objectStore('up').put(value, key);

await new Promise((resolve, reject) => { tx.oncomplete = resolve; tx.onerror = () => reject(tx.error); });

db.close();

}

async function loadProgress(key) {

const db = await openDB('wsup');

const tx = db.transaction('up', 'readonly');

const req = tx.objectStore('up').get(key);

const val = await new Promise((resolve, reject) => { req.onsuccess = () => resolve(req.result || 0); req.onerror = () => reject(req.error); });

db.close();

return val;

}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部