Потоковая передача данных с Node.js
-
23-09-2019 - |
Вопрос
Я хочу знать, возможно ли передавать данные с сервера клиенту с помощью 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"> </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()
.Возможно ли это или я должен вместо этого использовать метод длительного опроса, при котором я снова вызываю функцию загрузки по мере ее поступления?
Решение
Это вполне возможно.Просто используй ответ.напишите() несколько раз.
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 (частичный ответ).Насколько я знаю, не все браузеры поддерживают это.Так что вам лучше использовать длинный опрос (или Websockets для Chrome / Firefox).
РЕДАКТИРОВАТЬ 2:Кроме того, если вы используете nginx в качестве обратного прокси-сервера для узла, иногда ему хочется собрать все фрагменты и отправить их пользователю сразу.Вам нужно это подправить.
Другие советы
Посмотрите на Sockets.io.Он обеспечивает потоковую передачу по протоколу HTTP / HTTPS и использует для этого различные транспортные средства:
- Веб - кошелек
- WebSocket поверх Flash (+ поддержка политики безопасности XML)
- Опрос XHR
- Многосоставная потоковая передача XHR
- Вечный Iframe
- Опрос JSONP (для междоменных пользователей)
И!Это легко работает с Node.JS.Это также пакет NPM.
Вы также можете прервать бесконечный цикл:
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 будет что-то вроде.