0、什么是RPC
RPC(Remote Procedure Call - 遠程過程調用),是通過網絡從遠程計算機上請求服務,而不需要了解底層網路技術的細節。簡單點說,就是像調用本地服務(方法)一樣調用遠端的服務(方法)。
RPC與REST的區別
RPC是一種協議,REST是一種架構風格。
RPC以行為為中心,REST以資源為中心。當加入新功能時,RPC需要增加更多的行為,並進行調用。REST的話,調用方法基本不變。
RPC可以不基於HTTP協議,因此在后端語言調用中,可以采用RPC獲得更好的性能。REST一般是基於HTTP協議。
1、RPC框架Thrift(0.9.3)
Thrift是一種開源的高效的、支持多種編程語言的遠程服務調用框架。支持C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml 和 Delphi等諸多語言,能夠很好的進行跨語言調用。
Thrift官網: https://thrift.apache.org/
2、Thrift的簡單實踐(Windows)
2.1 安裝Thrift
在http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.exe這里可以下載Thrift的windows系統編譯版本。
該文件是一個綠色文件,可以放置在目錄中,進入該目錄的cmd,就可以直接使用thrift。輸入thrift -version
可以查看當前Thrift的版本。
至此,Thrift已完成安裝
2.2 編寫接口定義文件
在安裝好Thrift之后,需要我們編寫接口定義文件,用來約定服務和thrift類型的接口定義。
Thrift主要有一下這些類型:
- bool --簡單類型,true or false
- byte --簡單類型,單字符
- i16 --簡單類型,16位整數
- i32 --簡單類型,32位整數
- i64 --簡單類型,64位整數
- double --簡單類型,雙精度浮點型
- string --簡單類型,utf-8編碼字符串
- binary --二進制,未編碼的字符序列
- struct --結構體,對應結構體、類等對象類型
- list --list容器
- set --set容器
- map --map容器
- enum --枚舉類型
接下來,利用這些類型,編寫一個簡單的.thrift接口定義文件。
/* 1.thrift file content */
namespace js ThriftTest
namespace csharp ThriftTest
service ThriftTest{
double plus(1:double num1, 2:double num2)
}
更復雜的案例: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=test/ThriftTest.thrift;hb=HEAD
在利用thrift --gen js:node --gen js 1.thrift
來生成好客戶端代碼和服務端代碼。可以跟多個--gen 參數,來實現一次性生成多個語言的代碼。
2.3 利用Thrift實現nodeJS服務端
var thrift = require('thrift');
var ThriftTest = require("./gen-nodejs/ThriftTest");
var ttypes = require("./gen-nodejs/1_types");
var nodeServer = thrift.createServer(ThriftTest, {
//完成具體的事情
plus: function(n1, n2, callback){
console.log(`server request, n1 = ${n1}, n2 = ${n2}.`);
callback(null, n1 + n2);
}
});
//處理錯誤,假設不處理,如果客戶端強制斷開連接,會導致后端程序掛掉
nodeServer.on('error', function(err){
console.log(err);
});
nodeServer.listen(7410);
console.log('node server started... port: 7410');
//如果client的瀏覽器,通信采用http的時候,需要創建http server
var httpServer = thrift.createWebServer({
cors: {'*': true}, //配置跨域訪問
services: {
'/thrift': { //配置路徑映射
transport: thrift.TBufferedTransport,
protocol: thrift.TJSONProtocol,
processor: ThriftTest,
handler: { //具體的處理對象
plus: function(n1, n2, callback) {
console.log(`http request, n1 = ${n1}, n2 = ${n2}.`);
callback(null, n1 + n2);
}
}
}
}
});
httpServer.on('error', function(err) {
console.log(err);
});
httpServer.listen(7411);
console.log('http server started... port: 7411');
2.4 Node Client 調用
var thrift = require('thrift');
var ThriftTest = require('./gen-nodejs/ThriftTest');
var ttypes = require('./gen-nodejs/1_types');
transport = thrift.TBufferedTransport()
protocol = thrift.TBinaryProtocol()
var connection = thrift.createConnection("localhost", 7410, {
transport : transport,
protocol : protocol
});
connection.on('error', function(err) {
console.log(false, err);
});
var client = thrift.createClient(ThriftTest, connection);
var sum = client.plus(1, 1, function(err, result){
//connection.end(); //如果不關閉連接,那么強制斷開連接,將會導致后端出現error
if(err){
console.log(err);
return;
}
console.log(result);
});
2.5、Http Client 調用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Thrift Test Client</title>
</head>
<body>
<input type="text" id="num1"> + <input type="text" id="num2"> <button onclick="call()">=</button> <span id="result">?</span>
<!-- <script src="jquery.js"></script> -->
<script src="thrift.js"></script>
<script src="gen-js/1_types.js"></script>
<script src="gen-js/ThriftTest.js"></script>
<script>
var transport = new Thrift.Transport("http://127.0.0.1:7411/thrift");
var protocol = new Thrift.TJSONProtocol(transport);
var client = new ThriftTest.ThriftTestClient(protocol);
var el_result = document.getElementById('result');
function call(){
var num1 = +document.getElementById('num1').value,
num2 = +document.getElementById('num2').value;
client.plus(num1, num2, function(result) {
el_result.innerText = result;
alert('調用成功!');
});
}
</script>
<script>
</script>
</body>
</html>
注意:如果在thrift生成代碼時,使用了--gen js:jquery參數,那么在瀏覽器調用的時候,就必須依賴jquery。
3、demo地址
https://github.com/hstarorg/HstarDemoProject/tree/master/thrift_demo