前回のエントリでsoket.ioにだいたい慣れたので、次は以前作ったEaselJSのスタディを少しいじって、soket.ioでつなぎタッチの可視化共有してみた。
今回作ってみた物を以下に置いておく。ただVPSサーバーの構成変更を行う予定なので、いつまでこの形でおいておくかは分からない。
できればiPhoneとmacとかiPhoneとiPadとかで見ていただけると、一方のタッチがリアルタイムに伝わる様が見えるだろう。もちろんブラウザウィンドウ2枚立ち上げでも何が起きるか把握できる。
EaselJSのスタディ02がタップやドラッグを使用していてsoket.ioで共有してみるサンプルとしては適切だろうということで、これをベースに少し表現を変えて作成をしていくこととした。
スタディ02の構成からsoket.ioで伝えるイベントはonMouseDownと、マウス押し状態でのonMouseMoveの2つにする。
このイベントで得られるポイントを、どの画角で見ても大丈夫なように横幅からの割合、縦幅からの割合にして、socket.emitで運ばれるオブジェクトに格納する。
以上の方針より、サーバー側は以下のようなスクリプトになった。
var sys = require('util'), express = require('express'), app = express.createServer(); app.configure(function(){ app.use(express.static(__dirname+'/views')); }); app.listen(8888); var io = require('socket.io').listen(app); //var socket = io.listen(app); io.sockets.on('connection', function(socket){ console.log('接続id ; '+socket.id); //connectOK(); socket.emit('message', '接続しました' ); socket.on('mouseclick', function(mouse){ console.log('mouseclick id ; '+socket.id + ' x ='+mouse.x+' y ='+mouse.y); var mouseObj = {id:socket.id,mouse:mouse}; //io.sockets.emit('mousemove',{value:mouseObj}); socket.broadcast.emit('mouseclick',mouseObj); }); socket.on('mousemove', function(mouse){ console.log('mousemove id ; '+socket.id + ' x ='+mouse.x+' y ='+mouse.y); var mouseObj = {id:socket.id,mouse:mouse}; //io.sockets.emit('mousemove',{value:mouseObj}); socket.broadcast.emit('mousemove',mouseObj); }); socket.on('disconnect', function(){ console.log('disconnect;;;;'+socket.id); io.sockets.emit('userdisconnected',socket.id); }); });
クライアント側はスタディ02をベースにsocket接続を入れた形なのでJSのメイン部分だけを示すことにする。
html側でsocket.ioのクライアント側スクリプトをロードしておき、キャンバス制御や通信はcotouch.jsに書くようにする。
<script src="/socket.io/socket.io.js"></script> <script src="js/cotouch.js"></script>
cotouch.js内部の初期化し、ソケットからの情報を受け取る部分はこうしている。
easel_main.addCirclesで、模様を描いている。
data.mouse.x,data.mouse.yは横幅内、縦幅内の比になっているのでcanvas.widthやcanvas.heightを掛けて位置を決めている。
function initSocket() { var socket = io.connect('http://localhost:8888/'); socket.on('message', function(t) { console.log('mes; ' + t); }); socket.on('mouseclick', function(data) { console.log('mouseclick; ' + data.mouse.x); easel_main.addCircles(Math.random() * 4 + 4, data.mouse.x * canvas.width, data.mouse.y * canvas.height, 1); }); socket.on('mousemove', function(data) { console.log('mousemove; ' + data.mouse.x); easel_main.addCircles(Math.random() * 2 + 2, data.mouse.x * canvas.width, data.mouse.y * canvas.height, 0.5); }); socket.on('userdisconnected', function(id) { console.log('userdisconnected; ' + id); }); return socket; }
マウスクリックやタッチで、ソケットへ情報を送る部分はこのような形にした。
同じくthat.addCirclesで、模様を描いている、thatになっているのは同じオブジェクト内だからだ。そして、ステージ内での位置情報はcanvas.width,canvas.heightで割って比に直している。
var mouseClick = function(evt) { //log("mouseClick",evt); that.addCircles(Math.random() * 10 + 10, evt.stageX, evt.stageY, 2); mysocket.emit('mouseclick', { x : evt.stageX / canvas.width, y : evt.stageY / canvas.height }); evt.target.onMouseMove = function(ev) { that.addCircles(Math.random() * 5 + 5, ev.stageX, ev.stageY, 1); mysocket.emit('mousemove', { x : ev.stageX / canvas.width, y : ev.stageY / canvas.height }); //log("onMouseMove",ev); } evt.target.onMouseUp = function(ev) { //log("onMouseUp",ev); evt.target.onMouseMove = null; evt.target.mouseUP = null; } }
クライアント側は、これ以外にも色々と入っているがsoket.io通信に関する部分はたったのこれだけ、それでタッチの共有ができてしまった。
デプロイするにあたりngixでサーバーというのはちょっとおおげさだったので、foreverでデーモン化することにした。
だけどforeverには問題があり、
$ forever list
で起動中のnodeアプリケーションを見ようとすると、
`forever list` shows no jobs while they exist
となってしまう。OSX、CentOS両方共だ。
調べてみると、githubのフォーラムでも全く同じ症状の方達が沢山おり、しょうがないので終了はコマンドでKILLすることにした。
soket.ioは随分と楽に面白いものができて、可能性を十分に感じさせてくれるた。
今回のものだとピアノのような音が出ると素敵だと感じる。タッチ系は音との連動があると楽しそうだ。
oAuthでTwitter/Facebook認証をしてアイコンとかtweetとかで遊んでみたり、みんなでお絵かきや塗り絵アプリみたいなのを作ってみたりしてみたくなる。