Top > HTML5 > WebSocket [全て閉じる]
2012年2月13日

HTML5のWebsocketを使ったお絵かきチャット

February 13,2012 12:03 AM
Tag:[, , ]
Permalink

HTML5のWebsocket(Node.js+Socket.IO)を使って、お絵かきチャットが行えるサンプルを作ってみました。Node.js+Socket.IOについては、下記のエントリーを参照してください。

Windows+Node.js+Socket.IO

環境を作ったのは自分のPCのためリアルでお見せできないのが残念ですが、動画をキャプチャしたのでそちらでご確認ください。

1.サンプル動画

2つのブラウザからそれぞれ「http://127.0.0.1:8124」にアクセスして、チャットを行います。お絵かきの内容をページにアクセスしている別のブラウザに反映します。

下の表示は画面が小さいので、全画面表示にするかYoutubeのサイトで直接見た方がいいかもしれません。

2.サンプルコード

Node.jsとSocket.IOを使ったサンプルコードを掲載しておきます。

色々ネットを探しましたが(探しきれてないかもしれません)、Node.js+Socket.IOでお絵かきチャットを行う適当なコードがみつからなかったので自作しました。Node.jsやSocket.IOに精通されている方にとっては当たり前のような実装かと思います。冗長な部分等ありましたらご指摘ください。

app.js(サーバ側のソース)

var app = require('express').createServer()
  , io = require('socket.io').listen(app);
app.listen(8124);
 
app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});
 
io.sockets.on('connection', function (socket) {
 
    // クライアントからメッセージ受信
    socket.on('clear send', function () {
 
        // 自分以外の全員に送る
        socket.broadcast.emit('clear user');
    });
 
    // クライアントからメッセージ受信
    socket.on('server send', function (msg) {
 
        // 自分以外の全員に送る
        socket.broadcast.emit('send user', msg);
    });
 
    // 切断
    socket.on('disconnect', function () {
        io.sockets.emit('user disconnected');
    });
});

index.html(クライアント側のソース:赤色部分がWebsocket関連の処理)

<!doctype html>
<html>
<head>
<meta charset="utf-8"> 
<title>Canvas</title>
<style>
body {
    margin: 20px;
}
canvas {
    top: 20px;
    left: 20px;
    border: 5px solid #ccc;
}
#button {
    position: relative;
    top: -55px;
    left: 345px;
}
#save {
    font-size: 120%;
    width: 80px;
    height: 50px;
}
#clear {
    font-size: 120%;
    width: 80px;
    height: 50px;
}
ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
li {
    cursor:pointer;
    cursor:hand;
    display:inline-block;
    border: 1px solid #000;
    width: 50px;
    height: 50px;
}
</style>
</head>
<body>
<canvas width="500" height="400"></canvas>
<ul>
<li style="background-color:#000"></li>
<li style="background-color:#f00"></li>
<li style="background-color:#0f0"></li>
<li style="background-color:#00f"></li>
<li style="background-color:#ff0"></li>
<li style="background-color:#fff"></li>
</ul>
<div id="button">
<input type="button" id="save" value="保存" />
<input type="button" id="clear" value="消去" />
</div>
 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
$(function() {
    var offset = 5;
    var fromX;
    var fromY;
    var drawFlag = false;
    var context = $("canvas").get(0).getContext('2d');
    var socket = io.connect('http://localhost');
 
    // サーバからメッセージ受信
    socket.on('send user', function (msg) {
        context.strokeStyle = msg.color;
        context.lineWidth = 2;
        context.beginPath();
        context.moveTo(msg.fx, msg.fy);
        context.lineTo(msg.tx, msg.ty);
        context.stroke();
        context.closePath(); 
    });
 
    socket.on('clear user', function () {
        context.clearRect(0, 0, $('canvas').width(), $('canvas').height());
    });
 
    $('canvas').mousedown(function(e) {
        drawFlag = true;
        fromX = e.pageX - $(this).offset().left - offset;
        fromY = e.pageY - $(this).offset().top - offset;
        return false;  // for chrome
    });
 
    $('canvas').mousemove(function(e) {
        if (drawFlag) {
            draw(e);
        }
    });
 
    $('canvas').on('mouseup', function() {
        drawFlag = false;
    });
 
    $('canvas').on('mouseleave', function() {
        drawFlag = false;
    });
 
    $('li').click(function() {
        context.strokeStyle = $(this).css('background-color');
    });
 
    $('#clear').click(function(e) {
        socket.emit('clear send');
        e.preventDefault();
        context.clearRect(0, 0, $('canvas').width(), $('canvas').height());
    });
 
    function draw(e) {
        var toX = e.pageX - $('canvas').offset().left - offset;
        var toY = e.pageY - $('canvas').offset().top - offset;
        context.lineWidth = 2;
        context.beginPath();
        context.moveTo(fromX, fromY);
        context.lineTo(toX, toY);
        context.stroke();
        context.closePath();
 
        // サーバへメッセージ送信
        socket.emit('server send', { fx:fromX, fy:fromY, tx:toX, ty:toY, color:context.strokeStyle });
        fromX = toX;
        fromY = toY;
    }
 
    $('#save').click(function() {
        var d = $("canvas")[0].toDataURL("image/png");
        d = d.replace("image/png", "image/octet-stream");
        window.open(d,"save");
    });
});
</script>
</body>
</html>

3.サーバへのデータ送信方法

お絵かきはHTML5のcanvasを利用しています。canvasを使ったお絵かきについては「HTML5のcanvasを使ったお絵かきツール詳説」で詳しく解説しているのでそちらを参照してください。サンプルは同じものを使っています。

サーバへお絵かき情報をサーバに送信するのは、マウスで線を引いているときに起動する関数draw()で、socket.emit()を記述します(青色部分)。

クライアント側

function draw(e) {
    var toX = e.pageX - $('canvas').offset().left - offset;
    var toY = e.pageY - $('canvas').offset().top - offset;
    context.lineWidth = 2;
    context.beginPath();
    context.moveTo(fromX, fromY);
    context.lineTo(toX, toY);
    context.stroke();
    context.closePath();
 
    // サーバへメッセージ送信
    socket.emit('server send', { fx:fromX, fy:fromY, tx:toX, ty:toY, color:context.strokeStyle });
    fromX = toX;
    fromY = toY;
}

「emit」は「送信する」という意味の英単語で、サーバ・クライアントどちらでも使えます。赤色は送受信のためのカスタムイベントで、ここでは任意の文字列「server send」を記述しています。

第2パラメータには他のブラウザにお絵かきを反映させるために必要な情報をJSON形式で定義しています。fxは開始地点のX座標、fyは開始地点のY座標、txは終了地点のX座標、tyは終了地点のY座標、colorは線の色です。必要な情報があればここにどんどん追加していけばOKです。

そして、クライアントからのデータを受信できるよう、サーバ側にsocket.on()を記述します。

サーバ側

io.sockets.on('connection', function (socket) {
    socket.on('server send', function (msg) {,
        // 受信メッセージの処理
    });
});

第1パラメータのカスタムイベント名はクライアントで設定したものと一致していなければいけません。ここが一致していないとサーバで受信できません。第2パラメータはデータ受信時の関数を定義します。パラメータ(ここではmsg)には受信時のデータを定義します。

4.クライアントへの送信方法

クライアントへブロードキャストで文字列を送信するには、まず、サーバ側にio.sockets.emit()を記述します(青色部分)。

サーバ側

io.sockets.on('connection', function (socket) {
    socket.on('server send', function (msg) {
        io.sockets.emit('send user', msg);
    });
});

赤色は先程と同様、カスタムイベントで、ここでは任意の文字列「send user」を記述します。第2パラメータにはクライアントから受信したチャットデータ(msg)を設定しています。

そして、サーバからのデータを受信できるよう、クライアント側にsocket.on()を記述します。

クライアント側

// サーバからメッセージ受信
socket.on('send user', function (msg) {
    context.strokeStyle = msg.color;
    context.lineWidth = 2;
    context.beginPath();
    context.moveTo(msg.fx, msg.fy);
    context.lineTo(msg.tx, msg.ty);
    context.stroke();
    context.closePath(); 
});

受け取るクライアントでは、サーバ側のemit()の第1引数(赤色のイベント名)を必ず指定します。ここが一致していないとクライアントで受信できません。第2パラメータはデータ受信時の関数を定義します。

受信後、関数の中で座標位置や配色を変数msgから取得します。JSONデータの取得方法は、例えば開始地点のX座標であれば「msg.fx」と書きます。あとはdraw()と同じ要領でお絵かきデータを表示します。

以上です。サンプルのHTML・CSS・jQueryの説明は割愛しています。

Comments [0] | Trackbacks [0]
2012年1月30日

HTML5のWebsocketを使ってチャットする

January 30,2012 12:03 AM
Tag:[, , ]
Permalink

HTML5のWebsocket(Node.js+Socket.IO)を使って、チャットが行えるサンプルを作ってみました。Node.js+Socket.IOについては、下記のエントリーを参照してください。

Windows+Node.js+Socket.IO

環境を作ったのは自分のPCのためリアルでお見せできないのが残念ですが、動画をキャプチャしたのでそちらでご確認ください。

1.サンプル動画

2つのブラウザからそれぞれ「http://127.0.0.1:8124」にアクセスして、チャットを行います。入力した文字列を送信すると、送信者およびページにアクセスしているブラウザに内容を反映します。

下の表示は画面が小さいので、全画面表示にするかYoutubeのサイトで直接見た方がいいかもしれません。

Websocket Chat Sample

2.サンプルコード

Node.jsとSocket.IOを使ったサンプルコードを掲載しておきます。

色々ネットを探しましたが(探しきれてないかもしれません)、Node.js+Socket.IOでチャットを行う適当なコードがみつからなかったので自作しました。Node.jsやSocket.IOに精通されている方にとっては当たり前のような実装かと思います。冗長な部分等ありましたらご指摘ください。

app.js(サーバ側のソース)

var app = require('express').createServer()
  , io = require('socket.io').listen(app);
app.listen(8124);
 
app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});
 
io.sockets.on('connection', function (socket) {
 
    // クライアントからメッセージ受信
    socket.on('server send', function (msg) {
 
        // ブロードキャストで送信
        io.sockets.emit('send user', msg );
    });
 
    // 切断 
    socket.on('disconnect', function () {
        io.sockets.emit('user disconnected',count);
    });
});

index.html(クライアント側のソース)

<style>
body {
    margin: 20px;
}
p {
    margin: 5px 0;
    padding: 5px 0;
    border-bottom: 1px solid #000;
}
dt{
    margin-top: 5px;
    width: 100px;
    float: left;
    text-align: right;
}
dd{
    margin: 5px 0 5px 100px;
}
input {
    font-size: 100%;
    padding: 5px;
}
#message {
    width: 400px;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
jQuery(function(){
  var socket = io.connect('http://localhost');
 
  // サーバからメッセージ受信
  socket.on('send user', function (msg) {
      jQuery('#chat').prepend('<p>'+msg+'</p>');
  });
  jQuery('input[type=submit]').click(function(){
      var name = jQuery('#name').val();
      var message = jQuery('#message').val();
 
      // サーバへメッセージ送信
      socket.emit('server send', name+':'+message);
  });
});
</script>
<div>
  <dl>
    <dt>名前:</dt><dd><input type="text" id="name"></dd>
    <dt>メッセージ:</dt><dd><input type="text" id="message" size="140" /></dd>
    <dd><input type="submit" value="送信" /></dd>
  </dl>
  <hr />
  <div id="chat"></div>
</div>

3.サーバへのデータ送信方法

サーバへ文字列を送信するには、まず、クライアント側にsocket.emit()を記述します(青色部分)。

クライアント側

jQuery('input[type=submit]').click(function(){
    var name = jQuery('#name').val();
    var message = jQuery('#message').val();
    socket.emit('server send', name+':'+message);
});

「emit」は「送信する」という意味の英単語で、サーバ・クライアントどちらでも使えます。赤色は送受信のためのカスタムイベントで、ここでは任意の文字列「server send」を記述しています。第2パラメータには送信ボタンをクリックしたときのテキストフィールドデータ(チャットの名前と文字列)の関数を定義しています。

そして、クライアントからのデータを受信できるよう、サーバ側にsocket.on()を記述します。

サーバ側

io.sockets.on('connection', function (socket) {
    socket.on('server send', function (msg) {
        // 受信メッセージの処理
    });
});

第1パラメータのカスタムイベント名はクライアントで設定したものと一致していなければいけません。ここが一致していないとサーバで受信できません。第2パラメータはデータ受信時の関数を定義します。パラメータ(ここではmsg)には受信時のデータを定義できます。

4.クライアントへの送信方法

クライアントへブロードキャストで文字列を送信するには、まず、サーバ側にio.sockets.emit()を記述します(青色部分)。

サーバ側

io.sockets.on('connection', function (socket) {
    socket.on('server send', function (msg) {
        io.sockets.emit('send user', msg);
    });
});

赤色は先程と同様、カスタムイベントで、ここでは任意の文字列「send user」を記述します。第2パラメータにはクライアントから受信したチャットデータ(msg)を設定しています。

そして、サーバからのデータを受信できるよう、クライアント側にsocket.on()を記述します。

クライアント側

socket.on('send user', function (msg) {
    jQuery('#chat').prepend('<p>'+msg+'</p>');
});

受け取るクライアントでは、サーバ側のemit()の第1引数(赤色のイベント名)を必ず指定します。ここが一致していないとクライアントで受信できません。第2パラメータはデータ受信時の関数を定義します。パラメータ(ここではmsg)には受信時のデータを定義できます。

受信後、チャットデータ(msg)をjQueryのprepend()を使って表示します。

以上です。サンプルのHTML・CSS・jQueryの説明は割愛しています。

Comments [0] | Trackbacks [0]
2012年1月11日

HTML5のWebsocketを使って同時接続数をサーバから送信する

January 11,2012 2:22 AM
Tag:[, ]
Permalink

HTML5のWebsocket(Node.js+Socket.IO)を使って、現在の同時接続数をサーバから送信するサンプルを作ってみました。

環境を作ったのは自分のPCのためリアルでお見せできないのが残念ですが、動画をキャプチャしたのでそちらでご確認ください。

1.サンプル動画

2つのブラウザからそれぞれ「http://127.0.0.1:8124」にアクセスして、そのページの同時接続数を各ブラウザに表示します。接続数の増減によって、ページに接続しているコネクションすべてに、サーバから情報を送信します。操作をしていないブラウザにも即時に接続数が反映されます。

非常にシンプルなものですが動いたときはちょっと感動しました。

2.サンプルコード

Node.jsとSocket.IOを使ったサンプルコードを掲載しておきます。

色々ネットを探しましたが(探しきれてないかもしれません)、Node.js+Socket.IOで動作するコードがみつからなかったので自作しました。Node.jsやSocket.IOに精通されている方にとっては当たり前のような実装かと思います。冗長な部分等ありましたらご指摘ください。

app.js(サーバ側のソース)

var app = require('express').createServer()
  , io = require('socket.io').listen(app);
 
// カウンタ初期化
var count = 0;
app.listen(8124);
 
app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});
 
io.sockets.on('connection', function (socket) {
 
    // 接続時にカウンタのインクリメント
    count++;
 
    // ブロードキャストで送信
    io.sockets.emit('user connected',count);
 
    // 切断
    socket.on('disconnect', function () {
 
        // カウンタのデクリメント
        count--;
 
        // ブロードキャストで送信
        io.sockets.emit('user disconnected',count);
    });
});

index.html(クライアント側のソース)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
jQuery(function(){
  var socket = io.connect('http://localhost');
 
  // 接続時の動作
  socket.on('user connected', function (data) {
      jQuery('span').html(data);
  });
 
  // 切断時の動作
  socket.on('user disconnected', function (data) {
      jQuery('span').html(data);
  });
});
</script>
<div>このページにアクセスしているのは<span></span>人です。</div>

サンプルコードの配置や起動方法については、Windows限定ですが「Windows+Node.js+Socket.IO」を参照してください。

また、このコードを実行する前に、上記記事の最後に掲載している「npm install socket.io express」を実行してください。

3.クライアントへの送信方法

サーバからブロードキャストで送信するには次のように記述するようです。赤色はイベント名で、任意の文字列を記述します。

io.sockets.emit('user connected', count);

受け取るクライアントでは、サーバ側のemit()の第1引数(赤色のイベント名)を必ず指定します。ここが一致していないと受信できません。第2引数のデータは引数として扱えます。

socket.on('user connected', function (data) {
    // ...
});

サンプルコードはブロードキャストで行ってますが、次のように記述すれば送信先を変更できるようです。

// 自分以外の全員に送る
socket.broadcast.emit('user connected',count);
// 自分だけに送る
socket.emit('user connected', count);

4.参考サイト

参考サイトは下記です。ありがとうございました。

Comments [0] | Trackbacks [0]
Now loading...
Introduction
List of "WebSocket"
Recent Entries
Recent Comments
Recent Trackbacks
QRcode

現在停止中です
携帯電話からこのQRcodeを撮影することで携帯用URLを取得することができます

URI for cellular phones
ギターに入った猫
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site
loading ...
Categories
Monthly Archives
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
Powered by
Movable Type 5.12