Dados de streaming com node.js
-
23-09-2019 - |
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"> </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?
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.
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.