Tweet
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
Home > > node.websocket.jsで超適当ホワイトボードアプリ
Home > > node.websocket.jsで超適当ホワイトボードアプリ
Home > html5 > node.websocket.jsで超適当ホワイトボードアプリ
Tweet
今週は仕事とドラクエVIが忙しくて全然勉強の時間がとれませんでした。
(モンスターが仲間に入らないのと難易度が下がってるのにはがっかりしましたが、やっぱり6はいいですね。)
というわけで週末、しかも2日目に慌ててやってみます。
触るのは、引き続きWeb Socket(s)。
前回のでAPI(クライアントサイド。つまりJS。sがつく方)は何となくイメージできたかなぁという感じ。
しかし、プロトコル(Web Socket protocol。こっちはsがつかない)はイマイチ理解できてません。
こういう時はやっぱり手を動かすのが一番ということでとりあえず何か作ってみます。
※ ほんとはパケットキャプチャ取りたかったんですがうまくいかなかったので断念
それでは始めましょう。
まずは参考記事探しから。
Web Socket ProtocolのRFC和訳 - YAMAGUCHI::weblog
ないと思ってたプロトコルの日本語訳がありました。感謝です。
ただこの仕様短いのはいいんだけど、細かい説明が全然ない・・・。
websoket-protcol:ヘッダって何の意味があるんだー。
(node.websokcet.jsではまだ未実装って書いてあるし)
InfoQ: HTML 5 Web Sockets vs. Comet and Ajax
仕様のこととかは詳しく書いてませんがおもしろかったです。
PubSubHubbubとWebSocketsとクライアントサイドのjavascript « ku
こちらも他の実現方法との比較。読みやすいです。
Html5 Web Applications
Html5, Web Applications 2
HTML5のWebアプリ関連仕様をサクっとまとめた素晴らしいプレゼンです。
[追記(2010/1/31 14:15)]
おっと、忘れてた。
HTTP/1.1 から TLS へのアップグレード
Upgrade
HTTPのUpgradeについて。さっぱりわからん。
[/追記]
やっぱまだ日本語のソースは少ないですねぇ。
ネットサーフィンはこれぐらいにして、
うーん・・・Cometアプリの代表例ホワイトボードでも作ってみますか。
というわけで、できたのがこちら。
ソースはいつも通りご自由に。
説明はコメントで。そんな難しいことはやってません。
(セキュリティ0なので間違っても公開しないで下さいね)
うーん、一応思った通りに動いたけど、サーバ側でsetIntervalやるのは綺麗じゃないなー。
このコード量、しかもJSだけでこういうアプリが作れるのはちょっとした衝撃でした。
var Module = this.Module = function(){
// グローバルにしとくと楽
sys = require('sys');
};
Module.prototype.onData = function(data, connection) {
// 初期化
if (data == 'start'){
// 定期的にファイルをcatして変わってたらクライアントに送る
this.interval = setInterval(function(){
var self = this;
sys.exec('cat temp').addCallback(function(stdout, stderr) {
if (self.temp != stdout) {
connection.send(stdout);
}
self.temp = stdout;
});
}, 100);
}
// データを受信したらtempファイルに書き込む(超脆弱!!)
else {
sys.exec('echo "' + data +'" > temp');
}
};
// 後始末
Module.prototype.onDisconnect = function(connection){
clearInterval(this.interval);
};
<!doctype html>
<html>
<head>
<title>whiteboard demo</title>
<style>
canvas {
border: 1px solid black;
position: relative;
}
</style>
</head>
<body>
<h1>whiteboard demo</h1>
<canvas width="300" height="200"></canvas><br />
<input type="button" value="clear" />
<script>
// node.websocket.js/modules/wb.jsに繋ぐ
var webSocket = new WebSocket('ws://localhost:8000/wb');
/* お絵かき処理ここから */
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
var isDraw = false;
var x, y;
canvas.addEventListener('mousedown', function(e) {
ctx.moveTo(x, y);
isDraw = true;
}, 'false');
canvas.addEventListener('mousemove', function(e) {
x = e.layerX;
y = e.layerY;
if (isDraw) {
ctx.lineTo(x, y);
ctx.stroke();
}
}, 'false');
canvas.addEventListener('mouseup', function(e) {
isDraw = false;
webSocket.send(canvas.toDataURL());
}, 'false');
/* お絵かき処理ここまで */
// サーバ側に初期化を知らせる
webSocket.onopen = function(event){
webSocket.send('start');
};
// データ受信時は問答無用でcanvasを更新
webSocket.onmessage = function(event){
var img = new Image();
img.onload = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
};
img.src = event.data;
};
// 白紙に戻す
document.querySelector('input[value=clear]').addEventListener('click', function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
webSocket.send(canvas.toDataURL());
}, 'false');
</script>
</body>
</html>