標籤:des style blog http color io os 使用 ar
1.url的處理
querystring.parse(urlObj.query)可以把url內的query參數轉為字串
JSON.parse可以把字串轉為json
2.非同步與同步
我的項目大約是這樣的
接受url請求並處理-解析-去拿到環境變數與參數。
等待上面的請求ok後,並發請求,使用上面的環境變數與參數去調用php與webredis
同步非同步交織在一起,很蛋疼。
不過接下來使用了eventproxy進行處理,非常好用~
https://github.com/JacksonTian/eventproxy
一個非常典型的代碼
1 ep.all(‘tpl‘, ‘data‘, function (tpl, data) { 2 // 在所有指定的事件觸發後,將會被調用執行 3 // 參數對應各自的事件名 4 }); 5 fs.readFile(‘template.tpl‘, ‘utf-8‘, function (err, content) { 6 ep.emit(‘tpl‘, content); 7 }); 8 db.get(‘some sql‘, function (err, result) { 9 ep.emit(‘data‘, result);10 });
那麼注意下面兩個函數,一定要保證callback執行,emit才會觸發。
當all內事件都觸發後,傳回值作為參數,觸發ep.all內的callback
更多的使用方法可以參考api。
3.nodejs發送post
1 var http = require(‘http‘); 2 var querystring = require(‘querystring‘); 3 4 var post_data = querystring.stringify({ 5 sys_text : ‘構造字串”歡迎回來,道客‘+cellphone.slice(cellphone.length-4,cellphone.length)+‘,您的語鏡已經串連系統,請安全駕駛‘, 6 interval : ‘1440‘, 7 agent: ‘超級管理員‘, 8 userid :userid, 9 });10 11 var options = {12 host:‘192.168.1.3‘,13 port:8080,14 path:‘/idts-1.0/httpservice/addweibo/php/add_sys_weibo.php‘,15 method:‘post‘,16 headers: {17 ‘Content-Type‘: ‘application/x-www-form-urlencoded‘,18 ‘Content-Length‘: post_data.length19 }20 };21 22 var req = http.request(options, function (res) {23 console.log("Got response: " + res.statusCode);24 res.setEncoding(‘utf8‘);25 res.on(‘error‘,function (e) {26 console.log("Got error: " + e.message);27 }).on(‘data‘, function (chunk) {28 console.log(‘BODY: ‘ + chunk);29 });30 });31 req.write(post_data + "\n");32 req.end();33 }
上面是整個發送post的流程。那麼注意一點一定要指定content-length頭。否則會報錯。ngix會報類似411 length required 這樣的錯誤。
之後只需要利用req.write向接收端寫訊息體即可。
至於nodejs發送get,可以直接使用http.get方法
相關的api http://docs.cnodejs.net/cman/http.html
3月13日更新
經過大牛snoopy的對代碼的斧正,發現了幾個問題
1.異常處理,JSON.parse可能會拋異常,因此需要處理
1 try {2 var cellphone = JSON.parse(result).MGET[0]3 } catch (e) {4 // console.log(e.name); // "MyError"5 // console.log(e.message); // "MyError"6 console.log(‘資料格式不正確‘)7 }
2. 拼接chunk
在接收服務端的資料時,若資料較長,直接在data監聽可能會收到多次chunk。
利用字串拼接chunk時,因為編碼等問題,可能出現錯誤,因此建議用數組拼接
見這篇文章 http://cnodejs.org/topic/4faf65852e8fb5bc65113403
1 var chunks = []; 2 var size = 0; 3 res.on(‘data‘, function (chunk) { 4 chunks.push(chunk); 5 size += chunk.length; 6 }); 7 res.on(‘end‘, function () { 8 var data = null; 9 switch(chunks.length) {10 case 0: data = new Buffer(0);11 break;12 case 1: data = chunks[0];13 break;14 default:15 data = new Buffer(size);16 for (var i = 0, pos = 0, l = chunks.length; i < l; i++) {17 var chunk = chunks[i];18 chunk.copy(data, pos);19 pos += chunk.length;20 }21 break;22 }23 });
思路就是上面的代碼,我也使用了文中提到的bufferHelper。
另外snoopy說可以使用0.10的stream2,等下次嘗試。
3.多核
nodejs裡內建了cluster模組,可以大大提高機器資源的使用
利用cluster做的多核
1 function start(handle) { 2 var http = require("http"); 3 var cluster = require(‘cluster‘); 4 var http = require(‘http‘); 5 var numCPUs = require(‘os‘).cpus().length; 6 if (cluster.isMaster) { 7 for (var i = 0; i < numCPUs; i++) { 8 cluster.fork(); 9 }10 cluster.on(‘death‘, function (worker) {11 console.log(‘worker ‘ + worker.pid + ‘ died‘);12 cluster.fork();13 });14 } else {15 function onRequest(request, response) {16 var options = {17 host:‘192.168.1.6‘,18 port:7379,19 path:‘/SADD/‘ + ‘niaAOVU2lg‘ + ‘:config/‘ + ‘2013-03-09‘ + Math.random(),20 method:‘get‘21 };22 var req = http.get(options, function (res) {23 // console.log("Got response: " + res.statusCode);24 res.on(‘error‘,function (e) {25 // console.log("Got error: " + e.message);26 }).on(‘data‘, function (chunk) {27 // console.log(‘BODY: ‘ + chunk);28 });29 });30 req.on(‘error‘, function (e) {31 // console.log("Got error: " + e.message)32 })33 req.end()34 response.writeHead(200, {‘Content-Type‘:‘text/html‘});35 response.end()36 }37 38 var server = http.createServer(onRequest).listen(8888);39 }40 }41 42 exports.start = start;//定義模組給外面的函數
經過效能測試,8核的機器跑滿了能達到以前的八倍。。。(8個同時跑嘛。。)
還有個問題
1 var req = http.request(o, function (res) { 2 var rec_leng = 0; 3 var rec_ary = []; 4 // res.setEncoding(‘utf8‘); 5 res.on(‘error‘,function (e) { 6 console.log("Got res error: " + e.message); 7 }).on(‘data‘, function (chunk) { 8 rec_leng += chunk.length; 9 rec_ary.push(chunk);10 /*11 * if(rec_leng > postLimit){12 rec_ary = null;13 req.connection.destroy()14 }15 * */16 }).on(‘end‘, function () {17 var buf = Buffer.concat(rec_ary, rec_leng);18 var result = buf.toString();19 callback.call(this, result);20 });21 })
注意setEncoding轉換的時候,會把2進位轉成string buffer的concat會出錯,所以兩個不要一起用。
來自:http://99jty.com/?p=1157
nodejs項目小總結(轉)