欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

使用示例:

復制代碼 代碼如下:

//服務端
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端啟動程序,連接服務端,連接完成后發(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ù)運行完成后,把結果序列化,連同之前收到的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ù)運行結果和callbackId,根據(jù)callbackId取出回調(diào)函數(shù),把運行結果傳入回調(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端收到結果,找到回調(diào)函數(shù),繼續(xù)執(zhí)行,完成。

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

相關文章

  • 解決Mac安裝thrift因bison報錯的問題

    解決Mac安裝thrift因bison報錯的問題

    今天小編就為大家分享一篇解決Mac安裝thrift因bison報錯的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Node.js讀取文件操作教程示例

    Node.js讀取文件操作教程示例

    這篇文章主要為大家介紹了Node.js讀取文件教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Node.js如何實現(xiàn)注冊郵箱激活功能 (常見)

    Node.js如何實現(xiàn)注冊郵箱激活功能 (常見)

    今天了解了node如何實現(xiàn)郵箱激活功能,這個功能非常常見,當我們注冊一個賬號時,肯定會有這步,下面看下如何實現(xiàn)這個功能
    2017-07-07
  • node.js中的console.info方法使用說明

    node.js中的console.info方法使用說明

    這篇文章主要介紹了node.js中的console.info方法使用說明,本文介紹了console.info的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • node.js讀取Excel數(shù)據(jù)(下載圖片)的方法示例

    node.js讀取Excel數(shù)據(jù)(下載圖片)的方法示例

    這篇文章主要給大家介紹了關于node.js讀取Excel數(shù)據(jù)(下載圖片)的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用node.js具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • 阿里云OSS實踐文件直傳基于服務端

    阿里云OSS實踐文件直傳基于服務端

    這篇文章主要為大家介紹了阿里云OSS實踐文件直傳基于服務端實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 淺談node.js中async異步編程

    淺談node.js中async異步編程

    本文嘗試結合Marc Fasel的指導思想和筆者的實踐經(jīng)驗來介紹一些NodeJS的異步編程風格,希望對NodeJS的初學者有所啟發(fā)。
    2015-10-10
  • 詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務器

    詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務器

    這篇文章主要為大家介紹了詳解如何優(yōu)雅在webpack項目實現(xiàn)mock服務器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 詳解Node.js中的Async和Await函數(shù)

    詳解Node.js中的Async和Await函數(shù)

    這篇文章主要介紹了Node.js中的Async和Await函數(shù)的相關知識,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-02-02
  • Nodejs 復制文件/文件夾的方法

    Nodejs 復制文件/文件夾的方法

    這篇文章主要介紹了Nodejs 復制文件/文件夾的方法,需要的朋友可以參考下
    2017-08-08

最新評論