Tuppari入門中。Tuppariでchatを作ってみました。

@hakoberaさん謹製のTuppariを使ってchatを作ってみました。
Tuppari de chat
yosuke-furukawa/tuppari-de-chat · GitHub

Tuppariというのは、東京Node学園で紹介されたPusherのクローンで、WebSocket通信用に作られたサービスです。

Tuppariの詳細はhakoberaさんのこちらのエントリを参考にしてください。
Tuppari - WebSocket on Your Cloud - - Scalaとlift のはずだった ・・・

node.js版ですごく簡単にできました。せっかくなので、作るまでにやったことをまとめてみます。

tuppariインストールからアカウント作成まではこちらを読んでください。

node.js + express + tuppari作成


前準備


expressからサンプル・アプリケーションを作成してください。

$ express tuppari-de-chat

依存関係&tuppari インストール

$ cd tuppari-de-chat
$ npm install
$ npm install validator
$ npm install tuppari

app.js修正


tuppariを使えるようにします。app.js側は本当に簡単で、20〜30行位追加しただけでTuppariに送信できました。

app.js

/**
 * Module dependencies.
 */

var express = require('express')
, routes = require('./routes')
, http = require('http')
, Tuppari = require('tuppari')
, keys = require('./keys')
, sanitize = require('validator').sanitize;
var app = express();

var tuppari = new Tuppari(keys);
//これでchannel作成とchannelへの参加を実施。
var channel = tuppari.join('chat');

app.configure(function(){
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler());
});

app.get('/', routes.index);

app.get('/chat', function(req, res){
    var message = sanitize(req.query.message).entityEncode();
    if (message) {
        //メッセージを送信。
        channel.send('your_event', message, function (err, res, body) {
            if (err) {
                console.error(err);
            }
            if (res) {
                console.log(res.statusCode, body);
            } else {
                console.error("no response.");
            }
        });
    }
    res.json(null);
});

http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});


keys.js作成


keys.jsにTuppariのアプリケーションID等を入れておきます。

keys.js

module.exports = {
  applicationId: process.env.TUPPARI_APPLICATION_ID,
  accessKeyId: process.env.TUPPARI_ACCESS_KEY_ID,
  accessSecretKey: process.env.TUPPARI_ACCESS_SECRET_KEY
};

あとでherokuにアップする際にはインストール時に得られたアプリケーションID等をprocess.envに入れてください。

$ heroku config:add TUPPARI_APPLICATION_ID=xxxxxx
$ heroku config:add TUPPARI_ACCESS_KEY_ID=yyyyyy
$ heroku config:add TUPPARI_ACCESS_SECRET_KEY=zzzzzz

ローカルで実行する場合は以下のようにして実行します。

$ export TUPPARI_APPLICATION_ID=xxxxxx
$ export TUPPARI_ACCESS_KEY_ID=yyyyyy
$ export TUPPARI_ACCESS_SECRET_KEY=zzzzzz

この方法の方がスマートかも。

クライアント側


tuppariのAPPLICATION_IDを持つクライアントを作成し、app.jsで登録した'chat' channelをsubscribeします。
chat.js

function chat() {
    var message = $('#message').val();
    console.log(message);
    $.ajax({
        url: "/chat",
        data: {message: message},
        async: false,
        success: function(data){
            $("#message").val('');
            //do nothing.
        }
    });
    $('#form').submit(function() {
        return false; 
    });
}
var client = tuppari.createClient({
    applicationId: '6545f512-301b-4951-b36f-a750716cb3a1' // Replace this with your Application ID.
});
var channel = client.subscribe('chat');
channel.bind('your_event', function (data) {
    var date = new Date();
    $('#list').prepend($('<dt>' + date + '</dt><dd>' + data + '</dd>'));
});

あとはindex.jadeやlayout.jadeなんかはこんな感じです。
index.jade

extends layout

block content
  h1= title
  form(id='form')
    input(type='text', name='message', id='message')
    button(type='submit', onClick="chat();") chat
  hr
  dl(id='list')

layout.jade

doctype 5
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    script(type='text/javascript', src='http://cdn.tuppari.com/0.1.0/tuppari.js') 
    script(type='text/javascript', src='/javascripts/jquery-1.7.min.js') 
    script(type='text/javascript', src='/javascripts/chat.js') 
  body
    block content

使ってみた感じの感想


簡単に使える良い感じのライブラリですね。
クライアントへのpush通知はこれでいいんじゃないかな、という気になります。
Fluentdとかと連携したりして、リアルタイムにリソース監視とか夢が広がります。
ハッカソンもあるので、もう少し入門してみます。