2011年11月1日火曜日

Amazon EC2を始める(MongoDB編)

経緯
Amazon EC2を始める(導入編)
Amazon EC2を始める(SSL編)
Amazon EC2を始める(SCP編)
Amazon EC2を始める(Apache編)
Amazon EC2を始める(node.js編)
Amazon EC2を始める(node.js - express編)
Amazon EC2を始める(node.js - socket.io編)」の続きです。


概要
今回はただインストールしただけです。
nodeから使ってみたりはまた今度やります。

MongoDB
http://www.mongodb.org/

上記の本家でもとてもわかりやすいのですが、↓こちらもわかりやすいです。
ハンズオンで分かる MongoDB チュートリアル
http://d.hatena.ne.jp/babie/20100805/1280982678


手順
# ダウンロード (最新版は上の本家リンクから探してくださいね。)
$ wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.1.tgz
--2011-10-31 15:33:46--  http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.1.tgz
Resolving fastdl.mongodb.org... 216.137.53.31, 216.137.53.40, 216.137.53.135, ...
Connecting to fastdl.mongodb.org|216.137.53.31|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 38242091 (36M) [application/x-tar]
Saving to: “mongodb-linux-x86_64-2.0.1.tgz”

100%[==========================================================>] 38,242,091  21.5M/s   in 1.7s   

2011-10-31 15:33:48 (21.5 MB/s) - “mongodb-linux-x86_64-2.0.1.tgz” saved [38242091/38242091]

# 解凍
$ tar xvfz mongodb-linux-x86_64-2.0.1.tgz

# 実行ファイルを移動
$ sudo cp mongodb-linux-x86_64-2.0.1/bin/* /usr/local/bin/


# データ保存先を作成
$ sudo mkdir /var/mongo
$ sudo chgrp -R webuser /var/mongo
$ sudo chmod -R g+w /var/mongo


# 起動
# --forkはバックグラウンド起動(--logpath必須)
# --dbpath以下にデータファイルを保持
$ mongod --dbpath /var/mongo/ --logpath /var/mongo/db.log --fork
$ forked process: 26384
all output going to: /var/mongo/db.log
Enter

# 起動してますね。
$ ps aux | grep mongo
ec2-user 26454  4.5  2.3 259360 14108 ?        Dl   15:49   0:01 mongod --dbpath /var/mongo/ --logpath /var/mongo/db.log --fork

# 使ってみる。
$ mongo
# 保存
> db.sample.insert({uid:'123',name:'ryooo'})
# 取得
> db.sample.find();
{ "_id" : ObjectId("4eaec46df0af44d032284e97"), "uid" : "123", "name" : "ryooo" }
# 全ドキュメント削除
> db.sample.remove();
> db.sample.find();
>

# mongoを終了はするなら
$ ps aux | grep mongo
ec2-user 26454  4.5  2.3 259360 14108 ?        Dl   15:49   0:01 mongod --dbpath /var/mongo/ --logpath /var/mongo/db.log --fork
$ sudo kill -TERM 26454

# バックグラウンド起動は↓こんな感じ。
$ sudo node chatapp/app.js > /dev/null 2>&1 &


次はnodeから使ってみます。
※ 来週までおそらく着手できませんが。

Amazon EC2を始める(node.js - socket.io編)

経緯
Amazon EC2を始める(導入編)
Amazon EC2を始める(SSL編)
Amazon EC2を始める(SCP編)
Amazon EC2を始める(Apache編)
Amazon EC2を始める(node.js編)
Amazon EC2を始める(node.js - express編)
の続きです。


概要
node.jsで簡単なチャットアプリを作成しました。
こんな感じです

ソース自体は以前にnode.exeで作ったものを少し改良したものになります。
node.exeでwebページに(付箋のような)メモを共有できるアプリを作ってみた

ソース
構成
構成はこんな感じです。
chatapp/
├── app.js
├── node_modules
│   ├── express ⇒ (今回は未使用)
│   ├── jade ⇒ (今回は未使用)
│   └── socket.io
└── public 
     ├── javascripts 
     │   └ chatapp.js
     └── index.html

nodeとnpmが入っていれば、こんな感じで構築可能
[ec2-user@ip-10-152-66-29 ~]$ cd /usr/local/src/
[ec2-user@ip-10-152-66-29 src]$ express chatapp
[ec2-user@ip-10-152-66-29 src]$ cd chatapp
[ec2-user@ip-10-152-66-29 chatapp]$ npm install socket.io

# アプリ起動
[ec2-user@ip-10-152-66-29 chatapp]$ node app.js 
Express server listening on port 3000 in development mode
   info  - socket.io started

サーバーサイド app.js
/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

/**
 * ルーティング
 */
app.get('/', routes.index);

/**
 * 起動
 */
app.listen(3000);
console.log("Express server listening on port %d in %s mode",
                   app.address().port, app.settings.env);
var io = require('socket.io').listen(app);

/**
 * socket 接続
 */
io.sockets.on('connection', function (socket) {
  /**
   * 各socketからbox情報の通知
   */
  socket.on('draged_caster', function (params) {
    console.log(params);
    socket.broadcast.emit('draged_listener', params);
  });
  
  /**
   * socket 切断
   */
  socket.on('disconnect', function() {
    console.log('Disconnect...');
  });
});

クライアントサイド index.html
<!DOCTYPE html>
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>chatapp</title>  
<style type="text/css">  
div.controller {  
  width: 120px;  
}  
div.box_black {  
  width: 200px;  
  height: 55px;  
  border: 1px solid #AAAAAA;  
  box-shadow: 0 0 6px #999999;  
  cursor: pointer;  
  background: none repeat scroll 0 0 #FFFFFF;  
}  
textarea {  
  width: 97%;  
  height: 90%;  
  box-shadow: 0 0 6px #999999;  
}  
</style>  
</head>  
<body>  
<div class="controller"><input id="btn_tweet" type="button" value="Tweet" /></div>  
<div id="MainContent" class="clearfix">  
<h2 id="NewsTitle">宇宙の起源・未来探る最大の謎 ノーベル物理学賞米豪チーム</h2>  
<div class="DateandPage">  
<span class="Timestamp">20xx.xx.xx xx:xx</span>  
<span class="Topicstitle">[ノーベル賞]</span>  
</div>  
<div class="NewsTextFull">  
<p> ノーベル物理学賞の受賞が決まった米国のソール・パールマッター、アダム・リース、オーストラリアのブライアン・シュミットの3氏による「宇宙の加速膨張」の発見は、科学史に残る大発見として近い将来の受賞が確実視されていた。宇宙の膨張速度は、過去よりも現在の方が加速しており、宇宙には空間を押し広げる謎のエネルギーが満ちていることを示した。</p><p> 宇宙は約137億年前、ビッグバンと呼ばれる大爆発で誕生した。その後も膨張は続いているが、物質や銀河同士を引きつける重力の影響で徐々に減速し、現在は一定速度で膨張していると考えられていた。</p><p> 研究チームはこの定説を覆した。超新星爆発の観測で宇宙の膨張速度を計測した結果、速度は一定ではなく、約70億年前に加速に転じたことを発見。その原因として、宇宙には互いに引きつけ合う重力とは逆に、退け合う「斥力」を持つ未知のエネルギーが存在すると結論付けた。</p><p> 研究チームはこれを「暗黒エネルギー」と命名。その正体はまったく不明で、宇宙の起源や未来を探る宇宙論での最大の謎になった。このエネルギーは、アインシュタインが自身の宇宙方程式に導入して後悔したとされる「宇宙項」との関連でも議論されている。</p><p> 横山順一東京大教授(宇宙論)は「時間の経過で暗黒エネルギーの大きさは変わるのかなど、その性質を明らかにする研究は現在も続いている。受賞に値する画期的な成果だ」と話す。</p>  
</div>  
</div><!-- /#MainContent -->  
  
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.3");</script>
<script type="text/javascript">google.load("jqueryui", "1.7");</script>
<script src="/socket.io/socket.io.js"></script>
<script src="/javascripts/chatapp.js"></script>
</body>  
</html>  

クライアントサイド chatapp.js
$(function() {
  /**
   * socketをサーバーと接続
   */
  var socket =
   io.connect('http://ec2-xxx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:3000/');
  socket.on('connect', function(){
    /**
     * 別socketからの通知を処理
     */
    socket.on('draged_listener', function (params) {
      var boxNum = params.id.split('_')[1];
      var boxObj = $('div#' + params.id);
      // boxが未作成なら作る
      if (!boxObj.length) {
        boxObj = funcAddBox(true, boxNum);
      }
      boxObj.css({top:params.y,left:params.x,position:'absolute'});
      boxObj.text(params.text);
    });
  });
 
  /**
   * boxの中身と位置をサーバーに通知
   */
  var ping = function (boxObj, text){
    var pos = boxObj.position();
    var params = {"id" : boxObj.attr('id'),
            "text" : text,
            "x" : pos.left,
            "y" : pos.top
            };
    socket.emit('draged_caster', params);
  }
 
  /**
   * boxを作る
   */
  var funcAddBox = function(isCopy, argNum) {
    var now = new Date(),
        num = now.getTime();
    // 新規/既存
    if (isCopy == true) {
      num = argNum;
    }
    boxObj = $('<div class="box_black">message...</div>')
      .attr('id', 'box_' + num)
      .css({'position': 'absolute', 'top' : 30})
      .draggable({
        "drag" : function(e, ui) {
          ping($(this), $(this).text());
        }
      })
      // ダブルクリックで編集
      .dblclick(function() {
        $(this)
          .wrapInner('<textarea></textarea>')
          .find('textarea')
          .focus()
          .select()
          .bind('keyup', function() {
            var boxObj = $(this).parent();
            ping(boxObj, $(this).val());
          })
          .blur(function() {
            var boxObj = $(this).parent();
            boxObj.html($(this).val());
            ping(boxObj, $(this).val());
          });
      });
    $('body').prepend(boxObj);
    // 新規ならサーバーに通知
    if (isCopy != true) {
      ping(boxObj, boxObj.text());
    }
    return boxObj;
  };
 
  /**
   * Tweetボタン クリック時
   */
  $('#btn_tweet').click(funcAddBox);
 
});

※ 上記構成の場合、public以下のindex.htmlにブラウザからアクセスします。
http://ec2-xxx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:3000/index.html