为二进制块创建元数据以通过 WebRTC 数据通道发送

Creating meta-data for binary chunks for sending via WebRTC datachannel

我在两个浏览器之间建立了数据通道连接,我想将文件分成多个块并将它们发送给 to/from 客户端。

我可以读取文件并将其分解成块。但是我需要一种方法让接收客户端知道

  1. 数据块与哪个文件相关(唯一标识符)。

  2. 重建时chunk应用于哪个地方(索引号)

在浏览器中传输二进制数据时,似乎整个负载必须是二进制的。所以我不能,例如,创建一个具有上述属性的 JSON 对象,并有一个 data 属性 与实际的二进制块。

我想我需要将文件块包装到包含标识符和索引的辅助二进制 blob 中。然后,接收客户端将解码第一个包装器块以检查元数据,然后根据该信息处理实际文件块。

如何在浏览器中执行此操作?我进行了大量 google 搜索,但似乎找不到任何相关信息,所以想知道我是否忽略了一些有助于简化此过程的内容?

您必须创建自己的文件传输协议。

  1. 我假设您有一个 File/Blob 对象。您可能还使用 split() 方法来获取块。
  2. 您可以简单地使用Uint8Array传输数据。

    1. 创建满足您需求的协议,例如:

      • 1 字节:包类型(255 种可能的包类型)
      • 2 字节:数据长度(每个块 2^16 字节 ~ 64KB 数据)
      • n 字节:<数据>
    2. 发送初始包(例如键入 0x01)

      • 数据包含一些信息(全部或部分):
        • 总长度blob/file
        • 文件类型
        • 块大小
        • 块数
        • 文件名
        • ...
    3. 发送数据块(例如类型 0x02)

      • 序列号至少应使用两个字节
      • 之后是数据(不需要长度,因为你知道总长度)

注意:如果传输多个文件,你应该添加一个id或其他东西。

在接收方,您可以等待初始包并创建一个新的 Uint8Array,其长度为整个文件的长度。之后您可以使用 set() 将接收到的数据添加到块位置(偏移量 = 0-based-chunk-number*chunk-size)。收到所有块后,您可以创建 Blob.

除了@Robert 的非常好的答案之外,您还可以使用 channel.send(blob)(至少在 Firefox<->Firefox 中)。最终这也应该适用于 Chrome。

如果是多个文件的简单问题,您可以为每个新文件创建一个新的数据通道。

每个通道都会处理它自己的缓冲、序列等。

类似于:

chan = peerCon.createDataChannel("/somedir/somefile", props);

然后将您的文件分成 <64k 块并按顺序 chan.send() 它们。

接收方可以获取标签并使用它来适当地保存文件

peerCon.ondatachannel = function(channel) {
     console.log("New file " + channel.label);
     channel.onmessage = function(

等等

P.S。 如果你真的必须在单个通道上使用文件系统协议(比如因为你想要随机访问行为)不要发明一个新的,使用一个已经存在并经过测试的协议 - 我喜欢来自 [=27= 的 9p ]