Block Rockin’ Codes

back with another one of those block rockin' codes

Stream.IO というものを作ってます。

追記

12/5/5
Stream, EventEmitter などを移植して chat サンプル動きました。Jxck's OutPut - Stream.io の example として Stream だけの Chat #nodejs_jp

本文

この記事は、JavaScript Advent Calendar 2011 (Node.js/WebSocketsコース) とは関係ありませんw


ただ、前回そのアドベントカレンダーで書いた Node.js の Stream API で「データの流れ」を扱う方法 - Block Rockin’ Codes で扱った Node.js の Stream API について、そこからも色々考える機会がありました。


その結果、思ってたアイデアがあったので、形にしてみようと思い、ごそごそやり始めました。
(お前、そんなことやってる場合か?という異論は、う、、受け付け、、ごめんなさいorz)

イメージシート

リポジトリ

まだサンプルしかありません。
https://github.com/Jxck/stream.io/

Stream.IO のモチベーション

要するに Web アプリにおける Server と Client を Stream で抽象化してしまおうということです。
すると、リアルタイムなデータのやりとりを、全て pipe() で繋ぐだけでできるようになります。

Client の Stream 化

例えば、サーバでファイルを読み込みながら、それを全てクライアントに WebSocket で送るような場合。
(イメージシートの上段)

  • Server = Readable Stream
  • Client = Writable Stream

的な。

//  server side
var client = stream.io.client();
var stream = fs.createStream(/* ... */);

stream.pipe(client);
// client side
var server = stream.io.server();
var output = $('impliment by jQuery etc..');

server.pipe(output);

これで済むようなイメージ。
クライアントと接続して、 emit(), on('data') していた部分が抽象化されます。

一応さっき作ってみたけど、こんな感じ。
https://github.com/Jxck/stream.io/tree/master/example/logstream
(注: sample.log という大きめのファイルを自分で用意してください。大きかったからコミットしなかった)

Bi-side の Stream 化

これはいわゆる Chat の例です。(イメージシートの下段)

  • Server = Duplex Stream
  • Client = Duplex Stream

かな?

//  server side
var client = stream.io.client();
client.pipe(client);
var server = stream.io.server();
var output = $('impliment by jQuery etc..');
var input = $('impliment by jQuery etc..');

input.pipe(server);
server.pipe(output);


こっちは、後述する理由でまだできていない。
https://github.com/Jxck/stream.io/tree/master/example/chat

MiddleWareFilter

Stream なので、いわゆる Express などで使われていた middleware は、
readable かつ writable な Filter になります。
Filter は API がわかってるので、みんが作って行くでしょう。
それを活用できます。


Stream 経由で読み込んだファイルを、行ごとに直すフィルターがこんな感じ。
https://github.com/Jxck/stream.io/blob/master/example/logstream/readLineFilter.js


これを使うと、ファイルから読み込んでクライアントに流す時、以下のように行単位に出来る。

readable.pipe(readline).pipe(client);

TODO & 課題

まず、 chat の方が出来ていない理由として、

  • ブラウザに Stream がない
  • ブラウザに EventEmitter がない

だけど、 EventEmitter はありました。
https://github.com/Wolfy87/EventEmitter

なので、まずこれを使って、 Stream の移植かな。

あとは、まだまだ思いついただけなので(npm は押さえたけど)、
とりあえずサンプルを作りながら、何が必要かと、
どういう API がいいかを煮詰めて行きたいです。

Stream ベースのリアルタイムアプリケーション

これは、最近自分の中では重要なキーワードです。
Stream.IO は作っている中で得られるものが多そうなので、
まああまりうまくいかなくても、ちょこちょこやって行きたいと思います。
そこで得られたことも、ここに書いていきたいと思います。