Thrift簡單實踐


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的版本。

img1

至此,Thrift已完成安裝

2.2 編寫接口定義文件

在安裝好Thrift之后,需要我們編寫接口定義文件,用來約定服務和thrift類型的接口定義。

Thrift主要有一下這些類型:

  1. bool --簡單類型,true or false
  2. byte --簡單類型,單字符
  3. i16 --簡單類型,16位整數
  4. i32 --簡單類型,32位整數
  5. i64 --簡單類型,64位整數
  6. double --簡單類型,雙精度浮點型
  7. string --簡單類型,utf-8編碼字符串
  8. binary --二進制,未編碼的字符序列
  9. struct --結構體,對應結構體、類等對象類型
  10. list --list容器
  11. set --set容器
  12. map --map容器
  13. 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM