Я пытаюсь отправить файл, используя stream
от client
до server
, когда сервер запрашивает его. Затем сервер отправляет поток во внешний интерфейс для установки его в качестве src
тега html5 audio
. Первый раз, когда я делаю запрос, я получаю ответ без проблем. Но при следующей попытке клиент все еще отправляет старый поток (поток первого запроса), и это приводит к ошибке TypeError: Cannot read property '_read' of null
.
Пожалуйста, найдите код ниже
Внешний интерфейс:
getSong = (songPath) => {
fetch('/song', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ path: songPath, userId: this.state.userId })
}).then(res => {
const reader = res.body.getReader();
return new ReadableStream({
start(controller) {
return pump();
function pump() {
return reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
return pump();
});
}
}
})
})
.then(stream => new Response(stream))
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url =>
this.setState({ songData: url });
})
}
Nodejs бэкэнд:
app.post('/song', async (req, res) => {
const songPath = req.body.path;
const userId = req.body.userId;
console.log(songPath);
if (!fsHandler.indexMap[userId]) {
res.status(404).send('User not found - ' + userId);
} else if (!fsHandler.indexMap[userId].socketId) {
res.status(404).send('User socket not connected - ' + userId);
} else {
fsHandler.fetchSong(req.body, res, (stream,res) => {
console.log("Stream readable ? - " + stream.readable);
stream.pipe(res, { end: false });
stream.on('end', () => {
res.end();
console.log("Song sent successfully!")
});
});
}
});
....
....
fsHandler.fetchSong = (songReq, res, cb) => {
const io = app.get('socketio');
let socketId = fsHandler.indexMap[songReq.userId].socketId; // the client is connected using socket which I store in a map. I use that to get back the socket connection to emit.
let socket = io.sockets.connected[socketId];
console.log("Socket id - " + JSON.stringify(io.sockets.connected[socketId].id));
socket.emit('get-song', { path: songReq.path });
ss(socket).on('song', (stream,data) => {
console.log('Sending song stream...')
console.log(JSON.stringify(data));
cb(stream, res);
});
}
Nodejs клиент (подключен с помощью socketio):
socket.on('get-song', (data) => {
console.log('Requested song - ' + data.path);
let stream = ss.createStream();
let fileStream = fs.createReadStream(data.path);
console.log("Sending song with length-" + fileStream.length);
fileStream.pipe(stream);
ss(socket).emit('song', stream, { name: data.path});
});
Ошибка:
Stream readable ? - true // my console log , added here for understanding where the error happens.
I:\project\node_modules\socket.io-stream\lib\iostream.js:97
this.socket._read(this.id, size);
^
TypeError: Cannot read property '_read' of null
Я симпатичная убедитесь, что это связано с повторным использованием того же потока. Кроме того, я обнаружил, что событие on ('song') сервера происходит дважды, что связано с тем, что обработчик on дважды регистрируется в сокете. Я даже пытался исправить это так:
if(!fsHandler.init){
ss(socket).on('song', (stream,data) => {
console.log('Sending song stream...')
console.log(JSON.stringify(data));
cb(stream, res);
});
fsHandler.init = true;
}
Но это приводит к ошибке Error [ERR_STREAM_WRITE_AFTER_END]: write after end
.
Пожалуйста, помогите мне.