Pergunta

Quero saber se é possível transmitir dados do servidor para o cliente com o Node.js. Quero postar uma única solicitação de Ajax no Node.js, depois deixar a conexão aberta e transmitir contínua dados para o cliente. O cliente receberá esse fluxo e atualizará a página continuamente.

Atualizar:

Como uma atualização para esta resposta - Eu não posso pegar isto para trabalhar. o response.write não é enviado antes de ligar close. Eu configurei um programa de exemplo que eu uso para conseguir isso:

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>

Usando este método, não recuperei nada até ligar close(). Isso é possível ou devo seguir uma abordagem de pesquisa longa, em vez de chamar a função de carga novamente quando se entra?

Foi útil?

Solução

É possível. Apenas use Response.Write() várias vezes.

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

Você pode ter que fechar e reabrir a conexão a cada 30 segundos.

EDITAR: Este é o código que eu realmente testei:

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

Eu me conectei a ele por Telnet e seu de fato distribui uma resposta em pedaços. Mas usá -lo no navegador Ajax deve suportar o xhr.readyState = 3 (resposta parcial). Nem todos os navegadores apóiam isso, até onde eu sei. Portanto, é melhor você usar pesquisas longas (ou WebSockets para Chrome/Firefox).

Edit2: Além disso, se você usar o nginx como proxy reverso para o nó, às vezes deseja reunir todos os pedaços e enviá -lo ao usuário de uma só vez. Você precisa ajustá -lo.

Outras dicas

Olhe para Sockets.io. Ele fornece streaming http/https e usa vários transportes para fazê -lo:

  • WebSocket
  • WebSocket Over Flash (Suporte da Política de Segurança XML)
  • XHR Polling
  • Streaming de multipartramento XHR
  • Para sempre iframe
  • Polling JSONP (para domínio cruzado)

E! Funciona perfeitamente com o Node.js. É também um pacote NPM.

https://github.com/learnboost/socket.io

https://github.com/learnboost/socket.io-node

Você também pode abortar o loop infinito:

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

Este é um exemplo de expressjs. Eu acredito que sem expressjs será algo como.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top