剛接觸到RPC(遠(yuǎn)程過程調(diào)用),就是可以在本地調(diào)用遠(yuǎn)程機(jī)子上的程序的方法,看到一個簡單的nodejs實現(xiàn),用來學(xué)習(xí)RPC的原理很不錯:nodejs light_rpc
使用示例:
Sample client:
簡單說說整個過程:
1.server端啟動程序,偵聽端口,實現(xiàn)提供給client調(diào)用的函數(shù)(如上述例子的combine和multiply),保存在一個對象里。
2.client端啟動程序,連接服務(wù)端,連接完成后發(fā)送describe命令,要求server返回它能提供調(diào)用的函數(shù)名。
3.server端接收到describe命令,把自己可供調(diào)用的函數(shù)名包裝好發(fā)送出去(“combine”, “multiply”)
4.client端接收到server發(fā)送的函數(shù)名,注冊到自己的對象里,給每個函數(shù)名包裝一個方法,使本地調(diào)用這些函數(shù)時實際上是向server端發(fā)送請求:
5.client端調(diào)用server端的函數(shù):
1) 給傳入的callback函數(shù)生成一個唯一ID,稱為callbackId,記錄到client的一個對象里。
2) 包裝好以下數(shù)據(jù)發(fā)送給server端:調(diào)用函數(shù)名,JSON序列化后的參數(shù)列表,callbackId
6.server端接收到上述信息,解析數(shù)據(jù),對參數(shù)列表反序列化,根據(jù)函數(shù)名和參數(shù)調(diào)用函數(shù)。
7.函數(shù)運行完成后,把結(jié)果序列化,連同之前收到的callbackId發(fā)送回client端
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ù)的。
為了解決這個問題,需要進(jìn)行復(fù)雜的處理:
1.深度遍歷每個要發(fā)送給遠(yuǎn)端的參數(shù),把函數(shù)成員抽出來,給這個函數(shù)生成唯一id,放到本地一個對象里,把這個函數(shù)成員替換成這個id字符串,并標(biāo)識這個成員實際上是一個函數(shù)。這樣這個對象就可以序列化發(fā)送出去了。
2.server接收到調(diào)用,當(dāng)要使用參數(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)。
新聞熱點
疑難解答