代码之家  ›  专栏  ›  技术社区  ›  user2859982

如何通过Websocket发送文件以及其他信息?

  •  7
  • user2859982  · 技术社区  · 6 年前

    我正在开发一个Web应用程序,通过管理界面将图像、视频等发送到两个监视器。我正在节点中使用ws。服务器端的js。我已经实现了选择服务器和外部URL上可用的图像并将其发送到客户端,但我还希望能够通过文件输入直接发送从设备中选择的图像。我设法用base64实现了这一点,但我认为它效率很低。

    目前,我发送了一个字符串化的JSON对象,其中包含必须向其发送资源的客户端、资源的种类和资源本身,在服务器中对其进行解析并将其发送到相应的客户端。我知道我可以将Websocket二进制类型设置为blob,然后只发送File对象,但是我无法告诉服务器它必须将其发送到哪个客户端。我尝试使用typeson和BSON来完成这项工作,但没有成功。

    还有其他方法吗?

    3 回复  |  直到 6 年前
        1
  •  7
  •   Myst    6 年前

    您可以通过WebSocket发送原始二进制数据。

    这很容易管理。

    一个选项是在“幻方字节”(将消息标记为非JSON的标识符)之前加上前缀。例如,使用 B 性格

    服务器所要做的就是在收集二进制数据之前测试第一个字符(如果没有魔法字节,可能是正常的JSON消息)。

    更严格的实现是在魔法字节后附加一个头(即文件名、总长度、发送数据的位置等)。

    这允许在断开连接时恢复上载(只发送未确认接收的部分)。

    您的服务器需要将数据拆分为 magic byte ,则, header binary_data 处理前。但这很容易做到。

        2
  •  7
  •   Travis Nguyen    5 年前

    希望这对别人有帮助。 根据插座。io文档您可以发送字符串、缓冲区或两者混合

    在客户端:

    function uploadFile(e, socket, to) {
      let file = e.target.files[0];
    
      if (!file) {
        return
      }
      if (file.size > 10000000) {
        alert('File should be smaller than 1MB')
        return
      }
    
      var reader = new FileReader();
      var rawData = new ArrayBuffer();
    
      reader.onload = function (e) {
        rawData = e.target.result;
        socket.emit("send_message", {
          type: 'attachment',
          data: rawData
        } , (result) => {
          alert("Server has received file!")
        });
        alert("the File has been transferred.")
      }
    
      reader.readAsArrayBuffer(file);
    }
    

    在服务器端:

    socket.on('send_message', async (data, cb) => {
      if (data.type == 'attachment') {
          console.log('Found binary data')
          cb("Received file successfully.")
          return
        }
    // Process other business...
    });
    
        3
  •  5
  •   Fide    3 年前

    我使用的是没有io的纯WebSocket,您无法混合内容-字符串或二进制。那么我的工作解决方案是这样的:

    客户:

        import { serialize } from 'bson';
        import { Buffer } from 'buffer';
    
        const reader = new FileReader();
        let rawData = new ArrayBuffer();
        ws = new WebSocket(...)
        reader.onload = (e) => {
          rawData = e.target.result;
          const bufferData = Buffer.from(rawData);
          const bsonData = serialize({  // whatever js Object you need
            file: bufferData,
            route: 'TRANSFER',
            action: 'FILE_UPLOAD',
          });
          ws.send(bsonData);
        }
    

    然后在节点服务器端,消息被捕获并解析如下:

            const dataFromClient = deserialize(wsMessage, {promoteBuffers: true}) // edited
            fs.writeFile(
              path.join('../server', 'yourfiles', 'yourfile.txt'),
              dataFromClient.file, // edited
              'binary',
              (err) => {
                console.log('ERROR!!!!', err);
              }
            );
    

    凶手是 promoteBuffer 反序列化函数中的选项。