最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node.js中RPC(遠程過程調(diào)用)的實現(xiàn)原理介紹

 更新時間:2014年12月05日 13:19:01   投稿:junjie  
這篇文章主要介紹了node.js中RPC(遠程過程調(diào)用)的實現(xiàn)原理介紹,本文基于一個簡單的RPC庫nodejs light_rpc實現(xiàn),需要的朋友可以參考下

剛接觸到RPC(遠程過程調(diào)用),就是可以在本地調(diào)用遠程機子上的程序的方法,看到一個簡單的nodejs實現(xiàn),用來學習RPC的原理很不錯:nodejs light_rpc

使用示例:

復制代碼 代碼如下:

//服務(wù)端
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端啟動程序,偵聽端口,實現(xiàn)提供給client調(diào)用的函數(shù)(如上述例子的combine和multiply),保存在一個對象里。
2.client端啟動程序,連接服務(wù)端,連接完成后發(fā)送describe命令,要求server返回它能提供調(diào)用的函數(shù)名。

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

5.client端調(diào)用server端的函數(shù):

1) 給傳入的callback函數(shù)生成一個唯一ID,稱為callbackId,記錄到client的一個對象里。
2) 包裝好以下數(shù)據(jù)發(fā)送給server端:調(diào)用函數(shù)名,JSON序列化后的參數(shù)列表,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端接收到上述信息,解析數(shù)據(jù),對參數(shù)列表反序列化,根據(jù)函數(shù)名和參數(shù)調(diào)用函數(shù)。

復制代碼 代碼如下:

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

7.函數(shù)運行完成后,把結(jié)果序列化,連同之前收到的callbackId發(fā)送回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端接收到函數(shù)運行結(jié)果和callbackId,根據(jù)callbackId取出回調(diào)函數(shù),把運行結(jié)果傳入回調(diào)函數(shù)中執(zhí)行。

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

幾個注意的點:

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

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

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

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

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

相關(guān)文章

  • nodejs 全局變量和全局對象知識點及用法詳解

    nodejs 全局變量和全局對象知識點及用法詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于nodejs 全局變量和全局對象知識點及用法等內(nèi)容,對此有興趣的朋友們可以學習參考下。
    2021-12-12
  • Node連接mysql數(shù)據(jù)庫方法介紹

    Node連接mysql數(shù)據(jù)庫方法介紹

    本篇文章主要介紹了Node連接mysql數(shù)據(jù)庫方法介紹。詳細的介紹了怎樣連接和操作數(shù)據(jù)庫,并舉例說明,有興趣的可以了解一下。
    2017-02-02
  • node版本升級npm命令警告原因及解決

    node版本升級npm命令警告原因及解決

    這篇文章主要為大家介紹了node版本升級npm命令警告原因解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • node爬取新型冠狀病毒的疫情實時動態(tài)

    node爬取新型冠狀病毒的疫情實時動態(tài)

    這篇文章主要介紹了node爬取新型冠狀病毒的疫情實時動態(tài),非常不錯,本文通過實例代碼給大家講解的非常詳細,需要的朋友可以參考下
    2020-02-02
  • node.js中優(yōu)雅的使用Socket.IO模塊的方法

    node.js中優(yōu)雅的使用Socket.IO模塊的方法

    Socket.IO是一個WebSocket庫,包括了客戶端的js和服務(wù)器端的node.js,它的目標是構(gòu)建可以在不同瀏覽器和移動設(shè)備上使用的實時應(yīng)用,這篇文章主要介紹了node.js中優(yōu)雅的使用Socket.IO模塊,需要的朋友可以參考下
    2022-12-12
  • nvm如何切換與管理node版本

    nvm如何切換與管理node版本

    這篇文章主要介紹了nvm如何切換與管理node版本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 簡述pm2常用命令集合及配置文件說明

    簡述pm2常用命令集合及配置文件說明

    這篇文章主要介紹了簡述pm2常用命令集合及配置文件說明,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • node.js實現(xiàn)BigPipe詳解

    node.js實現(xiàn)BigPipe詳解

    這篇文章主要介紹了node.js實現(xiàn)BigPipe詳解,BigPipe是 Facebook 開發(fā)的優(yōu)化網(wǎng)頁加載速度的技術(shù),BigPipe 的核心概念就是只用一個 HTTP 請求,只是頁面元素不按順序發(fā)送而已,需要的朋友可以參考下
    2014-12-12
  • Node.js模塊全局安裝路徑配置方法

    Node.js模塊全局安裝路徑配置方法

    今天小編就為大家分享一篇Node.js模塊全局安裝路徑配置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 使用node.js 制作網(wǎng)站前臺后臺

    使用node.js 制作網(wǎng)站前臺后臺

    本文給大家介紹實用node.js 制作網(wǎng)站前臺和后臺,非常的詳盡,有需要的朋友可以參考下
    2014-11-11

最新評論

平阴县| 德安县| 曲麻莱县| 留坝县| 九台市| 都兰县| 巴塘县| 安西县| 乐昌市| 黑水县| 巴林左旗| 朝阳县| 温泉县| 仁化县| 喀喇| 康马县| 靖西县| 井冈山市| 叙永县| 泸溪县| 仁怀市| 新竹县| 新乐市| 林州市| 兴仁县| 沅江市| 商都县| 临沧市| 秭归县| 叶城县| 蒙自县| 若羌县| 大厂| 略阳县| 建湖县| 双牌县| 宜川县| 繁峙县| 中西区| 赣州市| 乐都县|