【问题标题】:Creating meta-data for binary chunks for sending via WebRTC datachannel为二进制块创建元数据以通过 WebRTC 数据通道发送
【发布时间】:2026-01-13 04:20:03
【问题描述】:

我有两个浏览器之间的数据通道连接,并且想将文件分成块并将它们发送到客户端/从客户端发送它们。

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

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

  2. 在重构中应用块的位置(索引号)。

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

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

如何在浏览器中执行此操作?我已经进行了很多谷歌搜索,但似乎找不到任何有关这方面的信息,所以想知道我是否可能忽略了一些有助于简化此过程的内容?

【问题讨论】:

  • 只需使用Uint8Array等类型化数组构建您自己的协议
  • 你能提供一个简单的例子吗?我一直在阅读有关处理二进制数据的各种 javascript API,但我仍然对此感到很困惑,并且还没有找到可靠的例子来说明如何实现上述目标。
  • 在下面查看我的答案。我正在使用Dart 而不是JavaScript,所以我无法真正为您提供示例。
  • @NickJennings 不要刻薄,但他的回答完全涵盖了您问题的所有基础,我认为一个好的经验法则是没有代码的问题通常会收到没有代码的答案。

标签: javascript browser blob webrtc rtcdatachannel


【解决方案1】:

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

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

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

      • 1 字节:包类型(255 种可能的包类型)
      • 2 bytes:数据长度(2^16 bytes ~ 64KB data per chunk)
      • n 字节:
    2. 发送一个初始包(例如类型 0x01)

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

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

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

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

【讨论】:

  • 感谢您的概述,这就是我的想法,但是以更务实的方式对其进行解释会很有帮助!
【解决方案2】:

除了@Robert 的非常好的答案,您还可以使用 channel.send(blob) (至少在 FirefoxFirefox 中)。最终这应该也可以在 Chrome 中使用。

【讨论】:

  • 因此'最终':-)
【解决方案3】:

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

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

类似:

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

然后将您的文件分成 chan.send() 它们。

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

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

等等

附: 如果你真的必须在单个通道上使用文件系统协议(比如因为你想要随机访问行为),不要发明一个新的,使用一个已经存在并经过测试的 - 我喜欢 inferno/plan9 的 9p

【讨论】: