swdyh

Node.jsでServer-Sent Eventsを使ってみた

2012-05-29 16:53:00


var util = require('util')
var events = require('events')
var express = require('express')
var redis = require('redis')

var app = express.createServer()
var notifyEmitter = new events.EventEmitter()
var redisClientSubscriber = redis.createClient()
redisClientSubscriber.on('message', function(ch, d) {
    util.log(JSON.stringify(['redisSubscriber', ch, d]))
    notifyEmitter.emit('myevent', 'redis node-sse-example:myevent ' + d)
})
redisClientSubscriber.subscribe('node-sse-example:myevent')

setInterval(function() {
    var len = notifyEmitter.listeners('myevent').length
    util.log(JSON.stringify(['listeners.length', len]))
    if (len > 0) {
        notifyEmitter.emit('myevent', 'interval!')
        util.log(JSON.stringify(['emit myevent']))
    }
}, 10 * 1000)

app.get('/', function(req, res) {
    var r = '<html><head><script>\n'
    var f = function() {
        var es = new EventSource('/sse')
        es.onmessage = function(m) {
            document.body.innerHTML += m.data + new Date() + '<br />'
        }
        es.onerror = function(e) {
            console.log('err:', e)
        }
    }
    r += 'var f = ' + f.toString() + '\n' + 'f()'
    r += '\n</script></head><body><h1>sever sent events test</h1></body></html>'
    res.send(r)
})

app.get('/sse', function(req, res) {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'X-Accel-Buffering': 'no' // disable nginx proxy buffering
    })
    res.write('\n')
    var f = function(d) {
        res.write('data: ' + d + ' \n\n')
    }
    notifyEmitter.on('myevent', f)
    req.on('close', function() {
        notifyEmitter.removeListener('myevent', f)
    })
})
app.listen(9301)
console.log('see http://localhost:9301/')
console.log("publish by redis 'redis-cli publish node-sse-example:myevent foo'\n")


https://gist.github.com/2823050