1.緣由
前幾天偶爾在網(wǎng)上看到thrift的信息饶套,其內(nèi)容和作用極大的引起了我的興趣饺律,因?yàn)槲乙彩亲鰅OS開發(fā)的,通過在網(wǎng)上的查詢發(fā)現(xiàn)信息雖然很多實(shí)用的很少啤覆,容易誤導(dǎo)他人,經(jīng)過自己的成功實(shí)踐惭聂,做了筆錄窗声,為了方便朋友了解和閱讀,就也啰里啰嗦的整理一下繁瑣的東西辜纲,希望對我的朋友和他人能有所幫助笨觅。
2.brew
我是在Mac上通過終端先安裝brew,再在終端輸入brew命令行來安裝thrift的耕腾,當(dāng)然還有其他的方式见剩,大家可以去網(wǎng)上了解一下,而我用brew是對其偏愛扫俺,是因?yàn)閎rew作為Mac OSX上的軟件包管理工具苍苞,能在Mac中方便的安裝軟件或者卸載軟件, 只需要一個命令狼纬, 而不用麻煩的終端命令羹呵,非常方便,另外brew 又叫Homebrew畸颅。具體安裝步驟非常簡單如下:
1担巩,打開終端,輸入ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"没炒。當(dāng)然也可以直接復(fù)制這個命令行粘貼到終端涛癌,按回車鍵
2,然后一會會跳出這個語句:Press RETURN to continue or any other key to abort送火,其意思就是按回車鍵繼續(xù)拳话,或者其他鍵跳出,當(dāng)然我們按回車鍵种吸,然后就開始安裝了弃衍。
3,注意坚俗,有時候過程可能稍慢镜盯,請耐心等候岸裙,其以上過程可能需要輸入你的本機(jī)賬號密碼,直接輸入然后按回車鍵即可速缆,
第一次我還不確定是否真的安裝成功降允,就有操作一次結(jié)果提醒我已經(jīng)安裝過,再次安裝會覆蓋以前的艺糜,所以大家不用擔(dān)心再次輸入操作剧董,如圖:
使用brew安裝軟件,通過在終端一行命令即可(brew的命令都是在終端輸入的)破停,如:sudo brew install git翅楼,就會安裝git,我們也可以sudo brew update更新brew真慢,常用命令列示如下:
1毅臊,sudo brew uninstall wget 卸載軟件wget
2,? sudo brew search /wge*/ 查詢軟件wget
3,? sudo brew list? ? ? ? ? 列出已安裝的軟件
4,? sudo brew home? ? ? 用瀏覽器打開brew的官方網(wǎng)站
5,? sudo brew info? ? ? ? 顯示軟件信息
6, ?sudo brew deps? ? ? ? 顯示包依賴
比如:輸入3,和4
3晤碘,thrift
當(dāng)然通過以上就知道如何安裝thrift了褂微,只需要在終端輸入brew命令行sudo brew install thrift,過程如圖:
注意過程很慢园爷,可從圖最下3.9%,最后安裝成功可從下圖比較:
一直到出現(xiàn)你的本機(jī)名的時候才算成功
安裝成功大家就可以使用thrift了,如果不了解thrift的朋友可以在網(wǎng)上查查童社,這里也做一些了解:
thrift最初由Facebook研發(fā)求厕,主要用于各個服務(wù)之間的RPC通信,支持跨語言扰楼,常用的語言ActionScript3,glibc,cocoa(開發(fā)ios用的),C++,C#,delphi,erlang,go,haskell,html,java,javame(山寨機(jī)開發(fā)),jquery,node.js,Ocaml,perl,php,python,ruby,smalltalk,xsd,簡單的說呀癣,就是可以讓人快速的寫Socket Server(服務(wù)器)和Client(客戶端)。其實(shí)不用thrift開發(fā)socket也不難弦赖,那么為什么要用thrift開發(fā)呢项栏?主要有兩個原因,一個是因?yàn)閠hrift本身幫你封裝了很多基本的東西蹬竖,你不需要自己去寫socket里面的bind沼沈,accept之類的,以及他們的邏輯币厕×辛恚可以很快速的開發(fā)基于進(jìn)程的,線程的旦装,SSL的socket页衙。第二個理由是標(biāo)準(zhǔn)化,跨語言和跨平臺,windows不算在其中店乐。主要是在各種Posix兼容的操作系統(tǒng)中都可以不需要改造基本直接可用艰躺,支持的語言種類也很多,基本你會寫的响巢,他都支持描滔。你不會寫的,他也支持踪古。類似的項(xiàng)目還有ICE和Avro,但是感覺都沒有thrift做的易用性好券腔。而且這是facebook開源的諸多項(xiàng)目中伏穆,為數(shù)不多的能正常編譯的軟件,
使用thrift需要先定義接口文件纷纫,在thrift里簡稱叫IDL枕扫,全稱叫Interface Description Language,接口描述語言辱魁。接口描述語言里面需要定義接口中所使用的數(shù)據(jù)類型烟瞧,方法等等
數(shù)據(jù)類型包括:
基本類型:
bool: 布爾類型(true或者false)
byte: 有符號8位整型
i16: 有符號16位整型
i32: 有符號32位整型
i64: 有符號64位整型
double: 64位浮點(diǎn)數(shù)
string: UTF8編碼的字符串
特殊類型:
binary: 未編碼的二進(jìn)制字節(jié)流
struct:結(jié)構(gòu)體類型
container:
list:列表,可以理解為數(shù)組染簇,其中的元素可以是任意類型的参滴。
exceptions:
用來拋出你自己定義的異常情況
service:
這個是最重要的定義,有些地方說是虛函數(shù)锻弓,但是理解成你程序中所使用的方法更容易明白一些砾赔。他需要你定義返回類型,這有點(diǎn)類似于C或者java的函數(shù)定義青灼。但你要明白暴心,這個返回是給socket的。如果你定義錯了杂拨,將不僅僅是你得不到返回值這么簡單的事情专普。而是程序會報錯
下面先聚一下網(wǎng)上的一個例子操作了一下還可以:來嘗試寫第一個thrift文件
test.thrift
service test
{
string GetSysVer()
#一個獲取系統(tǒng)版本的方法,返回給socket一個字符串
string FileTransfer(1:string filename, 2:binary content )
#傳送文件的方法弹沽,入口參數(shù)為string類型的文件名和二進(jìn)制流類型的文件內(nèi)容檀夹,方法將給socket一個字符串類型的返回值,如果你需要傳送結(jié)構(gòu)體贷币,可以在Service外面定義struct File{1:string filename,2:binary content,3:i64:filelen...}等等击胜,然后用list類型賦值給入口參數(shù),例如string FileTransfer(1:list transfer)
bool FileExists(1:string filename)
#檢查server端指定文件是否存在役纹,返回布爾
}
假設(shè)我們用Python來寫接口:thrift --gen py test.thrift
server端文件:
host = '0.0.0.0'
#監(jiān)聽地址
port = 12345
#監(jiān)聽端口
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端就寫完了偶摔,來看下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)
整個Server和Client就寫完了,服務(wù)器端的代碼TThreadedServer是多線程的服務(wù)器促脉,可以換成TThreadPoolServer基于線程池的辰斋,TSimpleServer是單線程的策州,TForkingServer基于新啟進(jìn)程的等等根據(jù)需要變換。
當(dāng)然不僅僅是用python宫仗,用什么語言取決于你生成什么樣的文件够挂,更取決于你的項(xiàng)目需求。主要的好處就是標(biāo)準(zhǔn)化和跨語言做的很好
而在iOS客戶端藕夫,在項(xiàng)目中使用孽糖,首先項(xiàng)目中要添加thrift框架,就是從官方gitHub https://github.com/apache/thrift 毅贮,下載源碼办悟,然后找到 lib/cocoa,將其拷貝到你工程里,就可以了
目前,我了解的就這么多滩褥,第一次寫東西病蛉,不妥之處望大家海涵.......