Question

I'm having some difficulties getting a node-express application functioning using iisnode. I have a simple http pub/sub server setup in iis. This receives messages via a POST, and pushes the data to the relevant listening client/s. Code...

Server

var express = require('express');
var app = require('express').createServer();

var clients = {};

app.configure(function(){
    app.use(express.bodyParser());
    app.use(express.methodOverride());
});

app.get('/pubsubleads/leads/:id', function(request, response) {
    var id = request.params.id.toString();

    response.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    clients[id] = response;

    request.on('close', function(){
        console.log('connection closing');
        delete clients[id];
    });
});

app.post('/pubsubleads/leads', function(request, response){
    console.log('New post');

    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.end();

    var id = request.body.id;

    if(clients[id] != null) {
        console.log('id = ' + id);
        console.log('data = ' + request.body.data);

        clients[id].write('id: ' + request.body.id + '\n');
        clients[id].write('data: ' + request.body.data + '\n\n');
    }
});
app.listen(process.env.PORT);
console.log('Server started on port ' + process.env.PORT);

Client

var source = new EventSource('/pubsub/data/@Session.SessionID');

source.onopen = function (e) {
    alert('onopen');
    document.body.innerHTML += 'Connected <br>';
};

source.onmessage = function (e) {
    alert('onmessage: ' + e.data);
    document.body.innerHTML += e.data + '<br/>';
};

source.onerror = function (e) {
    if (e.readyState == EventSource.CLOSED) {
        alert('closed');
    }
};

...where the parameter passed to the EventSource url is something that uniquely identifies this client.

The server and client are hosted on separate sub-domains, under the same root domain. I've confirmed that the server is receiving messages correctly. The problem I have is that the client event handlers are never hit. I have tried wrapping the client code in a $(document).ready() but that had no affect. I've replicated the setup outside of IIS, with a standalone node process, and that works correctly.

I'm using Chrome 18, nodejs 0.6.18, iisnode, IIS 7.5 all on Windows 7 64-bit.

I'm fresh out of ideas, and haven't been able to find any similar issues discussed online. Any help would be appreciated.

Was it helpful?

Solution

By default, IIS caches up to 4MB of response data before flushing, which improves performance in case of short responses and static files. It appears you intend to stream short chunks of data back to the client over time and expect low latency for delivery of these chunks.

iisnode allows you to override this default IIS behavior by forcing the flushing of response data after every write. Please set the system.webServer\iisnode\@flushResponse configuration setting in web.config to true (https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config#L90) to turn this behavior on. Alternatively, if you upgrade to iisnode v0.1.19 or later, you can also set this value using the new iisnode.yml configuration file (see http://tomasz.janczuk.org/2012/05/yaml-configuration-support-in-iisnode.html for details).

OTHER TIPS

EventSource does not have the same client-side API as WebSockets. You need to use addEventListener:

source.addEventListener('open', function (e) {
    // opened
});

source.addEventListener('message', function (e) {
    // e.data
});

source.addEventListener('error', function (e) {
    // whoops
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top