ひよっこ。

I want to…

Posts Tagged ‘javascript’

Meteorで画面遷移を実装する(泥臭い感じ)

Posted by hikaruworld : 2012 9月 12

最近Meteorで遊んでいます。

簡単にプログラムできて楽しいのですが、
Meteorは基本的には画面遷移を持たない構成が前提になっているらしく、
画面遷移を実装するためには少し工夫する必要があります。

Meteorのテンプレート機能にはif文などの制御文を書く事が可能です。
今回はこの制御文とSessionを介したReactiveProggramingモデルを使って、
Sessionに状態を格納して画面遷移を制御します。

index.htmlに以下の様に定義します。

// index.html
<body>
    {{> state}}
</body>

<template name="state">
    {{#if state_is "login"}}{{> login}}{{/if}}     // LOGIN状態の場合
    {{#if state_is "main"}}{{> main{{/if}}       // MAIN状態の場合
</template>

<template name="login">
    <h3>ログイン</h3>
</template>

<template name="main">
    <h3>メイン画面</h3>
</template>

javascriptでstate_isの関数を定義します

// index.js
/** 引数に指定した状態とSessionに格納した状態が同じ場合にtrueを返す */
Template.state.state_is = function(state) {
    return Session.get("STATE") === state;
}

あとは、Sessionに状態を設定すると画面が遷移します。
デベロッパーツールなどのjavascriptコンソールでSession#setで値を設定してみます。

Session.set("STATE", "login");
Session.set("STATE", "main");

ちなみにmeteor.comにデプロイもしてみました。

ちなみにこちらのサイト(英語)が参考になりました。

以上です。

広告

Posted in program | タグ: , | Leave a Comment »

proxy環境でnpm使おうとしたら、Error: socket hang up

Posted by hikaruworld : 2011 10月 27

バージョンはnodeが0.5.10、npmが1.0.101。
OSはVirtualbox上に構築したUbuntu11.10。
nave経由でインストールした、npmでnpm install hogehogeしたらこんなエラーが発生。

hikaruworld@hikaruworld-VirtualBox:/tmp$ npm install express
npm ERR! Error: socket hang up
npm ERR! at createHangUpError (http.js:1083:15)
npm ERR! at CleartextStream. (http.js:1166:27)
npm ERR! at CleartextStream.emit (events.js:88:20)
npm ERR! at Array.0 (tls.js:719:22)
npm ERR! at EventEmitter._tickCallback (node.js:194:26)
npm ERR! Report this *entire* log at:
npm ERR!
npm ERR! or email it to:
npm ERR!
npm ERR!
npm ERR! System Linux 3.0.0-12-generic
npm ERR! command “node” “/home/hikaruworld/.nave/installed/0.5.10/bin/npm” “install” “express”
npm ERR! cwd /tmp
npm ERR! node -v v0.5.10
npm ERR! npm -v 1.0.101
npm ERR! code ECONNRESET
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /tmp/npm-debug.log
npm not ok

ちなみにhttpもhttpsのproxyは設定済み。
wgetやcurl、apt-getが動くことは確認済み。
npm config set proxyもやってある。
/etc/resolve.confも設定されてる。

というわけで半泣きになりながら検索してたら、GoogleGroupで、Node install behind auth proxyという投稿を発見。

一縷の望みをかけて、

npm config set registry http://registry.npmjs.org/

を実行。

無事登録されたみたいなので、再度npm install。

上手くいったョ!。

Posted in program | タグ: , , , , | Leave a Comment »

今更だけどDotcloud上にnode.js環境をデプロイしてみる(1)

Posted by hikaruworld : 2011 7月 27

今更ですが、node.jsを使ってdotcloud0.4上に環境を構築してみました。

ちなみにローカル環境はMacOSX10.6.7(SnowLeopard)です。
この辺りを参考にしていたんですが、6/22にdotcloud0.4がリリースされて
ちょこっと変わったらしく、結局公式ドキュメントを読んでやりました。

1.DotCloudのアカウント登録

何はともあれ、dotcloudにアカウントを登録してAPIKey(あとで必要になります)を取得可能な状態にしておきます。

2. ローカル環境にDotCloudのCLIツールをインストール

DotCloudにログインすると、右上からDashboardやsettingにアクセス可能になります。

このDashboardにアクセスしてみると…
Start deploying by INstalling the CLI.とな。

まだないようです(ー。そのうちGUIが提供されるのでしょう〜。

というわけでリンク先にあるようにDotCloudを操作するために
dotcloudというコマンドをローカルマシンにインストールします。
python製ですので、easy_installなりpipで行うのですが、公式サイトのリファレンスでは

sudo easy_install pip && pip install dotcloud

とのことなのでpipでインストールしておきましょう。

※最初easy_installでインストールしてしまったのですが、
easy_installはアンインストールを手動で行う必要があるので、pipの方が楽チンですョネ。

3. dotcloudのセットアップ

dotcloudのインストールが終わったら、dotcloudコマンドのセットアップを行うために、以下のコマンドを実行します。

dotcloud setup

以下のように聞かれるので、

Enter your api key (You can find it at http://www.dotcloud.com/accounts/settings):

settingsに記述されているAPIKeyを入力します。

このコマンドを実行すると、設定したキー情報が~/.dotcloud以下に格納されます。

.dotcloud/
├── dotcloud.conf
└── dotcloud.key

4. アプリの登録

今回は冒頭にあるようにNode.jsでアプリを作っていきます。
DotCloud上にNode.jsで構築する方法は公式ドキュメントに詳しく書いてあります。

まず、DotCloud上で利用するアプリケーション名を登録します。
このアプリケーション名は自身のアプリケーション内で一意である必要があります。
ここではとりあえずhelloNodeというアプリケーション名にしてみます。
というわけで、以下を実行します。

dotcloud create hellonode

無事作成出来るとこんな感じに出力されます。

Created application “helloNode”

dotcloud上への登録はこれだけです。

5. アプリの作成

次に登録するアプリの実体を作成していきます。
任意のディレクトリを切ってそこで作業します。私の場合は~/programs/dotcloud/helloNodeとしました。

$ mkdir -p ~/programs/dotcloud/helloNode
$ cd ~/programs/dotcloud/helloNode

dotcloud.ymlの作成

次にdotcloud.ymlというビルドファイルを作成します。
これはYAML形式でアーキテクチャやプログラミングコードの設定を行うことが可能です。
今回はDBを利用しないので、こんな感じになります。

www:
    type: nodejs
    approot: helloNode

wwwという風につけたserviceをnodejsのプログラミング言語を使ってルート以下のhelloNode以下に作成するという意味になります。
wwwはあくまでもサービスの名前なので後で変更可能です。
typeは利用するプログラム言語、
approotとは、ルートディレクトリからの指定でこの指定されたディレクトリ以下が設定された対象になります。複数のサービスを定義する場合にはdbやbatchと行った感じで設定を増やすことが可能です。

これをふまえて現在のディレクトリ構造はこんな感じになっています。

helloNode/
├── dotcloud.yml
└── helloNode

supervisord.confの作成

起動用の設定ファイルとしてsupervisord.confを作成します。

$ cd helloNode
$ vim supoervisord.conf

こんな感じでチュートリアルと同じ設定を書いておきます。

[program:node]
command = node server.js
directory = /home/dotcloud/current

commandには実行するnodeコマンドを書きます。
directoryはDotCloud環境上にUPされる場所が/home/dotcloud/currentとのこと(変更可能?)。

server.jsの作成

これは通常のnode.jsのファイルになります。
とりあえずこんな感じに書いておきます

var http = require('http');

var server = http.createServer(function (request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"})
    var output = "Hello World!\n";
    response.end(output);
});

server.listen(8080)

ま、いわゆるHelloWorldですね。
listenしているportは8080ですが、これはセキュリティ上の理由からだそうです。
実際のURLは80でアクセスできるとのこと。

なお、この時点でのディレクトリ構造はこんな感じになっています。

helloNode/
├── dotcloud.yml
└── helloNode/
    ├── server.js
    └── supervisord.conf

6.クラウド環境へのデプロイ

作ったアプリの動作確認をしたら、クラウド環境へのデプロイをpushコマンドで行います。

dotcloud push helloNode ~/programs/dotcloud/helloNode

デプロイ => 起動までが無事完了するとこんなログが流れます。

# upload helloNode/ ssh://dotcloud@uploader.dotcloud.com:21122/hellonode
# rsync
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added ‘[uploader.dotcloud.com]:21122,[XXX.XX.XX.XX]:21122’ (RSA) to the list of known hosts.
building file list … done
./
dotcloud.yml
helloNode/
helloNode/server.js
helloNode/supervisord.conf

sent 594 bytes received 98 bytes 106.46 bytes/sec
total size is 352 speedup is 0.51
Deployment for “hellonode” triggered. Will be available in a few seconds.
2011-07-26 11:27:12 [api] Waiting for the build. (It may take a few minutes)
2011-07-26 11:27:12 [www.0] Deploying…
2011-07-26 11:27:34 [www.0] Service booted
2011-07-26 11:27:34 [api] All the services are ready. Beginning the build.
2011-07-26 11:27:34 [www.0] The build started
2011-07-26 11:27:35 [www.0] Fetched code revision rsync-1311679630.79
2011-07-26 11:27:39 [www.0] node: stopped
2011-07-26 11:27:39 [www.0] node: started
2011-07-26 11:27:39 [www.0] The build finished successfully
2011-07-26 11:27:39 [api] Deploy finished

Deployment finished. Your application is available at the following URLs
www: http://6634c12a.dotcloud.com/

おまけ:ignoreの設定

当然分散バージョン管理使っている訳で、バージョン管理ファイルやデプロイしたくないファイルがある訳ですが、
DotCloudさんはその辺はまだ対応していないようです。
現在これを実現したい場合はGitかHgでバージョン管理を行い、リポジトリからデプロイするようにしなければいけないとのこと。そうした場合gitやhgのignoreを反映してくれるそうです。

bzrは???(涙)…bzr-hgとかbzr-git使えってことですね。はい。

7.動作確認

6.で表示されたURLにアクセスすることで該当環境にアクセスできます。
早速やってみましょう。
http://6634c12a.dotcloud.com/へアクセスします(今はつながりません)。
HelloWorldと表示されました。

8.npmの依存関係解決

node.jsでプログラミングする以上パッケージ管理のnpmは使いたいところです。

DotCloudではnpmの依存関係もpackage.jsonを用意しておくことで自動でダウンロード及び参照してくれます。

ここではexpress(とjade)のテンプレートをdotcloud上で動かしてみます。
なお、expressとjadeは既にグローバルインストール(npm install express -gd)されているものとします。

まずは4.と5.でやったようにアプリを登録して、デプロイ用のディレクトリを作成します。

dotcloud create hexp
mkdir hello-express
cd  hello-express

expressコマンドを使って(パスが通っている前提)、ひな形のアプリケーションを作成します。

express create app

グローバルにインストルしたnpmのモジュールを紐つけます。

npm link express jade

この時点でディレクトリ構成はこんな感じになります。

hello-express/
├── app
│   ├── app.js
│   ├── node_modules
│   │   ├── express -> ~/.nave/installed/0.4.9/lib/node_modules/express
│   │   └── jade -> ~/.nave/installed/0.4.9/lib/node_modules/jade
│   ├── package.json
│   ├── public
│   │   ├── images
│   │   ├── javascripts
│   │   └── stylesheets
│   │       └── style.css
│   └── views
│       ├── index.jade
│       └── layout.jade
└── dotcloud.yml

dotcloud上に必要な設定を書いていきます。
まずはdotcloud.ymlを既存の構成にあわせて書き直します。

www:
  type: nodejs
  approot: app

package.jsonを修正します。
既にテンプレートインストール済みですので、しなくても大丈夫ですが…どうせなのでnameを変更しておきます。

{
    "name": "hello-express"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.4.3"
    , "jade": ">= 0.0.1"
  }
}

app.jsのlistenするポートを変更します。

//app.listen(3000);
app.listen(8080);

app以下にsupervisord.confを作成します。

[program:node]
command = node app.js
directory = /home/dotcloud/current

dotcloud上にデプロイします。

dotcloud push hexp hello-express

長いのでログは省略しますが、一部だけ。

ignoring unsafe symlink “/home/dotcloud/repositories/3/d/1/2/7/13093/hexp/rsync/app/node_modules/express” -> “~/.nave/installed/0.4.9/lib/node_modules/express”

と出ました。シンボリックリンクは無視してくれるみたいです。グッジョブ!

2011-07-26 12:18:39 [www.0] npm info build Success: hello-express@0.0.1
2011-07-26 12:18:39 [www.0] npm info build Success: jade@0.13.0
2011-07-26 12:18:39 [www.0] npm ok

と行った感じでpackage.jsonに書かれている必要なライブラリをビルドしてくれます。

9.その他のコマンド

dotcloudにはその他に便利なコマンドが準備されています。
一部ここで紹介しておきます。

利用可能なコマンドはdotcloud -hと打つことで参照可能です。
ちなみに、これPythonのCmdというパッケージを使って実現しているようです。便利デスヨ。

おまけ:application.service

helpを見ていると頻繁にapplication.serviceという表現が頻繁に出てきます。
これはapplicationはcreateしたアプリ名を指し、
serviceは、dotcloud.ymlに定義したservice名(今回でいえばwww)を指します。
application.serviceという表記は、hexp.wwwというように指定します。

コマンド

setup/create/pushは今まで使ってきましたので省略。

list

createした環境の一覧を表示します。

hexp:
  - www (type: nodejs; instances: 1)

versions

pushでデプロイした際のrsyncのバージョンが表示されます。

- rsync-1311682682.25
- rsync-1311683164.82

run

dotcloud環境上でコマンドを実行します。
たとえばlsだとこんな感じになります。

dotcloud run hexp.www ls

なお、引数を与えたい場合は–を使います

dotcloud run hexp.www ls -- -ls

logs

ログを出力します。実体はtail -Fで/var/log/supervisor/*.log が流れます。

dotcloud run hexp.www ls 

alias

ヘルプを見ると、独自ドメインに紐つけるとのこと。持ってないので未確認

destroy

createで登録したアプリケーションを削除します。

url

デプロイしたアプリケーションのURLを参照します。
うっかり忘れた時用。

info

アプリケーションないしはサービスの情報を参照します。
アプリケーションであればURLやプログラミング言語、インスタンスなど、
サービスであればhttpのアクセスやsshのアクセスのURLなどが参照できます。

status

supervisorctlを通して起動しているサービスの状態が参照可能です。

node RUNNING pid 230, uptime 0:28:42

rollback

???

ssh

該当アプリケーションのサービスにsshでアクセスします

restart

指定したアプリケーションのサービスを再起動します。

参考サイト

以下のサイトがとても参考になりました。
http://docs.dotcloud.com/services/nodejs/
http://d.hatena.ne.jp/replication/20110603/1307026830

以上です。
次はmongodbとつなげてみようと思います。

Posted in program | タグ: , , , | Leave a Comment »

flotで日付のaxis表示がずれて焦るなど

Posted by hikaruworld : 2011 2月 25

jQueryのプラグインflotは便利です。
IEでなければ…ですが。

flotにおいて横軸はoptions.xaxisで整形出来ますが、
これに日付を設定していた場合にちょっとはまったのでメモしておきます。

たとえば、こんな風にミリ秒を与えて、xaxisのmodeを利用して整形しようとします。

var ticksData: [1298300400000, 1298905200000 /*...以下省略 */]

xaxis: {
	mode: "time",
	timeformat: "%m/%d",
	ticks: ticksData,
}

期待する値はは2/22,3/1ですが、
出力される結果は2/21,2/28になってしまいます。

これは日付を整形するflotの実装関数$.plot.formatDateが

getUTCDate()

になっているためでした。

まぁ、ローカル時間で渡していて世界標準時間で取ったらずれたという、よくあるパターン…
というわけで、tickFormatterを自分で定義しておきました。

xaxis: {
	ticks: ticksData,
	// 変換ロジックを定義
	tickFormatter: function (v, axis) {
		var d = new Date(v);
		var r = [];
		r.push(d.getMonth() + 1);
		r.push("/");
		r.push(d.getDate());

		return r.join("");
	}
}	

Posted in program | タグ: , , , | Leave a Comment »

jQueryのグラフライブラリflotをちょっとだけチューニングする

Posted by hikaruworld : 2011 2月 15

jQueryのライブラリの一つでグラフ描画用のライブラリでflotというものがあります。
これを利用しようとして試していたログになります。
ちなみにjQueryのバージョンはGoogleCodeの最新のリビジョン293を利用しました。

とりあえず、1000*10本ほどデータをプロットしてみます。
さくさく動きます(Firefoxで)。データの初期化なども簡単です。
さくさく動きます(GoogleChromeで)。プラグインも導入できるみたいです。

IEはexcanvasが必要との事で、excanvasを読み込んで
IE8で確認してみました。

さくさく動きません(IE8で)…
とりあえず目算だと…

  • Firefox & Chrome -> 1秒未満
  • IE8 ————–> 10秒以上

TODO IE8でプロファイリングして、プロファイリング結果を書く。

直接的なボトルネックはexcanvasが原因のようです…

とりあえず、(出来る範囲で)flotの設定周りからいじっていきます。

その1 影を消す

flotのデフォルト設定ではplotされる線に影の設定がされているので、これを消します。

shadowSize : 0

TODO 時間の差分

その2 plotポイントを変更

flotのplot設定はデフォルトではarc(円)になっているのでこれを、fill(四角)に変更します。
symbolで任意のcallback関数を指定する事でplotされる点をカスタマイズできます。

var options = {
	lines: { show: true },
	points: { 
		show: true,
		symbol: function(ctx, x, y, radius, shadow) {
			ctx.fillRect(x, y, 1, 1);
			//ctx.lineTo(x, y); ラインという方法もあり?
		}
	}
},

その3 plotポイントを削除

長方形でも遅いので、pointsを消します

var options = {
	lines: { show: true },
	points: { 
		show: false,
	}
},

# これちょっと悲しすぎる気が…

これで大体1/2の早さになりましたが、まだまだです。

その4 lineを消す

var options = {
	lines: { show: false },
	points: { 
		show: false,
	}
},

意味なし。既にグラフではありません。

# え?、ChromeFrameを使えって?、FlashCanvasを使えって?
# それが出来るならFlexで書きますよ、はい。

TODO 差分ロードが出来ないか検証
TODO Flot及びexcanvasをチューニング出来ないか検討

Posted in program | タグ: , , | Leave a Comment »

SNBinderを試すなど

Posted by hikaruworld : 2011 2月 4

ちょっと仕事でJSのテンプレートエンジンが欲しくなって、探していたら、
Life is beautifulの方がSNBinderを出していたので、
ちょっと触ってみてた。

詳細は本人が言及されているリンクが詳しい。

んで、いくつかハマったことを。

SNBinder.bind_rowsetで色々書きだしていたんだけど、
配列の書き出し方がわからず困った。

indexは$(index)でいけるみたいなんだけど(README参照)、

$(index) will be replaced by the index (in case or bind_rowset)

サーバからは配列で送ってしまったので、そもそもkeyがない。
# いや、それJSONの仕様的におかしいだろと言われるのは重々承知です、はい。

実際どうやってるんだろうなぁとソースを見てたら、192行目辺り(ver0.53)にevalしているコードを発見。

        compile: function(htm) {
            var _templatize = function(htm) {
                return '"' + htm.replace(/\"/g, "'")
                                .replace(/[\r\n]/g, " ")
                                .replace(/\$\(index\)/g, '"+index+"')
                                .replace(/\$\(\.([a-z0-9_\.]*)\)/gi, '"+SNBinder.escape(""+row.$1)+"')
                                .replace(/\$\(\_([a-z0-9_\.]*)\)/gi, '"+row.$1+"')
                                +'"';
            }; // "
            var _func;
            eval("_func = function(row, index) { return (" + _templatize(htm) + "); };");
            return _func;
        },

なるほど、テンプレートの変数をここで置換しているらしいですね。
内部ではrowで行数を持ちまわってぽいのでちょっと修正してみた。

        compile: function(htm) {
            var _templatize = function(htm) {
                return '"' + htm.replace(/\"/g, "'")
                                .replace(/[\r\n]/g, " ")
                                .replace(/\$\(row\.\)/g, '"+SNBinder.escape(""+row)+"')
                                .replace(/\$\(row\)/g, '"+row+"')
                                .replace(/\$\(index\)/g, '"+index+"')
                                .replace(/\$\(\.([a-z0-9_\.]*)\)/gi, '"+SNBinder.escape(""+row.$1)+"')
                                .replace(/\$\(\_([a-z0-9_\.]*)\)/gi, '"+row.$1+"')
                                +'"';
            }; // "
            var _func;
            eval("_func = function(row, index) { return (" + _templatize(htm) + "); };");
            return _func;
        },

うまくいったっぽい。あんまり細かくは試してないけども。
escapeは制御したかったので、.は後ろ付で。

あと、SNBinder.ajaxしたら、Acceptが*/*で送られてて、サーバ側ではじいた自分のコードが
あって、一瞬焦ったりしました。

テンプレートの入れ子とかもしようと試してたんだけど、上手くいかなかった。
やり方まずかったのかもしれないけど、時間切れデス。

キャッシュとログイン周りも確認しておきたいところ。

全体的にシンプルで使いやすいので仕事で使ってみようかなと思ってたりします。

# SNBinderのSNってイニシャルなんだろうか…ちょっと気になる。

Posted in program | タグ: , | Leave a Comment »