gist

2012年1月25日水曜日

socket.ioでマウスの動きを共有しよう(sessionの識別)

前回のエントリーで作ったアプリでは、一つのマウスをみんなで共有してしまうため、同時にマウスを動かすと何がなんだか。

今回はブラウザのセッションごとにそれぞれマウスを持たせてみます。

app.js


/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')

var app = module.exports = express.createServer();

var io = require('socket.io').listen(app);
io.set('log level', 1); 

// Configuration

app.configure(function(){
  app.set('views', __dirname   '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(require('stylus').middleware({ src: __dirname   '/public' }));
  app.use(app.router);
  app.use(express.static(__dirname   '/public'));
});

// Routes

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

app.listen(3000);


var map = {}; // セッションIDをキーとした自動生成したUUIDの連想配列

io.sockets.on('connection', function(socket) {

    // 接続されたらUUIDを生成し、セッションIDをキーとして連想配列mapに保存する。
    map[socket.id ''] = (function(){
        var S4 = function() {
            return (((1 Math.random())*0x10000)|0).toString(16).substring(1);
        }   
        return (S4() S4() "-" S4() "-" S4() "-" S4() "-" S4() S4() S4());
    })();

    socket.on('mousemove', function(mouse) {
        // 座標と一緒にUUIDをブロードキャストする
        socket.broadcast.json.volatile.send({
            x:mouse.x, 
            y:mouse.y, 
            id:map[socket.id '']
        });
    });

    socket.on('disconnect', function() {
        // 切断したらセッションIDを連想配列から削除する。
        map[socket.id ''] = null;
        delete map[socket.id ''];
        // 削除されたUUIDをブロードキャストする。イベント名はremovemouse。
        socket.broadcast.json.volatile.emit('removemouse',{
            id: map[socket.id '']
        });
    });
});

console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

クライアント側を実装していきます。(そろそろ分離せにゃ)

views/layout.jade

!!!
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    // マウスのスタイル(赤丸)
    style
        div.point {
            position: fixed;
            width: 8px;
            height: 8px;
            background-color: #f00;
            border-radius: 8px;
        }
    script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' ,type='text/javascript')
    script(src='/socket.io/socket.io.js' ,type='text/javascript')
    // 連想配列points にUUIDをキーとして、マウスとなる要素を入れています。
    // mousemoveでUUIDキーのマウス座標を動かします。
    // removemouseイベントでUUIDキーで連想配列から削除されます。
    script(type='text/javascript')
        $(document).ready(function() {
            var points = {};

            var socket = io.connect();
            socket.on('message', function(mouse) {
                console.log(mouse.id);
    
                var $point = points[mouse.id];
                if(!$point){
                    $point = $('<div/>')
                    .attr('id', mouse.id)
                    .addClass('point')
                    .appendTo('body');
    
                    points[mouse.id] = $point;
                }
            
                $point.css({
                    'left':mouse.x,
                    'top':mouse.y,
                });
            });
        
            socket.on('removemouse', function(mouse){
                points[mouse.id] = null;
                delete points[mouse.id];
            });

            $(document).mousemove(function(event) {
                $('#point').css({
                    'left':event.pageX   'px',
                    'top':event.pageY   'px'
                });
                socket.emit('mousemove', {x:event.pageX, y:event.pageY});
            });

        });
  body!= body

views/index.jade

h1= title   
p Welcome to #{title}
#point(class='point')

実行してみます。

$ node app.js 
   info  - socket.io started
Express server listening on port 3000 in development mode

実行結果

色が同じだとサッパリわからないですね。次回は色を変えてみます。F5押し続けるとマウスが減らなかったり若干あやしいです。disconnect周り。一定時間でセッションIDを切るようにするといいかもしれません。

0 件のコメント: