【问题标题】:How do I send image to server via socket.io?如何通过 socket.io 将图像发送到服务器?
【发布时间】:2020-04-16 02:30:58
【问题描述】:

我一直在努力解决这个问题,但找不到合适的解决方案。 我希望能够通过 socket.io emit 将图像上传到服务器,然后再将它们保存到 MongoDB 数据库中。我该怎么做呢?我见过有人用 base64 编码来做,但我不知道它是如何工作的,这个网站上还有其他问题询问关于通过 socket.io 从服务器向客户端发送图像,但没有关于这个。感谢所有帮助。

目标:将图片上传到socket.emit('image', someimagefile)或类似的服务器。

如果您能提供类似的方式将图像发送给客户,我将不胜感激。

【问题讨论】:

  • 不要使用base64...没有意义。您所做的只是在大小上增加 33% 的开销,浪费 CPU 和内存使用,以实现零收益。 Web Sockets 和 Socket.IO 支持二进制传输。此外,为什么要通过 socket.IO 发送它?正常的 HTTP 请求可以正常工作。此外,虽然您可以将二进制数据推送到 MongoDB 数据库中,但它很少是最佳解决方案。最好将资产存储在磁盘上,这样您就可以使用普通的 CDN 提供它,而不是稍后提供。

标签: javascript html node.js socket.io


【解决方案1】:

如您所述,您可以使用FileReader.readAsDataURL 将图像转换为base64 并发送编码字符串,然后在服务器上对其进行解码:

document.getElementById('file').addEventListener('change', function() {

  const reader = new FileReader();
  reader.onload = function() {
    const base64 = this.result.replace(/.*base64,/, '');
    socket.emit('image', base64);
  };
  reader.readAsDataURL(this.files[0]);

}, false);
socket.on('image', async image => {
    const buffer = Buffer.from(image, 'base64');
    await fs.writeFile('/tmp/image', buffer).catch(console.error); // fs.promises
});

或者更好地使用FileReader.readAsArrayBuffer 来获取您将发送到服务器的字节数组。

document.getElementById('file').addEventListener('change', function() {

  const reader = new FileReader();
  reader.onload = function() {
    const bytes = new Uint8Array(this.result);
    socket.emit('image', bytes);
  };
  reader.readAsArrayBuffer(this.files[0]);

}, false);
socket.on('image', async image => {
    // image is an array of bytes
    const buffer = Buffer.from(image);
    await fs.writeFile('/tmp/image', buffer).catch(console.error); // fs.promises
});

从服务器接收:

// Server side
socket.emit('image', image.toString('base64')); // image should be a buffer
// Client side
socket.on('image', image => {
    // create image with
    const img = new Image();
    // change image type to whatever you use, or detect it in the backend 
    // and send it if you support multiple extensions
    img.src = `data:image/jpg;base64,${image}`; 
    // Insert it into the DOM
});

【讨论】:

    【解决方案2】:

    我不知道是否有人在寻找它,但我可以通过 socket.io 发送媒体...这是代码:

    // sending media from client side
    $("#send_media").change(function (e) {
      var data = e.originalEvent.target.files[0];
      var reader = new FileReader();
      reader.onload = function (evt) {
        var msg = {};
        msg.file = evt.target.result;
        msg.fileName = data.name;
        socket.emit("base64 file", msg);
        console.log(msg)
      };
      reader.readAsDataURL(data);
    });
       
    // showing media to ui 
    socket.on("base64 image", (msg) => {
      console.log("as", msg);
      $(".messages")
        .append(`<img src=${msg.file} alt="Red dot" />`);
    
      scrollToBottom();
    });
    

    // sending media from server side
        socket.on("base64 file", function (msg) {
          console.log("received base64 file from server: " + msg.fileName);
          socket.username = msg.username;
          io.to(roomId).emit('base64 image', //exclude sender
          // io.sockets.emit(
          //   "base64 file", //include sender
    
            {
              file: msg.file,
              fileName: msg.fileName,
            }
          );
        });
    

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      相关资源
      最近更新 更多