Потоковая передача данных с Node.js - PullRequest
41 голосов
/ 01 апреля 2010

Я хочу знать, возможно ли передавать данные с сервера на клиент с помощью Node.js. Я хочу отправить одиночный AJAX-запрос в Node.js, затем оставить соединение открытым и непрерывно передавать данные клиенту. Клиент получит этот поток и будет постоянно обновлять страницу.

Обновление:

В качестве обновления этот ответ - Я не могу заставить это работать. response.write не отправляется до того, как вы позвоните close. Я настроил пример программы, которую я использую для достижения этой цели:

Node.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>
    <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>

Используя этот метод, я ничего не получаю, пока не позвоню close(). Возможно ли это, или вместо этого я должен использовать метод длинного опроса, где я снова вызываю функцию загрузки, когда она приходит?

Ответы [ 3 ]

24 голосов
/ 02 апреля 2010

Это возможно. Просто используйте 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();

Возможно, вам придется закрывать и открывать соединение каждые 30 секунд или около того.

РЕДАКТИРОВАТЬ : это код, который я на самом деле тестировал:

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');

Я подключился к нему через Telnet, и он действительно выдает частичный ответ. Но чтобы использовать его в браузере AJAX, он должен поддерживать XHR.readyState = 3 (частичный ответ). Насколько я знаю, не все браузеры поддерживают это. Поэтому лучше использовать длинные опросы (или веб-сокеты для Chrome / Firefox).

EDIT2 : Кроме того, если вы используете nginx в качестве обратного прокси-сервера для Node, он иногда хочет собрать все куски и отправить их пользователю сразу. Вам нужно настроить его.

16 голосов
/ 26 мая 2011

Посмотрите на Sockets.io. Он обеспечивает потоковую передачу HTTP / HTTPS и использует для этого различные транспорты:

  • WebSocket
  • WebSocket over Flash (+ поддержка политики безопасности XML)
  • XHR Polling
  • XHR Multipart Streaming
  • Навсегда Iframe
  • JSONP Polling (для междоменного домена)

И! Работает без проблем с Node.JS. Это также пакет NPM.

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

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

4 голосов
/ 19 февраля 2012

Вы также можете прервать бесконечный цикл:

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);
    }); 
}); 

Это пример expressjs. Я верю, что без expressjs будет что-то вроде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...