とあるサーバ管理者 & PG & SEのメモ帳

2011-12-05

HTML5でサーバプッシュ(Node.jsとWebSocket)

HTML5 Advent Calendar2011の6日目。

私がHTML5の中で最も注目しているWebSocketについて書きます。

今更説明するまでもないのですが、WebSocketはHTML5で実装されたサーバプッシュを

「簡単に」実現させることができます。

サーバプッシュと言うくらいなので、当然サーバ側の仕組みが必要で、

WebSocketサーバを実現するライブラリが世の中には既にかなりありますが、

なんといってもNode.jsを使ったNode WebSocket Serverがお手軽で、

クライアントサイドと同じJavaScriptで書けるのが素敵。


とまぁ、能書きはいいので、簡単なサンプルを。

Node.jsインストールこちら辺りを参考にどぞ。

Node WebSocket Serevrはnpmコマンドでインストールします。

#> npm install websocket-server

これでカレントディレクトリのnode_modules/以下にインストールされる。

ではまずクライアント側から。

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>ニュース速報</title>
<script type="text/javascript">
window.onload = function() {
	//WebSocketオープン
	socket = new WebSocket("ws://192.168.12.50:10080");
	socket.onmessage = function(event) {
		document.getElementById('news').innerHTML = event.data;
	}
}
</script>
</head>
<body>
ニュース受信中:<div id="news"></div>
</body>
</html>

IPアドレスは適当に自分の環境に合わせて書き換えてください。

またポート番号は10080にしていますが、これも自分の環境に合わせて。

当然WebSocketサーバ側でListenするポート番号と一致している必要があります。

このサンプルはサーバプッシュされてきた文字列を単に表示させているだけ。

次にサーバ側。

先ほどのnode_modules/ というディレクトリと同階層にこのjsファイルを設置します。

newsServer.js

var sys = require("util");
var fs = require("fs");
var ws = require("websocket-server");
var server = ws.createServer();

server.addListener("connection", function(connection){
	var client_id = connection.id;
	sys.log("Connected->"+client_id);
	readFile();

	fs.watchFile('./news.dat',readFile);
});

function readFile(curr,prev) {
	fs.readFile('./news.dat','UTF-8', function(err,data) {
		sys.log("news->"+data);
		server.broadcast(data);	
	});
}

server.listen(10080);

このjsファイルと同じ階層にnews.datというファイルを作成し、

このファイル内にテキストで適当にニュースなりメッセージなり書いておきます。

#> echo "This is first news." > news.dat

準備ができたらWebSocketサーバを起動しておきます。コマンドラインから、

#> node newsServer.js
node newsServer.js

で起動。


ブラウザでindex.htmlを開きます。

WebSocketに対応するブラウザwikipedia:WebSocketを参照。

ただMacChromeだとうまく動かない。WinChromeは不明。

Opera11なら(設定すれば)動作可。SafariWinでもMacでもOK。

iPhone/iPadでも可。Androidは不可。

ブラウザで開くと、サーバ側のコンソールには、

5 Dec 23:44:47 - Connected->3942536650
5 Dec 23:44:57 - news->This is first news.

なんて出ます。This is first news.ってのがnews.datの中身。

クライアント側のブラウザには

ニュース受信中:
This is first news.

となってるはず。

で、news.datを書き換える。

echo "second news" > news.dat

するとこの内容がクライアント側にほぼ瞬時に伝わることが分かるでしょう。

まぁこれはあくまでもサンプルなので何の実用性もないけども、例えばnews.datではなく

ニュースの内容をDBに登録しておき、最新ニュースがDBに登録されたら

クライアントサーバプッシュしたり、野球サッカーの試合速報、チャット

対戦型ゲーム、オークションサイトでの応札状況、株価、ショッピングサイトでのタイムセール、etc・・・

将来的には緊急地震速報サーバプッシュで配信するのもありかも(※今は安定性や対応ブラウザが少ない)。


注:ここから宣伝。

今月末に、小生が執筆したHTML5を使ったスマートフォン向けWebアプリ制作の本が

秀和システムから発刊されることになりました。

その中でこのNode.js+Web Socket Serverを使ったサンプルアプリを紹介していますので、

興味のある方はよろしければどうぞ。

注:ここまで宣伝乙。

と、まぁ応用範囲はアイディア次第で無限なWebSocketに、今後も期待大、というお話でした。

2011-11-09

上梓しました

今更な感じもするが、9月末にPHP本を上梓しました。

一人で書いたのでなく4人の共同執筆ですが一応。

PHP逆引き大全 516の極意

PHP逆引き大全 516の極意


現在2冊目の校正の真っ最中。


死にそう(苦笑)

2011-11-07

VMware Fusion上のXWindowで勝手にCAPS LOCKになってしまう件

意外とネット上で解決策が見つからなかったので自分用メモ。

自分はCentOSだが恐らく他のLinuxディストリビューションでも同様だと思われる。(XWindow環境での話だから)

※少なくとも手元のFedoraでも同様だった

原因はMacの「英数」キーがCAPS LOCKに割り振られてしまうため。

決して勝手にCAPS LOCKされてしまうのではなく、英数キーがCAPS LOCKに割り振られているためで、

入力中に無意識に英数キーを押しているのでCAPS LOCKになってしまう。

要はFusionのキーマップが悪いのだけど、プラスMacで日本語キーボードを使ってるから発生する問題。

US配列キーボード使っていればこれは発生しない(はず)。


ってことで、解決方法としてはXWindowのキーマップを書き換えてしまう。

英数キーのKeycodeは66で、それがCaps Lockにバインドされているために起こる。

つまりKeycode66を他のキーに割り当ててしまえばいい。

自分の場合は無変換に割り当ててしまった。


vi ~/.XModmap

keycode 66 = Muhenkan

clear Lock


これで一端ログアウトしてからログイン

英数キーを押してもCAPS LOCKされないことを確認。


ちなみに同じ方法でかなキーで日本語入力Onにすることもできる(はず)。

かなキーのkeycodeは208。

自分の場合はLinux上で日本語入力することが無いのでSCIMすらいれてないので

試しようがないが・・・。

2011-09-15

Parallels仮想環境上のCentOS Apache で静的ファイルがレスポンスされない

あまりこの問題でブチ当たる人はいないと思うけど・・・


MacOSX上のParallels DesktopでLinuxCentOS)をゲストOSとして起動、

開発環境でApacheを使っている場合の話。


静的なファイル(JPGとかJavaScriptとか)へのリクエストが帰って来ず、ブラウザが真っ白になる。

(レスポンスデータが0byte)。同環境でVMware Fusionだと問題ない。

ApacheのDocumentRootは、ParallelsMac上のディレクトリを共有。


結論からいうと、このホストOS上のディレクトリをゲストOSが共有して、ApahceのDocumentRootとしている場合。

Parallelsの場合はParallels ToolというのをゲストOS作成時にインストールするのだが、

これがLinuxカーネルの一部を書き換えてる模様(Toolインストール時にkernel sourceのパッケージを要求される)。

これが悪さして、Apacheクライアントに素早くレスポンスするためにOSに対して発行するSendfile syscallが

動作しないらしい。


解決策はここ。

http://httpd.apache.org/docs/2.0/faq/error.html

Sendfileをディレクティブでoffにしろ、と。


<Directory>ディレクティブで

EnableSendFile Off

としてApache再起動


これで動作しました。改めてググると、VirtualBoxでも同様らしい。

今までVMware Fusion3使ってて、Fusion4の出来の悪さに嫌気がさしてPara7に移行したんだけど・・・・

環境の移行って簡単にやるとこういうことでハマるというお話。

2011-03-20

Xcode4

そろそろ1年前から構想を練ってるiPhoneアプリでもつくるか・・・・

と思ったら、Xcodeが4になってた。

そーいえば、ちょっと前にメールきてたな、と思いつつ

4GBものファイルを落としてインストール

ちょっ・・・これ・・・・。

InterfaceBuilderがXcodeに統合され、最近のAppleの流行りのUIになってた。

24インチiMacならいいけど、これじゃノートで開発するのはまず無理だろ・・・。

で、何がどこにあるのかさっぱり分からん。

3.xに戻そうか。いや、でもこれからはこっちに慣れないと・・と格闘すること2時間。

・・・・ウインドのタイトルバーを消すプロパティがどうしても見つからん。

そんなことに2時間もかかったことに呆然としながら、今日はもう寝よう。

Xcode4の使い方ガイドってどっかにないかなー。