2012年11月26日 星期一

透過某種"方式"讓Node.js程式順序執行

var exec = require('child_process').exec;

var arr = [1,2,3,4,5,6,7];
                      
function doit(v){
  exec('echo ' + v, function(err, stdo, stde){
    console.log('-->' + stdo);
    if(arr.length >0) //如果array還有值,則再call一次本身
      doit(arr.pop());
  });
}

doit(arr.pop());

執行結果:
# node test.js 
-->7
-->6
-->5
-->4
-->3
-->2
-->1

2012年11月25日 星期日

Node.js的forEach迴圈非循序進行

Node.js的forEach迴圈非循序進行:

var arr = [1,2,3,4,5,6,7]

arr.forEach(function(v,i){
  exec('echo ' + arr[i], function(err, stdo, stde){
    console.log('-->' + stdo);
  });
});

執行1:
# node test.js 
-->6
-->5
-->4
-->3
-->2
-->1
-->7

執行2:
# node test.js 
-->5
-->4
-->3
-->2
-->1
-->7
-->6

2012年11月20日 星期二

使用smartos建立node.js之ssl web server

下面展示使用micloud smartos建立node.js之ssl web server
smartos在建立起來時候,會自動產生一組selfsigned.pem的key
可以省去建立openssl的時間...
設定node.js https時候,可以直接將key與cert都指定在selfsigned.pem上
透過該key提供ssl需要的認證金鑰...

Step 1:
# express ssltest && cd ssltest && npm install

Step 2:
# vi app.js

var express = require('express')
  , routes = require('./routes')
  , https = require('https') //使用node.js https模組
  , fs = require("fs")
  , path = require('path');

//設定https需要使用的options參數
var key = '/opt/local/etc/openssl/private/selfsigned.pem';
var crt = key; 
var privateKey = fs.readFileSync(key);
var certificate = fs.readFileSync(crt);
var options = {
    key: privateKey,
    cert: certificate,
};

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 1330);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

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

app.get('/', routes.index); //express default root

//建立一個測試route
app.get('/test', function(req, res){
  res.writeHead(200);
  res.end('TEST...');
});

//使用https來建立server, 建立過程中帶入options參數
https.createServer(options, app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

Step 3 - 測試:
# node app.js

打開Browser連線:https://your.ip.address:1330/test



參考:


2012年11月3日 星期六

NodeJS connect Couchdb

CouchDB是NoSQL資料庫的一支,由Apache維護...(這是我選他的最大原因)
預設CouchDB提供RESTful server,並由該Server作為所有API的接口
同時Apache也有許多專案實作接入CouchDB的各市程式語言的API

本篇以想使用Node.js連接Couchdb的部分為教學
假設大家已經有Node.js以及Couchdb的服務...

安裝Cradle套件
# npm install cradle

設定cradle連線couchdb的connection
  db = new(cradle.Connection)(db_address, db_port, {
    auth: { username: dbusername, password: dbpassword },
    cache: true,
    raw: false
  }).database(databasename);
上述建構連線資料庫的基本資訊,包含資料庫位置、port號、帳號、密碼等資訊。

而Couchdb的新刪改查說明如下:

新增一筆資料,id=PK,doc=欲儲存文件,callback=儲存結束後回傳:
db.save(id, doc, callback);

刪除一筆資料,id=PK,rev=版本號碼,callback同上:
db.remove(id, rev, callback);

修改一筆資料,id=欲修改之資料id,doc=欲修改的文件內容,callback同上:
db.merge(id, doc, callback);

查詢一筆資料,id=欲查詢的資料id,callback為查詢回傳,包含查詢結果:
db.get(id, callback);


下面為一個整體的資料庫查詢範例,您可以修改內部的一些實作來變成專案中處理CouchDB的幫手∼

var util = require('util')                                                                                                                                
  , cradle = require('cradle')
  , dbusername = 'your_db_username'
  , dbpassword = 'your_db_password'
  , databasename = 'your_db_name'
  , db_address = 'your.db.address'
  , db_port = 'your_db_port' //default: 5984
  , db = new(cradle.Connection)('http://' + db_address, db_port, {
    auth: { username: dbusername, password: dbpassword },
    cache: true,
    raw: false
  }).database(databasename);

//如果要做到查詢模組∼
exports.queryExample = function(id, callback) {
console.log('Query of %s', id);
db.get( id, function (err, doc) {
if(err) console.log(err);
callback(err, doc);
});
}
/*
ex: sample data: {_id:"simon","_rev":"3-f84647507bd83e29a6deae7c377a74dc","first_name":"simon","last_name":"su"}
this.queryExample('simon',function(err, doc){
...
})
*/

//如果要做到查尋View∼
exports.queryViewExample = function(id, callback) {
console.log('Query of %s', id);
db.view( 'domain/userDomain',{key: userid}, function (err, doc) {
if(err) console.log(err);
callback(err, doc);
});
}
/*
ex: sample data: [{key:"simon", value:{....}},{key:"jelly", value:{....}},{key:"kimi", value:{....}}...]
this.queryViewExample('simon',function(err, doc){
...
})
*/

//如果要建立一筆資料∼
exports.createExample = function(id, doc, callback) {
db.save(id, doc, function(err, res){
if(err) console.log(err);
callback(err, res);
});
}
/*
ex: sample input doc={name:"simon",phone:"0953609275"}
this.createExample(id, doc, function(err, res){
...
});
*/

//如果要更新一筆資料∼
exports.updateExample = function(id, doc, callback) {
db.merge(id, doc, function (err, res) {
if(err) console.log(err);
callback(err, res);
});
}
/*
ex: sample update data id=key_of_row, doc={...}
this.updateExample(id, doc, function(err, res){
...
});
*/


/** 其他範例:
//Create Database:
var db = c.database('database_name');
db.create();

//Delete Database
db.destroy(callback);

更多範例請參考:https://github.com/cloudhead/cradle
**/
  

2012年10月1日 星期一

Using temp view in cradle

當使用cradle作為node連線couchdb時候
要用temp view來動態撈取資料可參考此篇

這邊是希望doc._id欄位字串中有帶入給定參數的
就撈出來呈現...

var util = require('util')                                                                                                                                               
  , cradle = require('cradle')
  , db = new(cradle.Connection)('http://xxx.xxx.xxx.xxx', 5984, {
    auth: { username: dbusername, password: dbpassword },
    cache: true,
    raw: false
  }).database('dbname');

//Write module
exports.test = function() {
  db.temporaryView({
    //If you want to bring a parameter into tmp view, you need to also have "" in your parameter
    map: 'function (doc) { if (doc && doc._id && doc._id.indexOf("'+ params +'") >=0 ) emit(doc._id, doc); }' 
  }, function (err, res) {
    if (err){
      console.log('[ERROR]:'+err);
    }   
    callback(err, res);
  }); 
}

//Use it
this.test();

需要注意的是,temporaryView中帶入的是json參數,由json帶入map function
因此最好將整個map function定義成變數
然後要帶入的變數就可以夾在中間...只是要注意到變數的兩邊要給他雙引號起來
因為轉成字串時候,需要有雙引號,才會是單純的字串,而不會又變回變數...

2012年7月23日 星期一

NPM using proxy

在使用NPM指令時候,如果剛好在個有Proxy的區域
常常npm會有問題,Linux的使用者會這麼做:

export HTTP_PROXY=http://your.proxy.ip.address:port

讓程是預設吃這個位置的proxy設定
但是Windows的使用者一般都是到網路管理界面設定...
這部分NPM連線就有問題
作法很簡單,Windows中的NPM也吃HTTP_RPOXY這個參數
所以只要這樣做:

set HTTP_PROXY=http://your.proxy.ip.address:port

就可以正常使用NPM了...

當然∼要確認NPM的repository是否可以辨識得到(這部分是跟DNS有關)


如果不小心被DNS漏掉,可以加到static route去(/etc/hosts或C:\Windows\system32\drivers\etc\hosts)
他的IP可以這樣查:

nslookup registry.npmjs.org 8.8.8.8

其中8.8.8.8是Google的DNS服務...將查到的IP寫到static route去就可以摟∼

2012年7月17日 星期二

JSON object in node.js

在Node.js/JavaScript中
針對JSON物件可以用這樣的方法循序倒出來

$ node
> var json = { "aa":1, "bb":2,"cc":3}
> for(key in json){
... console.log(key);
... }
aa
bb
cc