[node.js]RPC(远程过程调用)的实现原理

2013-1-31 评论(0) 分类:技术文章 Tags:

刚接触到RPC(远程过程调用),就是可以在本地调用远程机子上的程序的方法,看到一个简单的nodejs实现,用来学习RPC的原理很不错:nodejs light_rpc

使用示例:

//服务端
var light_rpc = require('./index.js');
var port = 5556;
var rpc = new light_rpc({
    combine: function(a, b, callback){
        callback(a + b);
    },
    multiply: function(t, cb){
        cb(t*2);
    }
}).listen(port);
Sample client:
//客户端
rpc.connect(5556, 'localhost', function(remote, conn){
    remote.combine(1, 2, function(res){
        if(res != 3){
            console.log('ERROR', res);
        }
    });
});

(更多…)

[Node.js]简化学习everyauth的异步流程控制

2012-10-22 评论(4) 分类:技术文章 Tags:

看了everyauth源码,第一次看解决异步流程问题的实现方法,感到很惊讶,为了更好地学习,实现了这个流程的简化版。

例子

先看看这段代码,功能是从本地文件读到一个url—请求这个url—把结果写入另一个文件。

var fs = require('fs'),
http = require('http');

fs.readFile('./url.txt', 'utf8', function (err,data) {
  http.get(data, function(res){
    var body = '';
    res.on('data', function(c){
      body += c;
    }).on('end', function(){
      fs.writeFile('./fetchResult', data + body, function(e) {
        if (e) console.log('error', e);
        else console.log('done');
      });
    });
  }).on('error', function(e){
    console.log(e);
  });
});

这段代码包括了三个步骤三个功能,但耦合在一起,可读性差,难以修改,对任意一部分修改或增加都要看完整坨代码才能找到,即时把每个callback都抽成一个变量,这一整个流程也是无法分离的。

改进版

对这种情况,everyauth使用了一种方法,可以把整个流程的实现代码写成这样:

engine
  .do('fetchHtml')
    .step('readUrl')
      .accepts('')
      .promises('url')
    .step('getHtml')
      .accepts('url')
      .promises('html')
    .step('saveHtml')
      .accepts('url html')
      .promises(null)

  .readUrl(function(){
    //read url from file
    ...
  })
  .getHtml(function(url){
    //send http request
    ...
  })
  .saveHtml(function(url, html){
    //save to file
    ...
  })

  .start('fetchHtml')

do是一串流水方法的开始,step指定每一个步骤对应的方法名,promises表示此步骤返回的变量名,accepts表示此步骤接受的参数(由前面step的方法提供的变量)。接下来是链式地实现每一个step的方法。

整个过程很清晰,程序的自我描述很好,把一段异步的流程按同步的方式写出来了。若要修改其中某个步骤,直接定位到某个步骤对应的方法就行,无需把整个流程的代码通读。若要增加步骤,也只需要在那些step流程上插入新的step然后实现具体方法,可以获取前面step提供的任何参数。

how it works

实现它用到四个对象:promise/step/sequence/engine

promise是基础,相信很多人熟悉它的概念,简单来说就是把多个callback放到一个promise对象里,在适当的地方通过这个对象调用这些callback。在这里的作用是:当step执行结束时,通知队列执行下一个step。具体地说就是把下一个step的函数保存到前一个step的promise里,前一个step完成任务时,带着数据回调下一个step进入执行。

step负责执行一个步骤,传入对应参数,并把执行结果(return值)按指定的promises名保存起来,以供下一个step使用。

sequence管理step链,让注册的step可以一步步往下执行。

engine是提供对外接口的对象,管理保存每一个do请求里的step和sequence,通过configurable配置自身的可动态添加的方法。

具体看代码:https://gist.github.com/3930621

(更多…)

node.js源码研究—模块组织加载

2011-6-8 评论(1) 分类:技术文章 Tags:

粗略研究了一下node.js源码,它有8000行C++代码,2000行javascript代码,来看看js和C++间是怎么组织连接起来,以及各个模块是怎样互相调用的。

本文使用的node.js版本是0.4.8,可以在https://github.com/joyent/node/tree/v0.4.8这里看到源码。

js2c.py

node.js使用了V8附带的js2c.py工具把所有内置的js代码转换成C++里的数组,生成node_natives.h直接include到程序中,成了C++源码的一部分。这样做能提高内置js模块的编译效率。

node.js里内置的javascript包括了主程序src/node.js和模块程序lib/*.js,通过js2c.py让每一个js文件都生成一个源码数组,存放在build/src/node_natives.h里,node_natives.h在node.js编译后才会生成(编译的脚本wscript中调用了js2c.py),可以看到大致的结构如下:

namespace node {
    const char node_native[] = {47, 47, 32, 67, 112 ......}
    const char console_native[] = {47, 47, 32, 67, 112 ......}
    const char buffer_native[] = {47, 47, 32, 67, 112 ......}
    .....
}
struct _native {  const char* name;  const char* source;  size_t source_len;};
static const struct _native natives[] = {
  { "node", node_native, sizeof(node_native)-1 },
  { "dgram", dgram_native, sizeof(dgram_native)-1 },
  { "console", console_native, sizeof(console_native)-1 },
  { "buffer", buffer_native, sizeof(buffer_native)-1 },
    ....
}

这个文件被包含在node_javascript.cc里,node_javascript.cc提供了两个接口:
MainSource() 处理node_native源码返回v8::Handle类型的数据可供编译。
DefineJavaScript(target) 把其他所有模块源码变成v8::Handle类型后加载到传入的target对象上。

所有的js模块都被转换成了C数组,接下来看看它们怎么执行和互相调用。
(更多…)

新浪微博node.js SDK

2011-4-5 评论(2) 分类:作品 Tags:

最近用node.js做东西,要连接到新浪微博,就写了这个新浪微博node.js SDK:node-weibo-oauth,其实这应该叫库不该叫SDK吧,但官方文档里这样写我也跟着这样写了。

用了node-oauth,就是node.js的OAuth库,但我折腾老半天才会用这个库,它只支持header认证,腾讯微博目前不支持header认证,就没弄腾讯微博了。

测试这个OAuth认证时我一直盯着新浪这个教程看,结果被误导了,怎么弄都是认证完后只给授权码不跳转到callback地址。弄了很久才发现原来是要把callback地址传给oauth/authorize,我还以为只传给request token就行了,这个教程也是这么写的,为啥这里不说清楚呢,搞不懂,浪费挺多时间。

simple node.js web server with js server page

2011-2-19 评论(0) 分类:技术文章 Tags:

一开始捣鼓node.js时我就想用它快速建一个网页,但它没有自带的像jsp asp php那样可以把脚本嵌入页面的功能,尝试用john的micro-Template做一个很简单的能在页面嵌入脚本的web server
(更多…)