読者です 読者をやめる 読者になる 読者になる

Node.js用データ通信ライブラリを公開しました

Node.js用データ通信ライブラリを公開しました

段々使える感じになってきたので、自宅でシコシコと開発しているNode.js用ライブラリ「Tikitaka」をGitHub 上に公開し、npmモジュールとして登録しました。

このライブラリは、サーバー(Node.js)・クライアント(ブラウザ)上のオブジェクトやファンクションを、接続対象のクライアント・サーバから、 あたかもローカルにあるかのように 操作できるようにしてくれる、國村隼さん並に激渋なライブラリです。

例えば、こんなことができます。

  • サーバ(Node.js)側スクリプト
function DBSample(){};
DBSample.prototype.get = function(key, client_func) {
    // keyからvalueを得る"db.get"というものがあるものとして・・・
    db.get(key,function(val) {
        client_func(val); // クライアントから受け取ったfunction(のスタブ)呼び出し
    });
}
  • クライアント(ブラウザ)側スクリプト
var dbsamp = new DBSample();
dbsamp.get(1, function(v){
    alert(v + 'だぞ'); // DBから受け取った値が出るはず!
});

動作するブラウザ等の情報は、GitHubの方に間違いだらけの英語で記載していますので、そちらを参照ください。

  • GitHub

https://github.com/osajiru/tikitaka

で、どんな感じで使うの?

インストール

まずは、こんな感じでお手軽かつお気軽にインストールしてください。

npm install tikitaka

サーバ側準備

httpサーバの準備

Tikitakaは、websocketを使用してクライアントと通信します。 websocketにはhttp接続が必要になりますので、Node.jsのhttpモジュールを使用して、httpサーバを隆々とした感じにおっ立ててください。

// sample
var http = require('http');
var fs = require('fs');

var sv = http.createServer(function(req,res) {
    if (req.url=='/') {
        fs.readFile('index.html', function(err, data) 
        {
            res.end(data);
        });
    }
}).listen(8000, function(){});

クライアントに公開するモジュールの準備

クライアントに公開する(接続の起点となる)モジュールを準備します。

コンストラクタ(?)functionとprototypeの構成でnewして使う形態にしてください。 namespaceの形のものは、tikitakaは両腕を組んで断固拒否するでしょう。

// sample

// これ、おれ、動く
function Dog() {}

Dog.prototype.calc = function( arr, callback ) {
    var v = 0, r = '';
    for ( var i in arr ) {
        v += arr[i];
    }
    for ( var i=0; i<v; i++ ) {
        r += 'ワン!! ';
    }
    callback(r);
}


// この形はウゴカナーイ
var Chimp = {
    calc : function( arr, callback ) {
        callback('ワタシニホンゴワカリマセン');
    }
};

初期化

Tikitakaに下記をパラメータとして与えて初期化します。

  • httpモジュール
  • 公開するライブラリ

初期化の段階で、こいつは内部にwebsocketサーバを立ち上げます。そこんとこシクヨロでお願いいたします。

// 先頭に
var tikitaka = require('tikitaka');

// どこでもいいんで、httpモジュールのインスタンスが受け取れる場所で
tikitaka.init(http, {Dog:Dog /* , Cat:Cat...."クライアント側公開名:実体"*/ });

クライアント側tikitakaモジュールの準備

Tikitakaは、initに渡された情報を基にクライアント用javascriptを生成します。 そいつを、人の道に反する手段を使ってでも何しても構いませんので、なんとかしてクライアントに渡してください。 こんな感じで

var sv = http.createServer(function(req,res) {
    if (req.url=='/test.js') {
        res.end(tikitaka.getScript()); // tikitakaからスクリプト文字列を受け取ってresponseとして送信
    } 
    ...

サーバ側は以上!

クライアント側準備

TikitakaクライアントJavaScriptの読み込み

Tikitakaが生成したjavascript(サーバ側でtikitaka.getScript()で受け取ったもの)を、こっそりと受け取ってください。 たとえば

<script src='/test.js'></script>

使いまくる

window.addEventListener('load', function() {
    var dog,
        arr = [1,2,3];
    dog = new Dog();
    dog.calc(arr, function(a){alert(a); });
});

以上!

備考

非同期です!

このライブラリで生成されたモジュールは、非同期でやりとりを行います。 よって、返り値は受け取れません。 通信対象から結果を受け取るには、コールバックfunctionをパラメータとして設定し、呼び出し先からそのfunctionを呼び出してもらう形にする必要があります。(いつもの非同期処理の記載でOKです)

// NG
var a = svobj.func(); // サーバ側の返り値は受け取れません

// OK
svobj.func(func(v) {
   // v:サーバから受け取った値
});
非同期で動くなら、newしてすぐにそのメンバをよんじゃだめなんじゃないの?

このライブラリには、newしてから通信対象から生成通知がくるまでの間に呼ばれたメンバをキューイングして、生成通知がきたときに順時実行する仕組みが含まれています。ですので、newについては、同期処理のような記載で問題ありません。

``` // こうしなくてよい。というか動かない var a = new SvObj( function() { a.test(); });

// これ、ワシ、動く a = new SvObj(); a.test();

受け取ったオブジェクトの変更は反映されません!

パラメータとしてobjectを渡すことはできますが、そのメンバを変更しても、相手側には反映されません。

// クライアント
var svobj = new SvObj();
var o = {
    a : 1, // こいつを2にしたい!
    b : function(v) {
       this.a = v;
    }
};
svobj.func(o)
// サーバ
function SvObj(){}
SvObj.prototype.func = function(obj) {
    console.log(obj.a); // 1と出力される
    obj.a = 2; // クライアントには反映されない
    obj.b(2); // これなら反映される
}

おわりに

使っていただける方は、恐る恐る使っていただけると幸いです。 そして、動かなかった情報(オブラートに包んだ感じの表現で)、こうしたほうがよい情報(特にセキュリティ的な部分で)等をフィードバックしていただけると、ボクの弛んだ表情筋にスイッチが入ります。

© 2009-2017 Osajiru All Rights Reserved.