ラベル javascript の投稿を表示しています。 すべての投稿を表示
ラベル javascript の投稿を表示しています。 すべての投稿を表示

2011年11月18日金曜日

実験くん(jQueryでグラフィカルEC2コンソール)

前回の記事でEC2まわりの構成の視覚化をしましたが、今回はさらに発展させてEC2まわりのサービスの結合をしてみました。



やったことは
  • EC2、SGに加え、ELB、EBSのサービスを追加しました
  • サービスはDrag&Dropで移動できます
  • 移動した位置はCookieで記憶しています 
  • 各サービスの中見出しはアコーディオンです 
  • 参照だけではなく、実際のサービス接続を操作できます 
  • EC2とELB,EBSの間は未使用端点からのDrag&Dropで結合ができます 
  • コネクタをダブルクリックするとサービス結合を切断します
などです。

今回ソースは長いので割愛して、実際に操作したところをスクリーンキャストで紹介したいと思います。


vimeoのサイトで直接みるとHD画質で再生できます。

AWS Plug by jQuery
http://vimeo.com/32302745

思った以上に構成がわかりやすくなり、操作も直感的にできたかと思います。
もっといじったら面白い事になりそうです。

本日は以上です。

2011年11月10日木曜日

実験くん(jsPlumbでAWSの構成を可視化)

jsPlumbという、HTMLのエレメント同士をコネクタで接続できるライブラリがあります。

このライブラリはjQueryのプラグインとしてもリリースしているので、これを使用してEC2とセキュリティグループの関係を接続図としてHTMLレンダリングするように実験してみました。 


EC2とセキュリティグループの情報をjsonで出力するPHPを以下のように用意します。


jsPlumbはGoogleCodeでホストされているので、以下からダウンロードします。

jsPlumb
http://code.google.com/p/jsplumb/downloads/list

次に、htmlページを用意し、phpからjsonを取得し、jsplumbに適用させます。

これだけで終わりです。

さっそく実行してみます。

おおー!
うまく表示されました!

はぐれセキュリティグループが一目でわかりますね。


jsplumbはjQueryUI.Draggableをサポートしているので、コネクタで接続されたエンドポイント(ノード)はドラッグで移動することも出来ます。



ELBの接続状況など、いろいろなことが可視化できそうです。

以上です。

2011年10月20日木曜日

WebSocketってなんじゃ?(Node編4 MongoDBってなんじゃ?)

今回はMongoDBの話題です。
MongoDBはいわゆるNoSQLで、BSONというJSONのバイナリ版のような形式でデータの入出力を行い、クエリなどのデータ操作をjavascriptで行うため、サーバーサイドJavascriptと非常に相性がよく、node.jsとともによく利用されているようです。

今回はこのMongoDBをnode.jsから操作してみます。

MongoDB公式サイトにあるように、yumでインストールするために、MongoDB用のyumリポジトリを追加します。
以下のファイルを作成します。
/etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686
gpgcheck=0


さっそく、yumでインストールします。
yum install mongo-10gen mongo-10gen-server -y


インストールが終了したら、mongodが/etc/init.d/以下にできるので、起動します。
/etc/init.d/mongod start


MongoDBのコンソールを立ち上げてみます。
$ mongo

MongoDB shell version: 2.0.0
connecting to: test
testというdbにつながったようです。
helpと入力すると、いくつかのコマンドが紹介されています。DBの一覧を見てみます。
> show dbs
local (empty)
test (empty)
localとtestというDBがあり、中身はまだ空になっています。

MongoDBは基本的にはスキーマを定義することなく、いきなりデータを保存できます。データが保存された時点でそれがスキーマになります。
以下のように、hogeというデータを保存、その直後にhogeを参照してみます。
> db.hoge.save({id:"1", name:"HOGE"});
>
> db.hoge.find();
{ "_id" : ObjectId("4e9f8ced316d58abc218dc43"), "id" : "1", "name" : "HOGE" }

このように、クエリにあたるものもすべてjavascriptで行い、結果はJSON形式で表示されます。いかにもnodeと相性がよさそうです。


それでは、このMongoDBにnode.jsからアクセスしてみます。
node.jsからMongoDBにアクセスするには、MongoDB用のパッケージモジュールを入れる必要があります。
Mongo用のモジュールはいくつかあるのですが、今回はMongooseを利用してみます。
mongooseはnpmでインストールします。
# npm install -g mongoose

> mongodb@0.9.6-22 install /usr/local/lib/node_modules/mongoose/node_modules/mongodb
> bash ./install.sh

================================================================================
=                                                                              =
=  To install with C++ bson parser do <npm --mongodb:native="" install="" mongodb="">   =
=  the parser only works for node 0.4.X or lower                               =
=                                                                              =
================================================================================
Not building native library for cygwin
Using GNU make
mongoose@2.3.5 /usr/local/lib/node_modules/mongoose
├── colors@0.5.0
├── hooks@0.1.9
└── mongodb@0.9.6-22


以下のようにmongoにデータを投入するコードを書いてみます。
#!/usr/local/bin/node

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/memorycraft');

var Schema = mongoose.Schema;
var ItemSchema = new Schema({title:String, auther:String, price:Number, date:Date});
var Item = mongoose.model('Item', ItemSchema);

var item = new Item();
item.title = "体脂肪計タニタの社員食堂 ~500kcalのまんぷく定食~";
item.auther = "タニタ";
item.price = 1200;
item.date = new Date(2010, 1, 21);

item.save(function(err){
  if(err){
    console.log(err.message);
  }
  else{
    console.log("保存しました");
  }
});


これを実行します。
$ ./hello_mongo.js
保存しました


ここで、実際にデータが投入されているか再度mongoのコンソールで確認してみます。
$mongo
> show dbs
local (empty)
memorycraft 0.0625GB
test 0.0625GB
>
> use memorycraft
switched to db memorycraft
>
> show collections
items
system.indexes
>
> db.items.find()
{ "date" : ISODate("2010-02-20T15:00:00Z"), "price" : 1200, "auther" : "タニタ", "title" : "体脂肪計タニタの社員食堂 ~500kcalのまんぷく定食~", "_id" : ObjectId("4e9f98394699a3fb40000001") }

memorycraftというdbが増えていて、投入したデータが入っていることが確認できました。

ここで、mongodb+nodeがいいのは、データの保持の時点でJSONなので、取得結果もJSONになっていることです。
そして、上記のコードを書いたようにアクセスの結果がすべてコールバックで記述できるので、とても柔軟にコード記述ができます。
例えば以下のように別途WEBフレームワークなどを使用した場合、取得したデータをそのままレスポンスに返すことで余計な変換処理が必要なくなります。
Item.find({}, function(err, items) {
  if(!err) {
    res.json(items);
  }
});

ほんの少し触れただけですが、とても便利なことがわかりました。
まだまだいろいろいじってみようと思います。
本日は以上です。

2011年10月19日水曜日

WebSocketってなんじゃ?(Node編3 node.jsでサーバーサイドjQuery)

再びnodeの話題です。 前回紹介したSocket.IOのように、node.jsにはnpmで管理される多数のパッケージモジュールがあり、それらをインストールすることでnodeの機能を拡張します。

今回は、jsdomというモジュールを使用してみます。
これはDOMのJS実装を、モジュール化したもので、node上でJSによるDOM解析と操作をサーバーサイドで行うことが可能です。

それでは早速試してみます。
まずnpmでjsdomをインストールしてみます。
$ npm install -g jsdom

> contextify@0.0.6 preinstall /usr/local/lib/node_modules/jsdom/node_modules/contextify
> node-waf clean || true; node-waf configure build

Nothing to clean (project not configured)
Setting srcdir to                        : /usr/local/lib/node_modules/jsdom/node_modules/contextify 
Setting blddir to                        : /usr/local/lib/node_modules/jsdom/node_modules/contextify/build 
Checking for program g++ or c++          : /usr/bin/g++ 
Checking for program cpp                 : /usr/bin/cpp 
Checking for program ar                  : /usr/bin/ar 
Checking for program ranlib              : /usr/bin/ranlib 
Checking for g++                         : ok  
Checking for node path                   : not found 
Checking for node prefix                 : ok /usr/local 
'configure' finished successfully (0.026s)
Waf: Entering directory `/usr/local/lib/node_modules/jsdom/node_modules/contextify/build'
[1/2] cxx: src/contextify.cc -> build/Release/src/contextify_1.o
[2/2] cxx_link: build/Release/src/contextify_1.o -> build/Release/contextify.node
Waf: Leaving directory `/usr/local/lib/node_modules/jsdom/node_modules/contextify/build'
'build' finished successfully (0.789s)
jsdom@0.2.8 /usr/local/lib/node_modules/jsdom 
├── htmlparser@1.7.3
├── cssom@0.2.0
├── request@2.1.1
└── contextify@0.0.6_
インストールが完了しました。


確認のために、自ら作成したDOMの一部を抽出するスクリプトを実行してみます。

hello_dom.js
#!/usr/local/bin/node

var jsdom    = require("jsdom").jsdom;
var document = jsdom("<html><head></head><body><div id='greeting'>hello world</div></body></html>"),
var window   = document.createWindow();

console.log(window.document.getElementById("greeting").innerHTML);
実行
$ chmod 755 hello_dom.js
$ ./hello_dom.js
hello world
うまく出力されました。

様々な言語にDOMを操作するライブラリがありますが、最も有名で最も使いやすいのはやはりjQueryだと思います。
ここではせっかくjavascriptを使っているので、jQueryを利用してみます。

jsdomはjQueryを実行するときに便利なenvメソッドを用意しています。 envメソッドは、ロードしたHTMLソースにscriptタグを追加し、そのscriptがDOMにロードされた後に引数のコールバック関数を呼び出します。
以下のスクリプトは、memorycraftのブログ(このブログです)のトップページから、記事のタイトルをjQueryで抽出してコンソールに出力する、いわゆるスクレイピングを行います。

hello_jquery.js
#!/usr/local/bin/node

var jsdom = require("jsdom");

jsdom.env("http://www.memocra.blogspot.com", [
  'http://code.jquery.com/jquery-1.5.min.js'
],
function(errors, window) {
  var $ = window.$;
  $("h3 a").each(function(){
    console.log($(this).text());
  });
});
実行
$ chmod 755 hello_jquery.js
$ ./hello_jquery.js
EC2でMySQL(世界編2 Spiderとレプリケーションで高速負荷分散)
EC2でMySQL(世界編1 Spiderとレプリケーションで世界進出)
SQSってなんじゃ?(AWSコンソールにSQS登場)
S3ってなんじゃ?(サーバー側でファイルのAES256暗号化)
WebSocketってなんじゃ?(Node編2 Socket.IOでプッシュ通信)

おお!うまく出力できました。

このようにjQueryをサーバーサイドで利用することで、クライアントとサーバーサイド両側で同じ方法でHTMLをコントロールすることができ、とても便利です。

WebSocket関係なくなっちゃいましたが、本日は以上です。

2011年10月5日水曜日

WebSocketってなんじゃ?(Node編2 Socket.IOでプッシュ通信)

前回Node編1で、スタンドアローンのHTTPサーバーをつくり、HTTP通信を行いました。

今回は、WebSocketを使用した通信を行ってみます。 WebSocketとは、ブラウザとサーバーの双方向通信のプロトコル規格で、現在標準化団体が仕様を策定中の技術です。chromeやsafariなど、いくつかのモダンブラウザがサポートしており、これが一般的に使用されると、いままでのサーバーアプリケーションの作り方が大きく変わってくる可能性がある、注目の技術です。

ここで使用するのは、Socket.IO というnode.jsのモジュールです。 node.jsはモジュールという単位でライブラリを管理しており、npmというモジュール管理ツールで簡単にいろいろなモジュールを追加削除できます。これはrubyでいうgemのようなものです。
Socket.IOはただnode.jsでWebSocketを実装しているだけではなく、モダンブラウザ以外のWebSocketを使用できないブラウザでも、AjaxやFlashなど他の代替手段があるかどうかを自動的に検知して通信方式を自動で選択されるので、ブラウザの対応をあまり気にしなくてもよくなっています。
また、Socket.IOは WebSocketとその代替手段において、クロスドメイン通信を可能にしています。

早速実践してみます。 まず最初にnpmをインストールします。
$ curl http://npmjs.org/install.sh | sh
$ npm install -g socket.io


socket.ioのインストールでエラーが出る場合がありますが、その場合はtarが古いので、tarを最新にしておきます。
$ cd /usr/local/src
$ wget http://ftp.gnu.org/gnu/tar/tar-1.26.tar.gz
$ tar xzvf tar-1.26.tar.gz
$ cd tar-1.26
$ ./configure
$ make
# make install


socket.ioをインストールします。
$ curl http://npmjs.org/install.sh | sh
$ npm install -g socket.io

※エラーになる場合は curl -L http://npmjs.org/install.sh | sh とやると良いようです。

これで実装の準備が整いました。
それでは実装を始めます。
今回は、メッセージを送信したら見ている全員にメッセージを表示させる、簡単なチャットの仕組みを作ってみます。

サーバー側

/opt/memorycraft/node/socketsample.js
require.paths.push('/usr/local/lib/node_modules');

var server = require('http').createServer(function(req, res){
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('server connected');
});
server.listen(1337);

var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
  socket.emit('info', { msg: 'welcome' });
  socket.on('msg', function (msg) {
    io.sockets.emit('msg', {msg: msg});
  });
  socket.on('disconnect', function(){
    socket.emit('info', {msg: 'bye'});
  });
});


サーバー側では任意のポート(ここでは1337)を開放したhttpサーバーにsocket.ioをつなげてリスン状態にします。
通信の確立(connection)や切断(disconnect)などのビルトインイベントや、自分のアプリケーションで使用したいオリジナルのイベント(ここではmsg)のイベントハンドラを定義します。
このコードでは接続したときに"welcome"、切断したときに"bye"をそのユーザーに、あるユーザーから"msg"というイベントが送られたら全員に"msg"というイベントを、それぞれプッシュ送信しています。

クライアント側

/var/html/www/test/node/index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
  <script src="http://xxx.xxx.xxx.xxx:1337/socket.io/socket.io.js"></script>
  <script type="text/javascript">
  $(function(){
    var socket = io.connect('http://xxx.xxx.xxx.xxx:1337/');
    socket.on('connect', function() {
      $("#log").html($("#log").html() + "<br />" + 'connected');
      socket.on('info', function (data) {
        $("#log").html($("#log").html() + "<br />" + data.msg);
      });
      socket.on('msg', function(data){
        $("#log").html($("#log").html() + "<br />" + "<b>" + data.msg + "</b>");
      });
      $("#send").click(function(){
        var msg = $("#msg").val();
        if(!msg){
          alert("input your message");
          return;
        }
        socket.emit('msg', msg);
      });
    });
  });
  </script>
  <title>nodetest</title>
</head>
<body>
  <input id="msg" type="text" style="width:400px;"></input>
  <input id="send" type="button" value="send" /></br >
  <div id="log" style="width:400px;height:400px;overflow:auto;border:1px solid #000000;"></div>
</html>

クライアント側からはサーバー側の1337ポートに接続しますが、サーバー側は実際にファイルを自分で配置しなくてもSocket.IOが勝手にクライアント側のライブラリを/socket.io/socket.io.jsとして配信してくれます。
そのファイルをscriptファイルでロードするようにし、あとは接続部分とサーバーからのイベントのハンドラを定義します。また、ボタンを押したらテキストをサーバー側に送信するように記述します。


それでは、サーバー側のコードを実行してみます。
$ node /opt/memorycraft/node/socketsample.js
   info  - socket.io started

ブラウザでhtmlを表示します。

サーバー側からの"welcome"メッセージが表示されていることがわかります。
また、メッセージを入力して送信すると、

メッセージ欄にサーバーから送られてきているのがわかります。

別のブラウザでも開いておき、そちらからメッセージを送信するともう一方のブラウザにメッセージが表示されることが分かります。


このように、socket.ioを利用することで多くのブラウザで簡単にWebSocketを実現することができます。
WebSocketは通信内容が少なく、コネクションやリソースの消費が少ないので、ゲームやソーシャルサイトなどのマルチユーザーアプリや、クライアントのログ集計など、様々な分野での利用が期待できます。
今日はここまで。

2011年9月29日木曜日

javascriptってなんじゃ?(V8のインストール)

とうとうこんなタイトルになるまで落ちぶれてしまいました。。
今回はGoogle製のJavaScriptエンジンであるV8をいじってみます。

V8はChromeにも搭載されておりますが、オープンソースとして公開されており、コンパイルすることによってサーバーサイドでも動作させることができます。これにより、サーバーサイドでJavaScriptを実行することができます。

さっそくv8をインストールしてみます。
# yum install -y subversion
# yum install -y scons

$ cd /usr/local/src/
$ svn co http://v8.googlecode.com/svn/trunk/ v8

$ cd v8/
$ scons
インストールが完了しました。


ここで、実行させるJavascriptファイルを作成してみます。
$ vi hello.js
~
function hello(name){
  return "Hello! " + name;
}
~


ここで、対話型のインターフェースを作って、そこで簡易的にJavascriptの実行をしてみます。
$ scons sample=shell

$ ./shell 
V8 version 3.6.4.1 [sample shell]
> load('hello.js');
> print(hello('memorycraft'));
Hello! memorycraft

正常に表示されました。

これで夢が広がりましたね。 今日はこれまで。

2011年9月28日水曜日

WebSocketってなんじゃ?(Node編1 node.jsのインストール)

かなりいまさらですが、nodeについて。
Node.jsは、非同期イベント駆動モデルのサーバーサイドJavaScript環境で、非ブロッキングI/O(入出力が完了しないうちに他の処理を開始できる)という方式でクライアントからの多数のリクエストを短い時間で処理することができます。

Node.jsではWebSocketを利用することで双方向のメッセージ送信を可能にします。
サーバーからクライアントに情報を渡す仕組みとしては、Ajaxがポーリングにより毎回コネクションを生成したり、Cometのロングポーリングによる擬似プッシュを実現しているのに対して、WebSocketは一度コネクションが生成されたらそのコネクション上で何度でも双方向にメッセージの送受信を行えるため、サーバーのリソースもクライアントの待機時間も節約できます。


それでは、さっそくnodeをインストールしてみます。
$ mkdir -p ~/src/git
$ cd ~/src/git/
$ git clone --depth 1 git://github.com/joyent/node.git
$ cd node
$ git checkout v0.4.11
$ ./configure
$ make
# make install


インストールができたら、以下のようなサンプルを作ってみます。
$ vi hello.js
~
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337);
console.log('Server is running');
~


実行します。
$ node hello.js
Server is running
※AWS上で構築している場合はSecurityGroupでTCPの1337を開放する必要があります。


ここで、クライアント(Mac)のコンソールで以下のようにアクセスしてみます。
$ curl http://xx.xx.xx.xx:1337/
Hello World


次に、さきほどのhello.jsを以下のように書き換えて実行してみます。
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write("Hello\n");
  setTimeout(function(){
    res.end('This is the Node World !!!!\n');
  }, 10000);
}).listen(1337);
console.log('Server running');

同じようにアクセスしてみます。
$ curl http://xx.xx.xx.xx:1337/
Hello

すると、一旦ここまでレスポンスが表示され、
10秒後に
$ curl http://xx.xx.xx.xx:1337/
Hello
This is the Node World !!!!
と "This is the node World !!!!" が追加で表示されます。

この時サーバークライアント間では、2つめのワードが返る間もコネクションが維持され、しかもサーバーはその間スループやロックやビジーになることなく他のアクセスの処理などを行うことができます。

見た目にはたったこれだけの違いなのですが、これによりとても多くの可能性をもつことになり様々な応用が期待できます。
今日はここまでです。