7

http.request()在普通 HTTP 服务器上使用 Node 的基本功能没有问题。我需要http.request()与 SHOUTcast 服务器一起使用(或类似的)。SHOUTcast“协议”与 HTTP 完全兼容,除了一个细节......第一个响应行。

正常的 HTTP 服务器响应:

HTTP/1.1 200 OK

SHOUTcast 服务器响应:

ICY 200 OK

同样,协议的其余部分是相同的。唯一的区别是HTTP/1.xICY

我想扩展、子类化或以某种方式修改 Node 的http.request()功能,以便我可以使其与 SHOUTcast 服务器一起使用。使用 Node 连接到 SHOUTcast之前已经完成,但只是通过重新发明整个轮子。我宁愿不这样做,因为这相当于一个小的协议差异。

我的问题:有没有办法执行以下操作之一?

  1. 扩展或覆盖Node 的 HTTP 解析器的相关部分。(我怀疑这是可能的,因为解析器似乎是本机代码。)

  2. 创建我自己的代码来解析 HTTP 的相关部分,但尽可能多地重用现有的 HTTP 节点组件。

  3. 创建一个简单的内部代理(或以某种方式中继数据),以便我可以在第一个服务器响应行到达 Node 的 HTTP 解析器之前对其进行修改。

  4. 还有什么?

我也考虑过使用Shred,但它不提供流式响应的选项。(它在触发事件之前等待整个服务器响应完成,这不适用于数据可以无限期运行的流服务器。)沿着同样的思路,我尝试了Request,但它使用 Node 自己的 HTTP 解析器,所以我得到与使用本机 HTTP 客户端相同的解析错误。

4

2 回答 2

5

我想出了另一种方法来做到这一点,类似于内部代理,但没有额外的连接。似乎可以覆盖 HTTP 客户端内部使用的套接字。完成后,很容易在将数据传递给原始内部套接字ondata函数之前挂钩和修改数据。

用法

var httpicy = new HttpIcyClient();
httpicy.request(/* your normal request parameters here */);

来源

var http = require('http');

var HttpIcyClient = function () {};
HttpIcyClient.prototype.request = function (options, callback) {
    var req = http.request(options, callback),
        originalOnDataFunction,
        receiveBuffer = new Buffer(0);

    req.on('socket', function (socket) {
        originalOnDataFunction = socket.ondata;
        socket.ondata = function (d, start, end) {
            receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]);
            if (receiveBuffer.length >= 4) {
                socket.ondata = originalOnDataFunction;
                if (receiveBuffer.toString('ascii', 0, 4) === 'ICY ') {
                    receiveBuffer = Buffer.concat([new Buffer('HTTP/1.0 ', 'ascii'), receiveBuffer.slice(4)]);
                }
                socket.ondata.apply(this, [receiveBuffer, 0, receiveBuffer.length]);
            }
        };
    });
    return req;
}
于 2012-08-25T06:31:53.800 回答
1

3. 创建一个简单的内部代理

砰。你说对了。

使用Node.jsnet对象创建一个实际位于用户和 http 服务器之间的 TCP 服务器。如您所描述的那样替换所有请求和响应的第一行,您可以继续按原样使用 http 服务器。(您在非标准端口上创建内部 http 服务器,在另一个端口上创建网络服务器,然后将两者之间的流链接起来,使用一些代码来拦截来自请求用户的第一块数据,以及第一块来自响应服务器的数据。)

你所有的 Javascript 代码,而且都是(几乎)没有缓冲膨胀的流式传输。

编辑,看来我误读了你的帖子。我看到您不是在尝试实现 Node.js 广播服务器,而是尝试从中访问数据。该net对象应该仍然可以工作,但方式不完全相同。

您需要使用net.connect与指定的直播服务器对话,并使用net了解net.connect流的新服务器在它和您的http.request(). 所以,它会像这样工作:

+---------------+    +----------+    +-----------+    +----------------+
| http.request()|--->|net.Server|--->|net.connect|--->|SHOUTcast Server|
|               |<---|          |<---|           |<---|                |
+---------------+    +----------+    +-----------+    +----------------+
                  TCP             JS               TCP

这就是我如何构建它。

于 2012-03-27T00:27:11.173 回答