はじめての共同作業 Canvas編 (node.js + websocket)
こんにちは、中川です。
先月無事に結婚をした開発者が一名おり、近年アシアルでは徐々に既婚者が増えてきている状況です。
ということで、結婚といえば共同作業ですよね。
今までは、一人で作業していて大変なことが色々あったと思いますが、
二人(複数)でやれば、乗り越えられることもあることでしょう。
Webアプリでも最近は、より共同作業がしやすい環境ができつつあるように思います。
そこで、今回はWebSocketを使ったリアルタイム通信でのやり取りを行い、
一緒にお絵描きができるサンプルアプリを作ってみました。

■■■概要■■■
・アプリ概要
・・Canvas + WebSocket
・対応ブラウザ
・・Chrome or Safari (他、WebSocketが使えるブラウザ)
・サーバ側プログラム
・・node.js 0.2.0
・・express@1.0.0rc2
・・websocket-server@1.3.50
※express, websocket-server は node.js のパッケージ管理システムの npm ( http://github.com/isaacs/npm ) でインストールしました。
node.js用のwebsocketサーバは何個かあるみたいですが
( 参照: http://github.com/ry/node/wiki/modules )、
今回は、比較的更新もされていて、手軽に利用できそうな node-websocket-server を使ってみました。
■■■アプリ構成■■■
プログラム一式ダウンロード:canvas-share.tar.gz
■■■プログラム内容■■■
・index.html
・js/client.js
※通信部分関連のみ抜粋
WebSocketが有効な場合は、マウスの移動座標と色をサーバに通知するようにし、また、受信したJSONデータからCanvasへの描画処理を行います。
・server.js
expressは、単純に静的ファイル(html,js)を出力しているだけですので、今回は特に必要性はありませんが、プログラム記述の楽がしたかっただけです。
WebSocketサーバ側の処理では、投げられたjson文字列データをログ配列に保持し、そのまま broadcast で接続中のクライアントに返すようにしています。
■■■動作確認■■■
サーバを起動します。
あとは、対応ブラウザを複数ウィンドウ立ち上げて、それぞれ
http: //example.com:3333/ にアクセスすれば動作します。

■■■最後に■■■
今回の実装はかなりやっつけな部分もありますがご容赦いただければと思います。
現行のIEやFirefoxなど主要ブラウザがまだWebSocketに対応していませんが、socket.io などのライブラリもあるようですので、対応させることもできそうです。
node.jsを利用すれば、phpでは難しい大量の同時接続をさばくこともできますので、このようなリアルタイムコラボレーション系のWebアプリも簡単につくることができそうですね。
今後も色々と試していきたいと思います。
先月無事に結婚をした開発者が一名おり、近年アシアルでは徐々に既婚者が増えてきている状況です。
ということで、結婚といえば共同作業ですよね。
今までは、一人で作業していて大変なことが色々あったと思いますが、
二人(複数)でやれば、乗り越えられることもあることでしょう。
Webアプリでも最近は、より共同作業がしやすい環境ができつつあるように思います。
そこで、今回はWebSocketを使ったリアルタイム通信でのやり取りを行い、
一緒にお絵描きができるサンプルアプリを作ってみました。
■■■概要■■■
・アプリ概要
・・Canvas + WebSocket
・対応ブラウザ
・・Chrome or Safari (他、WebSocketが使えるブラウザ)
・サーバ側プログラム
・・node.js 0.2.0
・・express@1.0.0rc2
・・websocket-server@1.3.50
※express, websocket-server は node.js のパッケージ管理システムの npm ( http://github.com/isaacs/npm ) でインストールしました。
node.js用のwebsocketサーバは何個かあるみたいですが
( 参照: http://github.com/ry/node/wiki/modules )、
今回は、比較的更新もされていて、手軽に利用できそうな node-websocket-server を使ってみました。
■■■アプリ構成■■■
- .
- `--
canvas-share |-- public | |-- index.html | `-- js | `-- client.js `-- server.js
プログラム一式ダウンロード:canvas-share.tar.gz
■■■プログラム内容■■■
・index.html
- <!DOCTYPE
html> - <html>
- <head>
<meta charset="UTF-8"> <title>Canvas Share Demo</title> - </head>
- <body>
<canvas id="layer0" class="canvas" style="position: absolute; top: 0; left: 0; border: 10px solid #dddddd;" width="900px" height="600px"></canvas> <input type="button" id="clear" value="Clear" style="position:absolute;" /> - <script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript" charset="utf-8"></script> - <script
type="text/javascript" src="/js/client.js?t=1149"></script> - <script
type="text/javascript"> - $(function(){
var painter = new Painter('layer0'); // WebSocket対応の場合は、コネクションを設定 if (window["WebSocket"]) { var conn = new WebSocket("ws://" + document.location.host + "/"); painter.setConnection(conn); } else { alert('This browser is not supported.'); } $('#clear').click(function() { painter.clear(); }); - });
- </script>
- </body>
- </html>
・js/client.js
※通信部分関連のみ抜粋
- /**
* マウス移動時の処理 */ Painter.prototype.move = function(event) { if (!this.isDrawing) { return; } var points = { bx: this.beforeX, by: this.beforeY, ax: event.clientX - 10, ay: event.clientY - 10, c: this.strokeStyle }; if (this.conn) { // 各座標をjson形式でサーバに通知 this.conn.send(JSON.stringify(points)); } else { this.drawLine(points); } this.beforeX = points.ax; this.beforeY = points.ay; }; /** * キャンバスのクリア処理 */ Painter.prototype.clear = function(conn) { if (this.conn) { // CLEAR処理をサーバに通知 this.conn.send('@CLEAR'); } else { this.clearCanvas(); } }; /** * WebSocketのコネクション設定 */ Painter.prototype.setConnection = function(conn) { this.conn = conn; this.conn.onclose = function() {console.log('Close');}; this.conn.onopen = function(){console.log('Connected');} var self = this; //メッセージ受信時の処理(クリアと描画) this.conn.onmessage = function(event) { if (event.data.indexOf('@') > -1) { if (event.data.indexOf('@CLEAR') > -1) { self.clearCanvas(); } } else { var d = JSON.parse(event.data); self.drawLine(d); } }; };
WebSocketが有効な場合は、マウスの移動座標と色をサーバに通知するようにし、また、受信したJSONデータからCanvasへの描画処理を行います。
・server.js
- var
sys = require("sys"), ws = require('websocket-server'); - /**
* web-server */ - var
express = require('express'); - var
app = express.createServer(); - app.configure(function(){
// ファイルをそのまま出力するディレクトリの設定 app.use(express.staticProvider(__dirname + '/public')); - });
- /**
* websocket-server */ - //var
json = JSON.stringify; - var
server = ws.createServer({server: app}); - var
points = []; - server.addListener("listening",
function(){ sys.log("Listening for connections."); - });
- server.addListener("connection",
function(conn){ sys.log('Hello'); //server.broadcast("@HELLO"); // 全てのログを初回接続時に送信 if (points.length > 0) { for(var i in points) { conn.send(points[i]); } } // メッセージ受信処理 conn.addListener("message", function(message){ if (message.indexOf('@') > -1) { points = []; server.broadcast(message); } else { points.push(message); server.broadcast(message); } }); - });
- server.addListener("close",
function(conn){ //server.broadcast("@BYE"); - });
- server.listen(3333);
expressは、単純に静的ファイル(html,js)を出力しているだけですので、今回は特に必要性はありませんが、プログラム記述の楽がしたかっただけです。
WebSocketサーバ側の処理では、投げられたjson文字列データをログ配列に保持し、そのまま broadcast で接続中のクライアントに返すようにしています。
■■■動作確認■■■
サーバを起動します。
- $
cd canvas-share/ - $
node server.js
あとは、対応ブラウザを複数ウィンドウ立ち上げて、それぞれ
http: //example.com:3333/ にアクセスすれば動作します。
■■■最後に■■■
今回の実装はかなりやっつけな部分もありますがご容赦いただければと思います。
現行のIEやFirefoxなど主要ブラウザがまだWebSocketに対応していませんが、socket.io などのライブラリもあるようですので、対応させることもできそうです。
node.jsを利用すれば、phpでは難しい大量の同時接続をさばくこともできますので、このようなリアルタイムコラボレーション系のWebアプリも簡単につくることができそうですね。
今後も色々と試していきたいと思います。
トラックバックURI
-
- ServersMan@VPSでExpress+node.js+sequelizeを試してみる from はるかなる熊
- 前回の「ServersMan@VPSでnode.jsを試してみる」に続いて、今度はnode.jsのSinatr...
2011年03月19日 10:50
最近の記事
システム開発エンジニア募集! [2012年02月03日 : 小林有佳]
OpenVPNで細々便利な設定 [2012年01月31日 : 門脇優児]
【iOS】Viewの開発・デバッグに役立つ色々 [2012年01月23日 : 中川善樹]
PHPDocumentorの利用方法まとめ [2012年01月19日 : 笹亀弘]
Google Chart Toolsを使ってサイトマップを描こう! [2011年12月21日 : 志田仁美]
stumpwm設定v2 [2011年12月19日 : 門脇優児]
Mashup Awards 7の授賞式が行われました [2011年12月16日 : 中川善樹]
社員旅行に行きました [2011年12月12日 : 大橋寛子]
iCloud風のアイコンを作成する(Fireworks) [2011年12月07日 : 和田記光]
iScroll4でネイティブに近いスマホ向けHTMLページを作成する [2011年12月02日 : 松田惇]













コメントフォーム