jQuery 使用 Node.js 流式传输数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2558606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:47:52  来源:igfitidea点击:

Streaming data with Node.js

jqueryhtmlajaxnode.jsdata-stream

提问by Saif Bechan

I want to know if it is possible to stream data from the server to the client with Node.js. I want to post a single AJAX request to Node.js, then leave the connection open and continuously stream data to the client. The client will receive this stream and update the page continuously.

我想知道是否可以使用 Node.js 将数据从服务器流式传输到客户端。我想向 Node.js 发布一个 AJAX 请求,然后保持连接打开并持续向客户端传输数据。客户端将接收此流并不断更新页面。

Update:

更新:

As an update to this answer- I cannot get this to work. The response.writeis not sent before you call close. I have set up an example program that I use to achieve this:

作为对这个答案的更新- 我无法让它工作。在response.write你打电话之前不发送close。我已经设置了一个示例程序,用于实现此目的:

Node.js:

节点.js:

var sys = require('sys'), 
http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    var currentTime = new Date();
    setInterval(function(){
        res.write(
            currentTime.getHours()
            + ':' + 
            currentTime.getMinutes()
            + ':' +
            currentTime.getSeconds()
        );
    },1000);
}).listen(8000);

HTML:

HTML:

<html>
    <head>
        <title>Testnode</title>
    </head>

    <body>
        <!-- This fields needs to be updated -->
        Server time: <span id="time">&nbsp;</span>

        <!-- import jQuery from google -->
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

        <!-- import jQuery -->
        <script type="text/javascript">
            $(document).ready(function(){
            // I call here node.localhost nginx ports this to port 8000
                $('#time').load('http://node.localhost');
            });
        </script>
    </body>
</html>

Using this method I don't get anything back until I call close(). Is this possible or should I go with a long poll approach instead where I call the load function again as one comes in?

使用这种方法,直到我调用close(). 这是可能的,还是我应该使用长轮询方法,而不是在一个进来时再次调用加载函数?

采纳答案by Kuroki Kaze

It is possible. Just use response.write() multiple times.

有可能的。只需多次使用response.write() 即可。

var body = ["hello world", "early morning", "richard stallman", "chunky bacon"];
// send headers
response.writeHead(200, {
  "Content-Type": "text/plain"
});

// send data in chunks
for (piece in body) {
    response.write(body[piece], "ascii");
}

// close connection
response.end();

You may have to close and reopen connection every 30 seconds or so.

您可能必须每 30 秒左右关闭并重新打开连接。

EDIT: this is the code I actually tested:

编辑:这是我实际测试的代码:

var sys = require('sys'),
http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    var currentTime = new Date();
    sys.puts('Starting sending time');
    setInterval(function(){
        res.write(
            currentTime.getHours()
            + ':' +
            currentTime.getMinutes()
            + ':' +
            currentTime.getSeconds() + "\n"
        );

        setTimeout(function() {
            res.end();
        }, 10000);

    },1000);
}).listen(8090, '192.168.175.128');

I connected to it by Telnet and its indeed gives out chunked response. But to use it in AJAX browser has to support XHR.readyState = 3 (partial response). Not all browsers support this, as far as I know. So you better use long polling (or Websockets for Chrome/Firefox).

我通过 Telnet 连接到它,它确实给出了分块响应。但是要在 AJAX 浏览器中使用它必须支持 XHR.readyState = 3(部分响应)。据我所知,并非所有浏览器都支持这一点。所以你最好使用长轮询(或 Chrome/Firefox 的 Websockets)。

EDIT2: Also, if you use nginx as reverse proxy to Node, it sometimes wants to gather all chunks and send it to user at once. You need to tweak it.

EDIT2:另外,如果您使用 nginx 作为 Node 的反向代理,它有时希望收集所有块并立即将其发送给用户。你需要调整它。

回答by BMiner

Look at Sockets.io. It provides HTTP/HTTPS streaming and uses various transports to do so:

看看 Sockets.io。它提供 HTTP/HTTPS 流并使用各种传输来实现:

  • WebSocket
  • WebSocket over Flash (+ XML security policy support)
  • XHR Polling
  • XHR Multipart Streaming
  • Forever Iframe
  • JSONP Polling (for cross domain)
  • 网络套接字
  • WebSocket over Flash(+ XML 安全策略支持)
  • XHR 轮询
  • XHR 多部分流
  • 永远的 iframe
  • JSONP 轮询(用于跨域)

And! It works seamlessly with Node.JS. It's also an NPM package.

和!它与 Node.JS 无缝协作。它也是一个 NPM 包。

https://github.com/LearnBoost/Socket.IO

https://github.com/LearnBoost/Socket.IO

https://github.com/LearnBoost/Socket.IO-node

https://github.com/LearnBoost/Socket.IO-node

回答by Andrey Antukh

You can also abort the infinite loop:

您还可以中止无限循环:

app.get('/sse/events', function(req, res) {
    res.header('Content-Type', 'text/event-stream');

    var interval_id = setInterval(function() {
        res.write("some data");
    }, 50);

    req.socket.on('close', function() {
        clearInterval(interval_id);
    }); 
}); 

This is an example of expressjs. I believe that without expressjs will be something like.

这是 expressjs 的一个例子。我相信没有 expressjs 会是这样。