2015年4月29日 星期三

Node.js 初體驗

         node.js也是目前最火紅的技術之一,身為JavaScript的開發人員也能開發後端,同樣也有跨平台的優勢,目前有專案原本想用Asp.net Web API透過vfpoledb 讀取foxproDB,並架在IIS上面, 但是,作者想用Node.js本地端架伺服器, 並呼叫C# 程式,透過瀏覽器發佈在網頁上面。

一、呼叫http物件

var http = require('http');  // 注入 http 模組
fs = require('fs'); //讀取檔案
var url = require('url'); //解析呼叫url 的動作
var requestListener = function (req, res) {
    var path = url.parse(req.url).pathname;   
    switch (path) {
        case '/':
            res.writeHead(200);
            try {          
//此段落寫下HTML5的語法… 
            }  catch (error) {               
                console.log(error);
            }
            res.end();
            break;
        case '/a1.html':
//讀取a1.html檔案…  該檔案就可以編寫html的語法
            res.writeHead(200);
            fs.readFile('a1.html', 'utf8', function (err, data) {
                if (err) {
                    return console.log(err);
                }
                res.end(data);
            });
            break;
        default:
            res.writeHead(404);
            res.write("opps this doesn't exist - 404");
            res.end();
            break;   
    }
};
var server = http.createServer(requestListener, function (err) {
    console.log(err);
});

server.listen(1234);  //設定port 1234

Node.js 的觀念是需要用到什麼模組,就需要注入該模組,http模組是把本地架成server,並設定port號,需要用到時,呼叫request(“http”),另外require('url'): 為了解析網址的參數,取得/ 斜線之後的值

二、呼叫c# exe的範例

作者透過node.js 呼叫c#應用程式,先把資料寫入到mongoDB  
Var http = require('http');
fs = require('fs')
var url = require('url');
var requestListener = function (req, res) {
    var path = url.parse(req.url).pathname;   
    switch (path) {
        case '/':
            res.writeHead(200);
            try {
//呼叫可以執行應用程式的模組
                var exec = require('child_process').execFile;               
                var fun = function () {
                    exec('ConsoleApplication1.exe', function (err, data) {
                        console.log(err)
                        console.log(data.toString());
                    });
                }
                fun();
            } catch (error) {               
                console.log(error);
            }            
            res.write("test");
            res.end();
            break;      
        default:
            res.writeHead(404);
            res.write("opps this doesn't exist - 404");
            res.end();
            break;    
    }
};
var server = http.createServer(requestListener, function (err) {
    console.log(err);
});
server.listen(1234);

C# 的範例程式
  class MongoDB
    {
        public void save(DataTable dt)
        {
            try
            {
                string connString = "mongodb://192.168.1.63:27017/cooper"; // 連接cooper db
                MongoClient _client = new MongoClient(connString);
                MongoServer _server = _client.GetServer();
                _server.Connect();               
                MongoDatabase db = _server.GetDatabase("cooper");// 連接到 db
                MongoCollection collection = db.GetCollection("patient");//資料表
               
                foreach (DataRow dr in dt.Rows)
                {
                    BsonDocument inserData1 = new BsonDocument();
                    foreach (DataColumn column in dt.Columns)
                    {
                        Dictionary<string, object> keyValue = new Dictionary<string, object>();
                        keyValue[column.ColumnName] = dr[column.ColumnName];
                        inserData1.AddRange(keyValue.ToBsonDocument());
                    }
                    collection.Insert(inserData1); //寫入資料表
                }
                _server.Disconnect();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


三、node.js 讀取mongodb的資料,並顯示在瀏覽器上

先記得下戴node.js mongodb的模組


var http = require('http');
fs = require('fs')
var url = require('url');
var requestListener = function (req, res) {
    var path = url.parse(req.url).pathname;   
    switch (path) {
        case '/':
  //顯示中文字
res.writeHead(200, { 'Content-Type': 'text/html' });
            res.write('<head><meta charset="utf-8"/></head>');          
            try {
       var mongo = require('mongodb'); //注入 mongodb 模組
                var Server = mongo.Server;
                var Db = mongo.Db;               
                var server = new Server('192.168.1.63', 27017, { auto_reconnect: true });
       var db = new Db('cooper', server); //開啟資料庫:cooper  
                var htmlCode = "<table border=1><tr><th>病歷編號</th></tr>";
                db.open(function () {
//開啟資料表patient
                    db.collection('patient', function (err, collection) {
                        collection.find().toArray(function (err, items) {                
                            for (var i = 0; i <= items.length - 1; i++) {
                                htmlCode+="<tr>";
                                htmlCode +="<td>"+items[i].病歷編號+"</td>"
                                htmlCode +="</tr>";
                            }
                            htmlCode += "</table>";
                            res.write(htmlCode);
                            res.end();
                        });
                    });                 
                });              
            } catch (error) {                
                console.log(error);
            }                     
            break;
        default:
            res.writeHead(404);
            res.write("opps this doesn't exist - 404");
            res.end();
            break;    
    }
};
var server = http.createServer(requestListener, function (err) {
    console.log(err);
});
server.listen(1234);


結果展示

    












以上就是用node.js做成簡易版的server,並結合mongodb讀取資料,那麼即使不用IIS+MSSQL,也能簡易的架設網站,是不是很神奇。



補充說明: node.js呼叫c# dll

透過npm 下戴edge 模組,路徑放置位置在專案目錄下










檔名: app.js
var edge = require('./edge/lib/edge.js');  //透過edge.js 就可以呼叫c# dll 元件
var helloWorld;
try {
    helloWorld = edge.func('ClassLibrary2.dll');
}
catch (error) {
    console.log(error);
}
var helloWorld;
helloWorld('8888'); // 呼叫 c# 函式         

     
檔名: ClassLibrary2.dll
public class Startup
    {
        public async Task<object> Invoke(dynamic input)
        {
            if (input == null)
            {
                return "this is my first test node.js";
            }
            else
            {
                PublicInfo.Cooper_Path = "d:\\Cooper";
                DataTable dt = commonDB.selectQueryWithDataTable("select * from doctor", false);
                return dt;
            }
        }
}

node.js 經由edge 模組產生helloWord 物件,如果未指定類別名稱時,預設會執行『Startup』類別的函式名稱為『Invoke』,所以該物件helloWord所傳遞的參數,就會傳遞到Invoke(dynamic input) 的函數,但回傳結果要以非同步方式回傳值async Task<object>

作者原本想透過c#.dll內部的函式呼叫Foxpro OLEDB讀取資料表並回傳到node.js, 但是Foxpro OLEDB 是不支援64位元,所以需要把c# DLL 的執行目標設為x86,但c#的dll的執行目標x86時,node.js無法執行成功,必需把c# DLL的執行目標設為Any PC, node.js的程式才能正常執行,但Foxpro OLEDB就出現error,所以node.js 的環境如果64位元,是無法相容X86執行目標的DLL,也許是作者沒有使用正確的方式,以上僅供參考,感謝各位的到訪。