【问题标题】:File uploads through socket.io (JavaScript & FileReader)通过 socket.io (JavaScript & FileReader) 上传文件
【发布时间】:2020-01-19 12:45:18
【问题描述】:

我正在创建一个聊天应用程序(在 React Native 中),但现在,我已经在 vanilla JavaScript 中进行了一些测试。服务器是 NodeJS 服务器。

它适用于发送短信,但现在我对发送照片/视频/音频文件有一些疑问。我在网上做了大量研究,了解什么是最好的方法。

我想出了使用 FileReader API 并将文件拆分成块,并通过 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),还是会占用大量带宽?
  • 将照片/视频/音频文件分割成块时会丢失一些质量吗?

如果有更好的方法,请告诉我。我不是在要求工作代码示例,只是在好的方向上提供一些指导。

【问题讨论】:

    标签: javascript node.js socket.io filereader


    【解决方案1】:

    您可以通过 WebSocket 发送原始字节,base64 有 33% 的大小开销。

    您也不必 JSON.stringify 所有(可能是大的)正文并在客户端解析它。

    我会失去一些品质

    不,底层协议 (TCP) 按顺序传送数据且不会损坏。

    【讨论】:

      【解决方案2】:

      我意识到这个答案晚了几个月,但为了将来参考,您应该考虑使用 socket.io here 的确认选项

        // with acknowledgement
        let message = JSON.stringify({
                      fileName: file.name,
                      fileType: file.type,
                      fileChunk: e.target.result
                  })
        socket.emit("message", message, (ack) => {
          // send next chunk...
        });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-14
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 2021-04-18
        相关资源
        最近更新 更多