1.緣由
前幾天偶爾在網(wǎng)上看到thrift的信息,其內(nèi)容和作用極大的引起了我的興趣,因?yàn)槲乙彩亲鰅OS開(kāi)發(fā)的,通過(guò)在網(wǎng)上的查詢(xún)發(fā)現(xiàn)信息雖然很多實(shí)用的很少,容易誤導(dǎo)他人,經(jīng)過(guò)自己的成功實(shí)踐,做了筆錄,為了方便朋友了解和閱讀,就也啰里啰嗦的整理一下繁瑣的東西,希望對(duì)我的朋友和他人能有所幫助。
2.brew
我是在Mac上通過(guò)終端先安裝brew,再在終端輸入brew命令行來(lái)安裝thrift的,當(dāng)然還有其他的方式,大家可以去網(wǎng)上了解一下,而我用brew是對(duì)其偏愛(ài),是因?yàn)閎rew作為Mac OSX上的軟件包管理工具,能在Mac中方便的安裝軟件或者卸載軟件, 只需要一個(gè)命令, 而不用麻煩的終端命令,非常方便,另外brew 又叫Homebrew。具體安裝步驟非常簡(jiǎn)單如下:
1,打開(kāi)終端,輸入ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"。當(dāng)然也可以直接復(fù)制這個(gè)命令行粘貼到終端,按回車(chē)鍵
2,然后一會(huì)會(huì)跳出這個(gè)語(yǔ)句:Press RETURN to continue or any other key to abort,其意思就是按回車(chē)鍵繼續(xù),或者其他鍵跳出,當(dāng)然我們按回車(chē)鍵,然后就開(kāi)始安裝了。
3,注意,有時(shí)候過(guò)程可能稍慢,請(qǐng)耐心等候,其以上過(guò)程可能需要輸入你的本機(jī)賬號(hào)密碼,直接輸入然后按回車(chē)鍵即可,
第一次我還不確定是否真的安裝成功,就有操作一次結(jié)果提醒我已經(jīng)安裝過(guò),再次安裝會(huì)覆蓋以前的,所以大家不用擔(dān)心再次輸入操作,如圖:
使用brew安裝軟件,通過(guò)在終端一行命令即可(brew的命令都是在終端輸入的),如:sudo brew install git,就會(huì)安裝git,我們也可以sudo brew update更新brew,常用命令列示如下:
1,sudo brew uninstall wget 卸載軟件wget
2,? sudo brew search /wge*/ 查詢(xún)軟件wget
3,? sudo brew list? ? ? ? ? 列出已安裝的軟件
4,? sudo brew home? ? ? 用瀏覽器打開(kāi)brew的官方網(wǎng)站
5,? sudo brew info? ? ? ? 顯示軟件信息
6, ?sudo brew deps? ? ? ? 顯示包依賴(lài)
比如:輸入3,和4
3,thrift
當(dāng)然通過(guò)以上就知道如何安裝thrift了,只需要在終端輸入brew命令行sudo brew install thrift,過(guò)程如圖:
注意過(guò)程很慢,可從圖最下3.9%,最后安裝成功可從下圖比較:
一直到出現(xiàn)你的本機(jī)名的時(shí)候才算成功
安裝成功大家就可以使用thrift了,如果不了解thrift的朋友可以在網(wǎng)上查查,這里也做一些了解:
thrift最初由Facebook研發(fā),主要用于各個(gè)服務(wù)之間的RPC通信,支持跨語(yǔ)言,常用的語(yǔ)言ActionScript3,glibc,cocoa(開(kāi)發(fā)ios用的),C++,C#,delphi,erlang,go,haskell,html,java,javame(山寨機(jī)開(kāi)發(fā)),jquery,node.js,Ocaml,perl,php,python,ruby,smalltalk,xsd,簡(jiǎn)單的說(shuō),就是可以讓人快速的寫(xiě)Socket Server(服務(wù)器)和Client(客戶(hù)端)。其實(shí)不用thrift開(kāi)發(fā)socket也不難,那么為什么要用thrift開(kāi)發(fā)呢?主要有兩個(gè)原因,一個(gè)是因?yàn)閠hrift本身幫你封裝了很多基本的東西,你不需要自己去寫(xiě)socket里面的bind,accept之類(lèi)的,以及他們的邏輯。可以很快速的開(kāi)發(fā)基于進(jìn)程的,線(xiàn)程的,SSL的socket。第二個(gè)理由是標(biāo)準(zhǔn)化,跨語(yǔ)言和跨平臺(tái),windows不算在其中。主要是在各種Posix兼容的操作系統(tǒng)中都可以不需要改造基本直接可用,支持的語(yǔ)言種類(lèi)也很多,基本你會(huì)寫(xiě)的,他都支持。你不會(huì)寫(xiě)的,他也支持。類(lèi)似的項(xiàng)目還有ICE和Avro,但是感覺(jué)都沒(méi)有thrift做的易用性好。而且這是facebook開(kāi)源的諸多項(xiàng)目中,為數(shù)不多的能正常編譯的軟件,
使用thrift需要先定義接口文件,在thrift里簡(jiǎn)稱(chēng)叫IDL,全稱(chēng)叫Interface Description Language,接口描述語(yǔ)言。接口描述語(yǔ)言里面需要定義接口中所使用的數(shù)據(jù)類(lèi)型,方法等等
數(shù)據(jù)類(lèi)型包括:
基本類(lèi)型:
bool: 布爾類(lèi)型(true或者false)
byte: 有符號(hào)8位整型
i16: 有符號(hào)16位整型
i32: 有符號(hào)32位整型
i64: 有符號(hào)64位整型
double: 64位浮點(diǎn)數(shù)
string: UTF8編碼的字符串
特殊類(lèi)型:
binary: 未編碼的二進(jìn)制字節(jié)流
struct:結(jié)構(gòu)體類(lèi)型
container:
list:列表,可以理解為數(shù)組,其中的元素可以是任意類(lèi)型的。
exceptions:
用來(lái)拋出你自己定義的異常情況
service:
這個(gè)是最重要的定義,有些地方說(shuō)是虛函數(shù),但是理解成你程序中所使用的方法更容易明白一些。他需要你定義返回類(lèi)型,這有點(diǎn)類(lèi)似于C或者java的函數(shù)定義。但你要明白,這個(gè)返回是給socket的。如果你定義錯(cuò)了,將不僅僅是你得不到返回值這么簡(jiǎn)單的事情。而是程序會(huì)報(bào)錯(cuò)
下面先聚一下網(wǎng)上的一個(gè)例子操作了一下還可以:來(lái)嘗試寫(xiě)第一個(gè)thrift文件
test.thrift
service test
{
string GetSysVer()
#一個(gè)獲取系統(tǒng)版本的方法,返回給socket一個(gè)字符串
string FileTransfer(1:string filename, 2:binary content )
#傳送文件的方法,入口參數(shù)為string類(lèi)型的文件名和二進(jìn)制流類(lèi)型的文件內(nèi)容,方法將給socket一個(gè)字符串類(lèi)型的返回值,如果你需要傳送結(jié)構(gòu)體,可以在Service外面定義struct File{1:string filename,2:binary content,3:i64:filelen...}等等,然后用list類(lèi)型賦值給入口參數(shù),例如string FileTransfer(1:list transfer)
bool FileExists(1:string filename)
#檢查server端指定文件是否存在,返回布爾
}
假設(shè)我們用Python來(lái)寫(xiě)接口:thrift --gen py test.thrift
server端文件:
host = '0.0.0.0'
#監(jiān)聽(tīng)地址
port = 12345
#監(jiān)聽(tīng)端口
import sys
import os
import platform
sys.path.append('./gen-py')
from test import *
from test.ttypes import *
# Thrift files
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class testHandler:
def FileTransfer(self, filename, content):
filename = filename
content = content
f = open(filename,"wb")
f.write(content)
f.close()
return "1"
def FileExists(self, filename):
if os.path.isfile(filename):
return True
else:
return False
def GetSysVer(self):
system_ver = platform.platform()
if system_ver.find("el5") > 0:
title = '5'
elif system_ver.find("el6") > 0:
title = '6'
else:
title = 'Not CentOS'
return title
handler = testHandler()
processor = test.Processor(handler)
transport = TSocket.TServerSocket(host,port)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
print 'Starting server'
server.serve()
這樣server端就寫(xiě)完了,來(lái)看下client
host = '127.0.0.1'
port = 12345
import sys
import platform
sys.path.append('./gen-py')
from test import *
from test.ttypes import *
# Thrift files
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
# Init thrift connection and protocol handlers
transport = TSocket.TSocket(host , port)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
agent = test.Client(protocol)
transport.open()
res = agent.FileExists("/root/test.thrift")
if res == True:
print "True"
else:
print "False"
filename = "/tmp/Aptana_Studio_3_Setup_Linux_x86_64_3.0.9.zip"
#定義服務(wù)端文件名和保存路徑
f = open("./Aptana_Studio_3_Setup_Linux_x86_64_3.0.9.zip","rb")
#本地文件路徑
content = f.read()
f.close()
boolean = agent.FileTransfer(filename,content)
res = agent.GetSysVer()
print res
transport.close()
except Thrift.TException, tx:
print 'Something went wrong : %s' % (tx.message)
整個(gè)Server和Client就寫(xiě)完了,服務(wù)器端的代碼TThreadedServer是多線(xiàn)程的服務(wù)器,可以換成TThreadPoolServer基于線(xiàn)程池的,TSimpleServer是單線(xiàn)程的,TForkingServer基于新啟進(jìn)程的等等根據(jù)需要變換。
當(dāng)然不僅僅是用python,用什么語(yǔ)言取決于你生成什么樣的文件,更取決于你的項(xiàng)目需求。主要的好處就是標(biāo)準(zhǔn)化和跨語(yǔ)言做的很好
而在iOS客戶(hù)端,在項(xiàng)目中使用,首先項(xiàng)目中要添加thrift框架,就是從官方gitHub https://github.com/apache/thrift ,下載源碼,然后找到 lib/cocoa,將其拷貝到你工程里,就可以了
目前,我了解的就這么多,第一次寫(xiě)東西,不妥之處望大家海涵.......