带有流媒体档案的 Websockets

Posted

技术标签:

【中文标题】带有流媒体档案的 Websockets【英文标题】:Websockets with Streaming Archives 【发布时间】:2013-10-15 08:16:12 【问题描述】:

这就是我正在使用的设置:

    我在一个快速服务器上,它必须将存档的二进制有效负载流式传输到浏览器(不管它是 ziptar 还是 tar.gz - 尽管 zip 会很好)。 在这台服务器上,我打开了一个 websocket,它连接到另一台服务器,该服务器正在向我发送目录中单个文件的二进制有效负载。我将这些有效负载逐个作为缓冲区流式传输,并且我正在串行执行此操作(即 - 逐个文件 - 一次没有打开多个 websocket,每个文件有一个 websocket )。这是我正在使用的 websocket 库:https://github.com/einaros/ws

我想浏览每个文件,打开一个 websocket,然后在缓冲区通过 websocket 时将它们附加到存档器。当数据附加到存档器时,如果我可以将存档器的输出流式传输到浏览器(通过带有response.writeresponse 对象),那就太好了。因此,基本上,当我从 websocket 获取有效负载时,我希望该有效负载通过存档器流式传输,然后发送到响应。 :-)

我研究过的一些事情:

    node-zipstream - 这很好,因为它给了我一个输出流,我可以直接通过管道传输到response.write。但是,它似乎不支持嵌套文件/文件夹,更重要的是,它只接受输入流。我查看了源代码(非常简洁易读),似乎如果我能够访问ZipStream.prototype.addFile 中的update 函数,我每次都可以在@ 上调用它987654333@ 从 websocket 获取二进制缓冲区时的事件。不过这很混乱/很麻烦,而且,鉴于这个库似乎已经不支持嵌套文件/文件夹,我不确定我是否会使用它。 node-archiver - 这与 node-zipstream 存在相同的问题(可能是因为它受到了它的启发),它允许我通过管道输出,但我不能在存档中为同一个文件附加多个缓冲区(然后手动发出信号当给定文件附加了最后一个缓冲区时)。但是,它确实允许我拥有嵌套文件夹,这明显胜过 node-zipstream。

有什么我不知道的,或者这只是我想做的一件非常疯狂的事情吗?

此时我看到的唯一选择是等待整个有效负载通过 websocket 流式传输,然后附加 node-archiver,但我真的很想获得真正的流式传输/存档的好处-飞。

我还考虑过创建某种读取流以充当代理对象的可能性,我可以将其传递给节点归档器,然后将我从 websocket 获得的缓冲区附加到该读取流。查看各种读取流,但我不确定如何执行此操作。我能想到的唯一方法是创建一个写入流,将缓冲区传输到它,然后从该写入流读取一个读取流。我在这里的思考过程是否正确?

一如既往,感谢您为 SO 社区提供的任何帮助/指导。

编辑

由于我刚刚打开了这个问题,而且我是 node 新手,因此可能会有比我提供的更好的答案。如果有人在几天内提出自己,我将保持这个问题的开放并接受更好的答案。与往常一样,我会投票赞成任何其他答案,即使它们很荒谬,只要它们是正确的并且允许我像我的那样即时流式传输。

【问题讨论】:

【参考方案1】:

我想出了一种方法来使用 node-archiver。 :-)

这是基于我创建临时“代理流”的直觉,灵感来自这个 SO 问题:How to create streams from string in Node.Js?

基本要点是(coffeescript 语法):

archive = archiver 'zip'
archive.pipe response // where response is the http response

// and then for each file...
fileName = ... // known file name
fileSize = ... // known file size
ws = .... // create websocket
proxyStream = new Stream()
numBytesStreamed = 0

archive.append proxyStream, name: fileName

ws.on 'message', (dataBuffer) ->
    numBytesStreamed += dataBuffer.length
    proxyStream.emit 'data', dataBuffer

    if numBytesStreamed is fileSize
        proxyStream.emit 'end'
        // function/indicator to do this for the next file in the folder

// and then when you're completely done...
archive.finalize (err, bytesOfArchive) ->
    if err?
        // do whatever
    else
        // unless you somehow knew this ahead of time
        res.addTrailers
            'Content-Length': bytesOfArchive
        res.end()

请注意,这不是我实施的完整解决方案。获取文件、它们的路径等仍然有很多逻辑处理。更不用说错误处理了。

编辑

由于我刚刚打开了这个问题,而且我是 node 新手,因此可能会有更好的答案。如果有人在几天内提出自己,我将保持这个问题的开放并接受更好的答案。与往常一样,我会投票赞成任何其他答案,即使它们很荒谬,只要它们是正确的并且允许我像我的那样即时流式传输。

【讨论】:

以上是关于带有流媒体档案的 Websockets的主要内容,如果未能解决你的问题,请参考以下文章

档案数字化

android MediaPlayer类可以得到播放档案位元速率不?

电脑问题

windows系统文件中各种扩展名分别是啥意思?

文件的类型有多少种?都用啥方式打开?

带有媒体查询的 chrome 中的错误