1

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

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

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

  2. 块适用于重建的位置(索引号)。

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

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

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

4

3 回答 3

7

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

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

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

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

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

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

注意:如果传输多个文件,您应该添加一个 id 或其他内容。

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

于 2015-05-13T03:51:14.373 回答
1

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

于 2015-05-15T06:27:44.603 回答
0

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

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

就像是:

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

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

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

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

等等

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

于 2017-03-23T09:01:32.813 回答