Я создаю приложение для чата (в React Native), но сейчас я провел несколько тестов на vanilla JavaScript. Сервер является NodeJS -сервером.
Он работает с отправкой текстовых сообщений, но теперь у меня есть несколько вопросов об отправке фото / видео / аудио файлов. Я провожу много исследований в Интернете о том, как лучше всего это сделать.
Мне пришла в голову идея использовать API-интерфейс FileReader, разделить файл на куски и отправлять куски по частям через socket.emit () - функция.
Это мой код (упрощенно):
Обратите внимание, что я создам приложение React Native, но пока (для тестирования ), Я только что создал HTML -файл с формой загрузки.
// index.html
// the page where my upload form is
var reader = {};
var file = {};
var sliceSize = 1000 * 1024;
var socket = io('http://localhost:8080');
const startUpload = e => {
e.preventDefault();
reader = new FileReader();
file = $('#file)[0].files[0]
uploadFile(0)
}
$('#start-upload').on('click', startUpload)
const uploadFile = start => {
var slice = start + sliceSize + 1;
var blob = file.slice(start, slice)
reader.on('loadend', e => {
if (slice < file.size) {
socket.emit('message', JSON.stringify({
fileName: file.name,
fileType: file.type,
fileChunk: e.target.result
})
} else {
console.log('Upload completed!')
}
})
reader.readAsDataURl(blob)
}
// app.js
// my NodeJS server-file
var file;
var files = {};
io.on('connection', socket => {
console.log('User connected!');
// when a message is received
socket.on('message', data => {
file = JSON.parse(data)
if (!files[file.fileName]) {
// this is the first chunk received
// create a new string
files[file.fileName] = '';
}
// append the binary data
files[file.fileName] = files[file.fileName] + file.fileChunk;
})
// on disconnect
socket.on('disconnect', () => {
console.log('User disconnected!');
})
})
Я не включал какие-либо проверки для типа файла (я еще не на этом этапе), Сначала я хочу убедиться, что это правильно.
Материал, который мне нужно сделать:
- Отправить сообщение (например, socket.emit ('uploaddone',. ..)) от клиента к серверу, чтобы уведомить сервер о том, что загрузка завершена (и сервер может передать весь файл другому пользователю).
Мои вопросы:
- Можно ли отправлять порции двоичных данных (base64) через сокет, или это займет много трафика?
- Wi Потеряю ли я качество (фото / видео / аудиофайлы) при разбиении их на куски?
Если есть лучший способ сделать это, пожалуйста, дайте мне знать. Я не прошу рабочие примеры кода, просто некоторые указания в хорошем направлении.