nodejs项目小总结(转)

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.length
19         }
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
posted @ 2014-10-08 14:27  食草动物  阅读(293)  评论(0编辑  收藏  举报