node.js+socket.ioでライブコーディング的なものを作るメモ

node.jsでchatアプリっぽいもの作るメモに引き続き、第2弾。
socket.ioを使って、あるtextareaで編集した内容を出来るだけリアルタイムに別のページに反映させるもの、を作ってみた。誰かがライブでtextareaで書いているコードをwebからみんなが見られる、的な。
https://github.com/sugyan/node-socket-sample にコード置いておきます。
サーバー側jsはこんなカンジで。

var express = require('express');
var app = express.createServer();
var ejs = require('ejs');
var io  = require('socket.io');

var port = 3000;
app.set('view engine', 'ejs');
app.set('view options', { layout: false });
app.set('views', __dirname + '/views');

app.get('/editor', function(req, res) {
    console.log('/editor');
    res.render('editor', { locals: { port: port } });
});
app.get('/viewer', function(req, res) {
    console.log('/viewer');
    res.render('viewer', { locals: { port: port } });
});
app.listen(port);

var socket = io.listen(app);
socket.on('connection', function(client) {
    client.on('message', function(msg) {
        client.broadcast(msg);
    });
    client.on('disconnect', function() {
        console.log('disconnect');
    });
});

console.log('Server running at http://127.0.0.1:' + port + '/');

editorページとviewerページを用意。httpのポートだけ任意に変えられるようにしています。
socket.ioは、「editorからのみmessageが来る」「viewerからはmessage受け取らずに送るだけ」という前提で、送信されてくるものをbroadcastするだけ。
で、"views/editor.ejs"

<html>
  <head>
    <title>editor</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.4.4");</script>
    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script type="text/javascript">
$(function() {
    var socket = new io.Socket(null, { port: <%= port %> });
    socket.connect();
    socket.on('connect', function() {
        console.log('connect');
    });
    socket.on('disconnect', function(){
        console.log('disconnect');
    });

    var code_prev = $('#code').val();
    var loop = function() {
        var code = $('#code').val();
        if (code_prev != code) {
            socket.send(code);
            code_prev = code;
        }
        setTimeout(loop, 100);
    };
    loop();
});
    </script>
    <style type="text/css">
textarea#code {
    width: 500px;
    height: 200px;
}
    </style>
  </head>
  <body>
    <textarea id="code"></textarea>
  </body>
</html>

100msごとにtextareaの内容をチェックし、前回チェックしたときから変更されていればsocketにsendします。差分だけとりだして、とかやろうとすると面倒なのでとりあえず内容をすべて丸投げ。
"views/viewer.ejs"では

<html>
  <head>
    <title>viewer</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.4.4");</script>
    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script type="text/javascript">
$(function() {
    var socket = new io.Socket(null, { port: <%= port %> });
    socket.connect();
    socket.on('connect', function() {
        console.log('connect');
    });
    socket.on('disconnect', function() {
        console.log('disconnect');
    });
    socket.on('message', function(msg) {
        $('#code').text(msg);
    });
});
    </script>
  </head>
  <body>
    <pre id="code" />
  </body>
</html>

socketから送られて来たものをそのまま反映するだけ。


これで、起動して片方では"/viewer"を開きつつ、別窓から"/editor"を開いてtextareaを編集すると…

結構リアルタイムに編集内容が反映されます。たのしい。
しばらくは
http://www1216u.sakura.ne.jp:3000/viewer
http://www1216u.sakura.ne.jp:3000/editor
で動かしておきますので壊さない程度に遊んでみて下さい。session管理とかしていないので色んな人がeditor側を弄ると大変なことになりそうだけど…w