I was trying to implement a NODE JS get method where I could encode in the url parameters and send back responses like in Server Sent Events. For example, when I used:
curl -D- 'http://localhost:8030/update'
The server would return a message, and then keep the connection opened to return more messages (like Push). I was using require('connect'), I tried with require('express') but can't get it working.
Here's part of my code:
var http = require('http');
var connect = require('express');
var app = connect();
app.use(bodyParser.urlencoded({ extended: false }))
.use(bodyParser.json()) // JSON
.use(cors(corsOpts))
.get('/update', updateMiddleware);
var server = http.createServer(app);
server.listen("twserver.alunos.dcc.fc.up.pt", 8030);
function updateMiddleware(req, res) {
res.setHeader('Connection', 'keep-alive');
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.writeHead(200);
setTimeout(function() {
res.write("this is an event");
res.flushHeaders();
}, 1000);
setTimeout(function() {
res.write("this is another event");
}, 2000);
// should print without ending
}
EDIT: I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages e like in chunks.
I was trying to implement a NODE JS get method where I could encode in the url parameters and send back responses like in Server Sent Events. For example, when I used:
curl -D- 'http://localhost:8030/update'
The server would return a message, and then keep the connection opened to return more messages (like Push). I was using require('connect'), I tried with require('express') but can't get it working.
Here's part of my code:
var http = require('http');
var connect = require('express');
var app = connect();
app.use(bodyParser.urlencoded({ extended: false }))
.use(bodyParser.json()) // JSON
.use(cors(corsOpts))
.get('/update', updateMiddleware);
var server = http.createServer(app);
server.listen("twserver.alunos.dcc.fc.up.pt", 8030);
function updateMiddleware(req, res) {
res.setHeader('Connection', 'keep-alive');
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.writeHead(200);
setTimeout(function() {
res.write("this is an event");
res.flushHeaders();
}, 1000);
setTimeout(function() {
res.write("this is another event");
}, 2000);
// should print without ending
}
EDIT: I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages e like in chunks.
Share Improve this question edited Jan 4, 2016 at 0:42 Pedro Barros asked Dec 30, 2015 at 1:01 Pedro BarrosPedro Barros 1831 silver badge12 bronze badges 4- checkout websockets. enables two way munication between the browser and client. Most websocket libraries will also give you pub/sub. – Quy Commented Dec 30, 2015 at 1:11
- I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages e like in chunks. – Pedro Barros Commented Dec 30, 2015 at 1:49
- @PedroBarros: If you need to wait a long time and the packets e in chunks then you're encountering the Nagle algorithm which was designed to improve throughput of TCP/IP traffic by not wasting time sending small packets. A simple work-around is to flush after each write. – slebetman Commented Dec 30, 2015 at 4:38
- I managed to do it by adding '\n' at the end of the write --' – Pedro Barros Commented Dec 30, 2015 at 16:42
3 Answers
Reset to default 4You can't use a single HTTP request to listen for multiple event data. If you are really stuck with HTTP (i.e. WebSocket or WebRTC is not an option) then the technique you are looking for is called long polling. This basically works this way:
- Client sends request to server
- Server waits until an event happens (or until a specific but not too long timeout, so the client application does not throw a timeout error for the request)
- Server responses with a plete http response, containing the details of the event
- Client receives the event details and immediately sends another request to listen to further events.
This method really takes advantage of HTTP Keep-Alive
EDIT:
For me it looks like your code does not follow the protocol of server sent events. Here is a tutorial: Server-Sent Events in nodejs.
Following another tutorial on MDN about Server-Sent Events, the structure of the messages should be the following:
: this is a test stream
data: some text
data: another message
data: with two lines
Note that the data to be sent must be followed by a double new-line \n\n
.
In general, http endpoints in Express aren't supposed to do things like that. If you want live event data, the best way is to use a web socket.
That being said, this thread has an example on how to force Express to do this.
socket.io or Webrtc is the best choice