nodejs+SSEを試してみる

仕事でログを可視化したいんですけど、どうせならリアルタイムで処理したいなと思いまして、ちょろちょろ調べていると、SSE使ったら良いらしいと言うので試してみました。本当はsinatraを使いたかったのですけど、SSEと組み合わせるのが面倒そうだったので、素直にnodejsにしました。

クライアントからはEventSourceオブジェクト作ってonmessageをフックするだけなので、WebSocketでガチャガチャするのに比べたら、コードが超シンプルで良いですね。

// sse.js
var http = require("http");
var fs = require("fs");

http.createServer(
    function(req, res) {
        console.log(req.url);
        if (req.headers.accept && req.headers.accept == 'text/event-stream') {
            if (req.url == '/events') {
                res.writeHead(200, {
                    'Content-Type': 'text/event-stream',
                    'Cache-Control': 'no-cache',
                    'Connection': 'keep-alive'
                });
                
                setInterval(function() {
                    var d = new Date();
                    res.write('id: ' + d.getTime() + '\n');
                    res.write('data: ' + d + '\n\n');
                }, 2000);
            }
        }
        else {
            res.writeHead(200, {'Content-Type':'text/html'});
            res.write(fs.readFileSync('index.html'));
            res.end();
        }
    }
).listen(8888);
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      window.onload = function() {
          var source = new EventSource('/events');
          source.onmessage = function(evt) {
              document.body.innerHTML += evt.data + '<br />';
          }
      }
    </script>
  </head>
  <body>
  </body>
</html>

ちなみに上記サンプルを走らせている間に、ngrepで中身を覗くと下記の出力が得られました。idとdataのチャンクを交互に送っているだけですね。一応ストリームの仕様はこの辺で見れます。

$ ngrep -W byline -q -d lo0 '' port 8888
...
T 127.0.0.1:8888 -> 127.0.0.1:54344 [AP]
HTTP/1.1 200 OK.
Content-Type: text/event-stream.
Cache-Control: no-cache.
Connection: keep-alive.
Date: Wed, 14 May 2014 03:08:42 GMT.
Transfer-Encoding: chunked.
.
12.
id: 1400036924400
.


T 127.0.0.1:8888 -> 127.0.0.1:54344 [AP]
2f.
data: Tue May 13 2014 23:08:44 GMT-0400 (EDT)

.


T 127.0.0.1:8888 -> 127.0.0.1:54344 [AP]
12.
id: 1400036926406
.


T 127.0.0.1:8888 -> 127.0.0.1:54344 [AP]
2f.
data: Tue May 13 2014 23:08:46 GMT-0400 (EDT)

.

何となくSSEの雰囲気がつかめました。これは色々使えそうですね。

Leave a Reply

Your email address will not be published. Required fields are marked *