3

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 come like in chunks.

Pedro Barros
  • 183
  • 1
  • 11
  • checkout websockets. enables two way communication between the browser and client. Most websocket libraries will also give you pub/sub. – Quy Dec 30 '15 at 01:11
  • I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages come like in chunks. – Pedro Barros Dec 30 '15 at 01:49
  • @PedroBarros: If you need to wait a long time and the packets come 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 Dec 30 '15 at 04:38
  • I managed to do it by adding '\n' at the end of the write --' – Pedro Barros Dec 30 '15 at 16:42

3 Answers3

4

You 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 complete 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.

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
1

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.

Community
  • 1
  • 1
John Kossa
  • 459
  • 2
  • 8
1

socket.io or Webrtc is the best choice

Rahul Kamboj
  • 449
  • 3
  • 14