Estoy creando una aplicación de carga de archivos para familiarizarme con el concepto de secuencias. Estoy tratando de convertir una lista de archivos o blobs en una transmisión, luego subirla al backend y almacenarla en el sistema de archivos.
No tuve ningún problema con las implementaciones de frontend y backend respectivamente, pero me está costando conectar las dos. Mi principal problema es que no entiendo la diferencia entre Web Streams API y Node.js Streams API. Logré convertir los blobs de los archivos de entrada seleccionados en el navegador en una Web, ReadableStreampero los paquetes que probé ( axiospara solicitudes socket.ioy socket.io-streampara WebSocket) solo aceptan la versión Stream de Node.js como argumentos. Tampoco pude canalizar un Web ReadableStream en un Node.js Writeable o Duplex Stream. Los nombres de los métodos también son diferentes (por ejemplo: pipeToo pipeThroughen la API web y pipeen la API de Node.js).
Sé que existen diferencias de implementación entre Node.js y los navegadores, pero ingenuamente pensé que las API serían similares. ¿Puedo de alguna manera convertir trivialmente entre flujos web y flujos de Node.js browserificados y me falta algo? ¿Vale la pena usar la Web Stream API stream-browserify?
Solución del problema
No es demasiado difícil convertir un flujo web en un flujo Node.js manualmente, pero realmente debería intentar encontrar una biblioteca que acepte flujos web nativos en lugar de calzar un Node.js shim para el streamintegrado en el navegador con Browserify.
Sin embargo, si resulta necesario usar un shim de flujo de Node.js en el navegador, debe instalarlo stream-browserifyy usarlo de esta manera:
import { Readable, Writable } from 'stream-browserify;'
// window.ReadableStream to Node.js Readable
const webRSToNodeRS = rs => {
const reader = rs.getReader();
const out = new Readable();
reader.read().then(async ({ value, done }) => {
while (!done) {
out.push(value);
({ done, value }) = await reader.read();
}
out.push(null);
});
return out;
}
// window.WritableStream to Node.js Writable
const webWSToNodeWS = ws => {
const writer = ws.getWriter();
const out = new Writable();
out._write = (chunk, encoding, callback) => {
writer.write(chunk);
callback();
};
out._final = callback => {
writer.close();
callback();
};
return out;
}
Estos métodos deberían ser suficientes para tener una interoperabilidad completa entre la web y los flujos de Node. Por ejemplo, si desea canalizar un ReadableStream web a un Node.js Writable/Duplex:
const pipeWebRSToWritable = (rs, writable) => {
// After converting you can use the normal pipe methods
webRSToNodeRS(rs).pipe(writable);
}
Sin embargo, me gustaría mencionar que no necesita una biblioteca para transmitir datos desde el cliente al servidor. La fetchAPI admite transmisiones web de forma nativa y es probablemente el camino que debe seguir.
// POST a ReadableStream (perhaps of a file) to the server
// Way easier and more performant than using a 3rd party library...
const postRSToServer = rs => fetch('/your/server/endpoint', {
method: 'POST',
body: rs
});
Última nota: asegúrese de estar usando directamente el Blob.prototype.streammétodo (llame a esto en un Fileobjeto, por ejemplo file.stream(), desde que Filese extiende Blob). Hay algunas formas de obtener ReadableStreamun archivo en JS que en realidad terminan cargando todo el archivo en la memoria del navegador, lo cual no desea.
No hay comentarios:
Publicar un comentario