var sys = require('sys'), http = require('http'), fs = require('fs'), auth = "************************", // "ユーザ名:パスワード" を Base64 したもの queue = new process.EventEmitter(), // イベント通知用 backlog = [], maxlogs = 100, port = 5000; var main = function() { http.createServer(handle_request).listen(port); var client = http.createClient(80, "chirpstream.twitter.com"); var request = client.request( 'GET', '/2b/user.json', { 'Host': 'chirpstream.twitter.com', 'Authorization': auth } // とりあえず Basic 認証 ); request.addListener('response', function (response) { sys.puts('STATUS: ' + response.statusCode); sys.puts('HEADERS: ' + JSON.stringify(response.headers)); response.setEncoding('utf8'); response.addListener('data', read_chunked(queue_writer)); }); request.end(); }; var queue_writer = function(input) { if (queue.listeners("message").length) { // listener がいたらイベント通知 queue.emit("message", input); } else { // いなければ backlog に積んでおく while ( backlog.length > maxlogs ) { backlog.shift(); } backlog.push(input); } }; // バッファリングして改行ごとに writer に渡す var read_chunked = function( writer ) { var buf = ""; return function(chunk) { if (chunk.match(/\n/)) { var chunks = chunk.split(/\r?\n/); writer( buf + chunks.shift() ); if (chunks.length) { buf = chunks.pop(); } var c = "" while ( c = chunks.shift() ) { writer(c); } return; } buf += chunk; } }; // HTTP server のリクエストハンドラ var handle_request = function (request, response) { if (request.url == "/") { // ファイルを読み込んで返す response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); var file = fs.createReadStream("./client.html"); file.addListener('data', function(data) { response.write(data) }); file.addListener('end', function(chunk) { response.end() }); } else if (request.url == "/stream") { var send_response = function(msg) { response.writeHead(200, {'Content-Type': 'application/json'}); response.end(msg); }; if (backlog.length) { // backlogがたまってたらそれを返す send_response(backlog.shift()); } else { // イベント通知を待つ listener を作って callback で返す var listener = function(msg) { send_response(msg); queue.removeListener("message", listener); }; queue.addListener("message", listener); } } else { response.writeHead(404, {'Content-Type': 'text/plain'}); response.end("Not Found\n"); } }; main();