2011年10月30日日曜日

Nylonサーバについて

Nylonサーバの役割

Nylonサーバは,あるWebブラウザから送られてきた通信内容を解析して,キーワードに「broadcast」が含まれていた場合には他のWebブラウザに転送する機能と,その他特定のキーワードに対応した処理を行う機能を持つものです.

理論上,言語は問いませんが,Socket.IOが便利なのでJavaScriptで記述するのが自然だと思います.実際,クライアント側の通信モジュール「nylon.coe.js」がSocket.ioを前提として組んでいます.

Nylonサーバのソースコード

以下にNylonサーバのソースコードを示します.できるだけコメントを付けているので,コメントを追いかけていけばなんとなく動作がわかると思います.21行目から31行目がメインの処理(=キーワードの解析・通信内容の転送など)となります.

動かし方

必要なものは,基本的にnode.jsとSocket.IOです.執筆時に使用したバージョンは,node.js 0.4.12とSocket.IO 0.8.5です.他にもexpressやejs(使っていますが,他のテンプレートエンジンでも構いません)も使用しています.

node.jsをインストールしたらディレクトリを作成して,上記プログラム(仮にnylon_server.js)をそのディレクトリに置きます.そのディレクトリの下にpublicディレクトリを作成し,前回紹介したプログラムを置いてください.ディレクトリの作成はexpressの機能を使ってもかまいません.

これで準備は整いました.後はWebブラウザからアクセスするだけで,リアルタイムチャットが動作します.複数のブラウザからアクセスして,動作を体験していただければ幸いです.なお,過去の書き込みの保存などは一切行なっておりません.リロードすると全書き込みがリセットされます.過去の書き込みの保存などを行いたい場合には,上記プログラムの29行目などに処理を追加することで対応可能です.追加するプログラムの例や,追加分のモジュール化などについては,そのうち紹介する予定です.

このエントリーをはてなブックマークに追加

2011年10月28日金曜日

Nylon入門

Nylonによるイベント送受信の流れ

前回はNylonの書き方について簡単に紹介しました.今回は,Webブラウザ間のやりとりについて,実際のコードを踏まえて説明したいと思います.下図のように,nylonサーバに複数のクライアント(Webブラウザ)が接続している状態です.ここで,obj_aは任意のオブジェクトです.COeはnylonサーバと通信するnylonモジュールで,正式なファイル名はnylon.coe.jsです.

Nylonのモジュールは,キーワードに従ってイベントを待つことができます.COeは,「broadcast」と「server」と言うキーワードで待ち受けをして,イベントの内容をnylonサーバに送ります.nylonサーバではキーワードを判別し,「broadcast」だった場合には,送られてきたイベントの内容を他のWebブラウザに送ります.「server」だった場合にはnylonサーバで何らかの処理を行います.続いて,各WebブラウザのCOeは送られてきたイベントを受け取り,ブラウザ内の他のオブジェクトにemitします.

例:リアルタイムチャット

リアルタイムチャットを例にとって説明します.リアルタイムチャットのオブジェクトがobj_aだと思ってください.obj_aはキーワード「append」に反応して書き込み欄に新たな内容を追加し,キーワード「clear」に反応して書き込み欄を消去するものとします.あるブラウザで発言があった場合,obj_aから「broadcast」と「append」という2つのキーワードを持ったイベントを送信します.擬似コードは以下のようになります.

イベントの登録

イベントの送信

実際のコード

リアルタイムチャットの実際のコードは以下のようになります.

6行目から8行目は,必要となるライブラリの読み込みです.サーバとの通信にはSocket.ioを使用しています.nylonサーバのプログラムは後日説明予定です.

22行目から32行目はイベントの登録です.先に説明したとおり,「append」と「clear」と言う2つのキーワードについて,その動作を登録しています

35行目から49行目はイベントの送信処理です.送信ボタンが押されたら名前と発言欄の内容を入れた,キーワード「append|broadcast」のイベントをemit(送信)しつつ,書き込み欄に追加します.

52行目から54行目は,接続した旨を表示するための確認欄の記述です.このプログラムではページ上部の「未接続」が「接続」に変化します.この辺は,格好良いインジケータを配置したいところですね.

その他

書き忘れていましたが,このソースプログラム及びNylonとNylonモジュールは無保証です.動作確認はChrome15.0.874.106,Safari5.1,Firefox7.0.1,iOS5のSafariで行っています

このエントリーをはてなブックマークに追加

2011年10月22日土曜日

Nylon

Nylonとは何か?

MeSHの開発に当たり,すべての機能を盛り込んだシステムとして開発すると,その後の変更作業が地獄と化すことが分かっています.そこで,e-Learningシステムを,個々の機能ごとに分割して開発し,統合する仕組みが必要となりました.その際,単にiframeなどで統合するのではなく,個別の機能を融合しつつ統合する仕組みが望まれました.今回は,その仕組として開発されたNylonについて説明します.

具体的に何が困るのか?

MeSHで目指しているWebによるリアルタイムe-Learningを実現することは,node.jsとsocket.ioのおかげで用意になりました.しかし,全ての機能を盛り込んだシステム(=モノリシックなシステム)を開発すると,機能追加や変更が面倒です.どこにバグが潜んでいるかヒヤヒヤです.

では,リアルタイムe-Learningを実現する機能をバラバラに見ていきましょう.まずは,スライド表示位があります.スライドを表示すると,そこにペンで書き込みしたくなります.そうすると,説明している姿を動画に残して,その動画に合わせてスライドやペンを再現したくなります.または,学生のペンによる書き込みを残しておくとか,「重要」などのマーキングもしたくなります.さらに,シミュレータについてもリアルタイムで操作情報を配信したり,後の自学自習に生かしたくなります.

これらの機能を融合しつつ統合することはできないでしょうか?そこで生まれたのがNylonという考え方です.具体的には,様々なモジュール単位で開発を行いつつ,モジュール間の動作を制御するイベント情報をやり取りするフレームワークです.

EventEmitter

ベースとなるヒントは,node.jsのソースコードに隠されていました.それを発見したのは当時学生だったi君です.どの様な仕組みかと言うと,個々のオブジェクト毎にキーワードとコールバック関数を定義する仕組みです.これにより,イベント駆動型のサーバ記述を実現しています.この仕組はEventEmitterと名付けられています.

EventEmitterをベースに,Webブラウザ上で動作する複数のモジュール間の通信を,共通するイベントマップで制御して,モジュール同士の「ゆるい」結合を実現したのがNylonです.Nylonとは,i君いわく,mesh(網目の織物)を実現するための素材から連想したとのことです.筆者は「モジュール同士を紡ぐ人工的な素材」と再定義しています.
ここで言うモジュールですが,Webブラウザ上で動作するモジュール + Webサーバサイドのモジュール + WebWorkersのモジュール + iframeに読み込まれたモジュール + Webサーバを通じて別のWebブラウザ上で動作するモジュールなどを含みます.

つまり,これまで面倒だった,Webブラウザ間の通信や,WebWorkersのworker側とメイン側の通信などを統一的に扱うことを可能とするフレームワークです.

Nylonの動作イメージ

obj_a, obj_b, guiの3つのオブジェクトがあり,これらが協調動作する様子を簡単に説明します.guiは,Webブラウザ上のボタンなどから制御されるオブジェクトと仮定します.obj_aはイベントとして,"A"を受け取り何らかの処理を行います.同様にobj_bはイベントとして,"B"を受け取り何らかの処理を行います.guiはAボタンが押されたらイベント"A"を送信します.同様にBボタンが押されたらイベント"B"を送信します.さらにCボタンが押されたらイベント"A"とイベント"B"を送信します.(プログラム中では"A|B"と表記)これらの動作を図にすると以下のようになります.
このように,キーワードをイベントとして送受信し合う仕組みがNylonです.この,「キーワードだけで動作する」というゆるい仕組みなので,モジュールのアップデートにも柔軟に対応できます.

Nylonの動作範囲と実際のプログラミング

先の例では,Webブラウザ内のモジュールを連想しますが,実際にはこれらのイベントを中継する仕組みも開発しています.現在のところ,WebWorkersによるworkerとの通信と,Webブラウザ同士の通信が実現されています.つまり,チャット(ピクトチャット含む)やカードゲーム,動画像の同期などに利用することが可能です.

実際のプログラミングで使用するメソッドはたったの2つで,onとemitです.onはキーワードとコールバック関数を定義するメソッドで,emitはキーワードと(必要があれば)パラメータを送信するメソッドです.例えば上の図の状況を定義する場合には以下のような記述となります. たったこれだけの記述でobj_a,obj_b,gui間のイベント処理が実現します.

次に,Webサーバを中継点として,Webブラウザ同士で上記のイベントをやり取りする場合のプログラミングについて説明します.キーワードは「broadcast」です.イベントキーワードに「broadcast」が入っていた場合,Webサーバを通じて同時に接続しているWebブラウザ上のオブジェクトに通知されます.実際には以下のようになります. ボタンが押された際の送信キーワードに「broadcast」を加えるだけで,Webブラウザ同士の通信を実現できます.この場合,接続しているどのWebブラウザ上でも良いのでボタンをクリックすると,各Webブラウザ上の該当する処理が実行されます.言い忘れましたが,キーワードは「|(パイプ記号)」で繋げることで,いくつでも指定できます.

Nylonはhttps://github.com/sudahiroshi/Nylon2で公開中です.
今後,何回かに分けてNylonについて説明していきます. このエントリーをはてなブックマークに追加