所以,我想在 chrome 扩展程序中通过 socket.io 网络共享文件。 我的代码流程如下:
//popup.js
shareButton.addEventListener("click", async () => {
if (fileInputElement.files.length === 0) {
alert("Choose the file you want to send 📁");
return;
}
let file = fileInputElement.files[0];
let reader = new FileReader();
reader.onload = () => {
let buffer = new Uint8Array(reader.result);
console.log(buffer);
initFileShare({ filename: file.name, bufferSize: buffer.length }, buffer);
};
reader.readAsArrayBuffer(file);
});
function initFileShare(metadata, buffer) {
const bufferArray = Array.from(buffer);
chrome.runtime.sendMessage({ event: "file-share", metadata, bufferArray});
}
if (message.event === "file-share") {
const buffer = new Uint8Array(message.buffer);
socket.emit("file-share", {
metadata: message.metadata,
buffer: buffer,
targetRoomId: curr_roomID,
});
}
io.on("connection", (socket) => {
console.log(`Connection made to socket id ${socket.id}`);
socket.on("file-share", ({ metadata, buffer, targetRoomId }) => {
console.log('metadata : ' , metadata ) ;
if (buffer && buffer.slice instanceof Function) {
console.log('Buffer:');
} else {
console.log('Invalid buffer:', buffer);
}
console.log('targetRoomId' , targetRoomId) ;
// Emit the file metadata to the target socket
io.to(targetRoomId).emit("file-metadata", metadata);
// Send file chunks to the target socket
let chunkSize = 1024;
let initialChunk = 0;
function sendNextChunk() {
if (initialChunk < metadata.bufferSize) {
let start = initialChunk;
let end = Math.min(initialChunk + chunkSize, metadata.bufferSize);
let filePiece = buffer.slice(start, end);
console.log(metadata.bufferSize, filePiece.length);
io.to(targetRoomId).emit("file-chunk", filePiece);
initialChunk += chunkSize;
// Check if all chunks have been sent
if (initialChunk >= metadata.bufferSize) {
console.log("poori file send ho gyi hai ");
socket.emit("file-sent", metadata);
} else {
setTimeout(sendNextChunk, 0);
}
}
}
// Start sending chunks
sendNextChunk();
});
window.addEventListener("load", () => {
let newFile = {
buffer: [],
metadata: null,
};
socket.on("file-chunk", (chunk) => {
let chunkSize = 1024;
newFile.buffer.push(chunk);
console.log(newFile.buffer);
if (newFile.metadata) {
console.log("Buffer size and metadata buffer size:",newFile.buffer.length,newFile.metadata.bufferSize);
if (newFile.buffer.length * chunkSize >= newFile.metadata.bufferSize) {
console.log("All chunks received. Initiating download...");
console.log("Received buffer size:", newFile.buffer.length);
let receivedFile = new Blob(newFile.buffer);
console.log("receivedFile", receivedFile);
chrome.runtime.sendMessage({
event: "downloadFile",
buffer: receivedFile,
filename: newFile.metadata.filename,
});
newFile = {};
alert("Yayy! File received 🎉");
}
}
});
发送完整文件后,在background.js 中创建的blob 并不是它应该的样子。我的意思是 blob 的最终大小应该等于文件的大小,但事实并非如此。
由于我无法在客户端接收原始文件,我的意思是当我下载收到的文件时,它只是一个空白文档,上面写着'[object][object]'
假设我正在上传一个 ~5kb 文件,请注意输出中的 blob 大小:
chrome
消息传递不支持 Chrome 中的二进制数据类型。请改用标准
navigator.serviceWorker
消息传递机制。//背景.js
/** @type MessagePort */
let port;
self.onmessage = evt => {
if (evt.data === 'port') {
port = evt.ports[0];
port.onmessage = onPortMessage;
}
}
function onPortMessage(data) {
console.log(data);
}
//popup.js
async function initSWPort() {
const mc = new MessageChannel();
navigator.serviceWorker.controller.postMessage('port', [mc.port2]);
return mc.port1;
}
async function usageExample() {
const port = initSWPort();
port.postMessage({ foo: new Blob(['bar']) });
port.onmessage = evt => console.log(evt);
}