亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

node.js中RPC(遠程過程調用)的實現原理介紹

2019-11-20 13:48:38
字體:
來源:轉載
供稿:網友

剛接觸到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);
        }
    });
});

簡單說說整個過程:

1.server端啟動程序,偵聽端口,實現提供給client調用的函數(如上述例子的combine和multiply),保存在一個對象里。
2.client端啟動程序,連接服務端,連接完成后發送describe命令,要求server返回它能提供調用的函數名。

復制代碼 代碼如下:

connection.on('connect', function(){
  connection.write(command(descrCmd));
});

3.server端接收到describe命令,把自己可供調用的函數名包裝好發送出去(“combine”, “multiply”)
4.client端接收到server發送的函數名,注冊到自己的對象里,給每個函數名包裝一個方法,使本地調用這些函數時實際上是向server端發送請求:

復制代碼 代碼如下:

for(var p in cmd.data){
  remoteObj[p] = getRemoteCallFunction(p, self.callbacks, connection);
  //getRemoteCallFunction的實現見下面
}

5.client端調用server端的函數:

1) 給傳入的callback函數生成一個唯一ID,稱為callbackId,記錄到client的一個對象里。
2) 包裝好以下數據發送給server端:調用函數名,JSON序列化后的參數列表,callbackId

復制代碼 代碼如下:

function getRemoteCallFunction(cmdName, callbacks, connection){
  return function(){
    var id = uuid.generate();
    if(typeof arguments[arguments.length-1] == 'function'){
      callbacks[id] = arguments[arguments.length-1];
    }
    var args = parseArgumentsToArray.call(this, arguments);
    var newCmd = command(cmdName, {id: id, args: args});
    connection.write(newCmd);
  }
}

6.server端接收到上述信息,解析數據,對參數列表反序列化,根據函數名和參數調用函數。

復制代碼 代碼如下:

var args = cmd.data.args;
args.push(getSendCommandBackFunction(c, cmd.data.id));
self.wrapper[cmd.command].apply({}, args);

7.函數運行完成后,把結果序列化,連同之前收到的callbackId發送回client端

復制代碼 代碼如下:

function getSendCommandBackFunction(connection, cmdId){
  return function(){
    var innerArgs = parseArgumentsToArray.call({}, arguments);
    var resultCommand = command(resultCmd, {id: cmdId, args: innerArgs});
    connection.write(resultCommand);
  };
}

8.client端接收到函數運行結果和callbackId,根據callbackId取出回調函數,把運行結果傳入回調函數中執行。

9.整個過程完成,詳見源碼:https://github.com/romulka/nodejs-light_rpc

幾個注意的點:

1.整個過程中client和server一直保持連接,不像http協議發送和接收完就斷開鏈接,所以不能以斷開鏈接判斷一次數據的傳送完成。為了判斷數據接收完成,client和server發送的數據遵循一個簡單的協議:在數據前加上數據包的長度和分隔符,如定分隔符為/n:[數據包長度/n數據],這樣在收到數據后首先取出數據包的長度,再不斷判斷累計已接收到的數據包是否等于或超過這個長度,若是則一次數據傳送完成,可以開始解析提取數據。

2.這個RPC簡單在于沒有考慮參數里有函數類型的情況,例如有參數是一個object,這個object下有函數成員,JSON序列化時會把函數忽略,在server端是執行不了這個函數的。

為了解決這個問題,需要進行復雜的處理:

1.深度遍歷每個要發送給遠端的參數,把函數成員抽出來,給這個函數生成唯一id,放到本地一個對象里,把這個函數成員替換成這個id字符串,并標識這個成員實際上是一個函數。這樣這個對象就可以序列化發送出去了。
2.server接收到調用,當要使用參數object里的函數時,判斷到這是一個經過client處理過的函數,有一個id,把這個id發送回client端,并用同樣的方法把自身的回調函數id傳給client,等待client端的回調。
3.client端接收到這個函數id,找到這個函數實體,調用,完成后根據server端給的回調id發送回給server端
4.server端收到結果,找到回調函數,繼續執行,完成。

函數的記錄方法可以以其他方式完成,大體思路就是把函數替換成可序列化的東西,記錄函數以便remote端調用時能在本地找到這個函數??梢詤⒖糳node的實現。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久av一区| 久久精品视频导航| 国产精品伦子伦免费视频| 亚洲影视九九影院在线观看| 国产精品第七十二页| 亚洲精品国产电影| 日韩视频精品在线| 国产欧美精品在线| 91精品久久久久久久久青青| 国产一区二区三区四区福利| 日韩av最新在线观看| 欧美综合国产精品久久丁香| 另类少妇人与禽zozz0性伦| 日韩精品极品毛片系列视频| 亚洲一区二区三区乱码aⅴ| 亚洲午夜精品久久久久久久久久久久| 国产精品福利无圣光在线一区| 日韩中文字幕网址| 在线视频免费一区二区| 国产香蕉一区二区三区在线视频| 黄色91在线观看| 三级精品视频久久久久| 国产性猛交xxxx免费看久久| 亚洲影院高清在线| 日本高清不卡的在线| 欧美日韩aaaa| 亚洲丝袜一区在线| 久久成人精品视频| 免费av在线一区| 热99久久精品| 欧美激情在线一区| 亚洲第一二三四五区| 日韩av大片在线| 久久精品福利视频| 亚洲成年人影院在线| 亚洲欧美制服另类日韩| 国产精品video| 草民午夜欧美限制a级福利片| 亚洲精品日韩在线| 欧美精品中文字幕一区| 日韩美女免费观看| 欧美亚洲激情视频| 91av在线免费观看视频| 中国china体内裑精亚洲片| 欧美久久精品一级黑人c片| 成人a在线视频| 色噜噜狠狠狠综合曰曰曰| 欧美在线视频播放| 北条麻妃一区二区在线观看| 91亚洲精品久久久久久久久久久久| 伊人久久大香线蕉av一区二区| 亚洲精品成人久久久| 国产主播喷水一区二区| 欧美成人精品激情在线观看| 亚洲色图狂野欧美| 国产成人一区三区| 国产日韩欧美日韩| 亚洲欧洲午夜一线一品| 色综合久久久久久中文网| 韩日欧美一区二区| 成人黄色免费片| 久久久久九九九九| 欧美激情亚洲国产| 亚洲人av在线影院| 色先锋久久影院av| 国产精品精品一区二区三区午夜版| 日韩av在线网页| 色无极影院亚洲| 国产欧美日韩专区发布| 91成品人片a无限观看| 国产成人精品国内自产拍免费看| 欧美精品videosex极品1| 免费97视频在线精品国自产拍| 欧美华人在线视频| 亚洲人成啪啪网站| 91中文精品字幕在线视频| 国产精品久久久久久久久久| 国产一区二区三区日韩欧美| 在线视频一区二区| 国产精品日韩欧美大师| www.日韩视频| 亚洲激情在线观看视频免费| 国产亚洲一区二区在线| 国产精品国产自产拍高清av水多| 国产精品香蕉在线观看| 欧美中文字幕视频| 亚洲精品久久7777777| 欧美国产日韩一区二区在线观看| 亚洲男人天堂2019| 亚洲国产私拍精品国模在线观看| 欧美激情乱人伦| 亚洲国产成人爱av在线播放| 亚洲人成网站色ww在线| 成人福利视频在线观看| 自拍视频国产精品| 亚洲人成亚洲人成在线观看| 91精品国产综合久久香蕉| 色偷偷亚洲男人天堂| 日韩中文字幕在线精品| 久久免费视频这里只有精品| 亚洲国产美女精品久久久久∴| 久久久中文字幕| 91精品视频在线播放| 日韩精品在线观看一区二区| 久久久久久久久久久国产| 久久视频免费观看| 国产精品高潮在线| 亚洲欧美国产日韩天堂区| 亚洲国内精品视频| 日韩综合视频在线观看| 欧美在线欧美在线| 国产日韩精品入口| 久久伊人精品天天| 日韩美女在线观看| 欧美成人黑人xx视频免费观看| 亚洲日韩欧美视频一区| 韩国一区二区电影| 3344国产精品免费看| 日韩精品免费综合视频在线播放| 精品国产依人香蕉在线精品| 国产精品久久婷婷六月丁香| 色噜噜国产精品视频一区二区| 国产一区二区精品丝袜| 欧美一级电影免费在线观看| 欧美在线视频观看免费网站| 亚洲日韩中文字幕| 国产精品美女无圣光视频| xxxx欧美18另类的高清| 日韩不卡中文字幕| 午夜精品久久久久久久白皮肤| 在线成人免费网站| 国产精品日韩在线观看| 久久69精品久久久久久久电影好| 国产精品欧美一区二区三区奶水| 中文字幕成人精品久久不卡| 国产在线视频欧美| 欧美巨大黑人极品精男| 69久久夜色精品国产7777| 欧美激情小视频| 国产一区私人高清影院| 国产大片精品免费永久看nba| 欧美激情视频在线免费观看 欧美视频免费一| 日韩电影中文字幕在线观看| 国产精品久久久久免费a∨| 欧美色视频日本高清在线观看| 丝袜情趣国产精品| 日本欧美国产在线| 亚洲老板91色精品久久| 国产精品草莓在线免费观看| 亚洲性xxxx| 亚洲美女视频网站| 国产日产欧美a一级在线| 亚洲精品欧美一区二区三区| 欧美在线视频播放| 亚洲女人天堂成人av在线| 久久精品欧美视频| 国产亚洲精品久久久久久牛牛| 欧美伊久线香蕉线新在线| 日韩欧美一区二区在线| 精品高清一区二区三区| 久久久亚洲福利精品午夜| 久久精品男人天堂| 日韩欧美高清视频| 亚洲人成电影网站|