Thrift c++ server / java client配置
在安裝thrift前需要安裝libevent,用於生成對應的lib連結。
server端
Linux配置
1.下載
從官網http://thrift.apache.org/上下載thrift-0.8.0版本,之前使用的是0.9.3版本,編譯時會報錯,因而改成了0.8.0版本。
2.解壓thrift壓縮檔案
tar zxvf thrift-0.8.0.tar.gz
3.安裝
進入到thrift-0.8.0目錄
cd thrift-0.8.0
執行
./configure --prefix=/usr/local/ --with-boost=/usr/local --without-php
make
make install
安裝時遇到如下錯誤
./configure --prefix=/usr/local/
thift configure: error: "Error: libcrypto required."
這個問題百度了下是缺少某些軟體導致的,但是因為虛擬機器配置問題一直上不了網,就只能依靠網上的建議手動安裝某些軟體來解決這個問題,然而安裝了很多東西還是不行,掙扎許久還是先去解決上網問題了·······
可以上網後,解決Error: libcrypto required.問題:
安裝 openssl openssl-devel (centOS)
yum -y install openssl openssl-devel
./configure --prefix=/usr/local/
執行後發現yum命令報錯:
This system is not registered with RHN
Redhat之所以會出現這個錯誤是因為沒有註冊RHN,只需要更新一下yum的源就可以了。
解決:
進入yum的配置目錄
cd /etc/yum.repos.d/
下載CentOS- Base.repo檔案
wget http://docs.linuxtone.org/soft/lemp/CentOS-Base.repo
將原有的rhel-debuginfo.repo備份一下
cp rhel-debuginfo.repo rhel-debuginfo2.repo
將CentOS- Base.repo重新命名成rhel-debuginfo.repo
mv CentOS-Base.repo rhel-debuginfo.repo
安裝成功
yum install build-essential
此時再次執行
./configure --prefix=/usr/local/ --with-boost=/usr/local --without-php
make
make install
在終端輸入 thrift –version 終於安裝成功
Thrift安裝總結:之前嘗試在windows下配置c++作為伺服器端,java作為客戶端封裝thrift,但是thrift編譯後總是一執行就各種出錯,多次嘗試失敗後只好換到了linux下進行配置和安裝=_=
4.定義thrift檔案
user.thrift
struct User{
1: string uid,
2: string uname,
3: bool usex,
4: i16 uage,
}
service UserService{
void add(1: User u),
User get(1: string uid),
}
5.通過thrift的shell工具命令生成c++,java程式碼框架
Shell程式碼
thrift -r --gen cpp user.thrift
thrift -r --gen java user.thrift
通過執行以上命令:會生成子目錄gen-cpp,gen-java。
6.通過執行如下命令,生成C/C++服務端程式碼
Shell程式碼
cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp
7.修改服務端的程式碼,如下所示
#include "UserService.h"
#include <config.h>
#include <protocol/TCompactProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
#include <concurrency/ThreadManager.h>
#include <concurrency/PosixThreadFactory.h>
#include <server/TThreadPoolServer.h>
#include <server/TThreadedServer.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace ::apache::thrift::concurrency;
using boost::shared_ptr;
class UserServiceHandler : virtual public UserServiceIf {
public:
UserServiceHandler() {
}
void add(const User& u) {
printf("uid=%s uname=%s usex=%d uage=%d\n", u.uid.c_str(), u.uname.c_str(), u.usex, u.uage);
if(u.uage<5)
printf("too young");
}
void get(User& _return, const std::string& uid) {
_return.uid = uid;
_return.uname = "喵";
_return.usex = "妹子";
_return.uage = 7;
printf("uid=%s uname=%s usex=%d uage=%d\n", _return.uid.c_str(), _return.uname.c_str(), _return.usex, _return.uage);
}
};
int main(int argc, char **argv) {
shared_ptr<UserServiceHandler> handler(new UserServiceHandler());
shared_ptr<TProcessor> processor(new UserServiceProcessor(handler));
shared_ptr<TProtocolFactory> protocolFactory(new TCompactProtocolFactory());
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));
shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(10);
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
printf("start user server...\n");
TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);
server.serve();
return 0;
}
這裡使用的是TCompactProtocol,則需要#include<config.h>
,還有就是Blocking的多執行緒伺服器。
8.執行如下命令
g++ -g -o UserServer -I /usr/local/include/thrift -I /usr/include/boost/ -I ./gen-cpp -L /usr/local/lib -lthrift UserServer.cpp ./gen-cpp/user_types.cpp ./gen-cpp/user_constants.cpp ./gen-cpp/UserService.cpp
剛開始執行報錯,滿滿一頁錯誤簡直喪心病狂,各種找不到檔案,因為是按照別人的教程配置的,很多安裝細節可能不一樣,最後只好根據需要把src檔案重新命名為thrift放到/usr/local/include/下,並把boost放到/usr/include/下,以及把找不到的config.h放到需要的目錄下,再次執行發現錯誤少了不少,果然是缺少檔案的原因。
但是還有報錯資訊顯示thrift自帶的包有問題,查詢報錯的位置,發現是沒有加this->引發的錯誤,加上之後伺服器端終於可以運行了,激動哭/(ㄒoㄒ)/~~
client端
Linux下客戶端配置:
執行java程式需要有jdk,發現虛擬機器上未安裝,於是使用yum安裝,一切順利,但是奇怪的是環境變數配置好後,javac命令居然找不到,到對應的路徑下發現居然真的沒有這個命令·········重新解除安裝安裝多次未果,只好用windows搜尋需要的壓縮包手動匯入了,以下為java安裝過程:
1.先解除安裝伺服器自帶的jdk軟體包
rpm -qa | grep jdk
yum -y remove 顯示的java名稱
2.從windows下載 jdk-7u67-linux-x64.tar.gz
偷個懶,直接解壓用filezilla匯入Linux下
3.移動到相應位置
mv jdk-7u67-linux-x64 /usr/lib/jvm/java7
4.新增jdk7.0到系統環境變數
cp /etc/profile /etc/profile.bak
vi /etc/profile
5.編輯新增下面的內容
export JAVA_HOME=/usr/lib/jvm/java7
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
6.儲存後在命令列輸入如下語句使配置立即生效
source /etc/profile
7.輸入如下語句判斷是否成功
java -version
客戶端java程式碼:
public static void main(String[] args) {
try {
TTransport transport;
String ip="x.x.x.x";
transport = new TSocket(ip, 9090);
TProtocol protocol = new TBinaryProtocol(transport);
UserService.Client client = new UserService.Client(protocol);
transport.open();
User u = new User();
u.uid = "001";
u.uname="22";
u.usex = "妹子";
u.uage = 3;
client.add(u);
System.out.println("新增使用者成功了喲!");
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException x) {
x.printStackTrace();
}
}
安裝成功後我就直接把java程式簡單粗暴的複製到linux下準備執行了,直接用javac執行的main函式,發現居然找不到jar包裡面的類,同時還各種報錯,後來才知道正確的開啟方式是要打成jar包再執行,簡直傻到哭o(╥﹏╥)o。
將jar包匯入linux下並執行jar包,當然前提是伺服器已經開啟。
java -jar client.jar
注:伺服器端執行後處於監聽狀態,此時需要再開一個session開啟客戶端,之前把伺服器停掉又開客戶端發現出不來結果還很奇怪=_=,最後可以成功的開始通訊了。
客戶端:
伺服器端:
補充:
Windows下的客戶端終於可以用了,原來一直覺得是windows這邊的防火牆的問題,各種配置未果,後來突然想到可能是linux下的防火牆,試了一下,果然是!!終於解決了,心情都舒暢了起來~
以下是解決方法:
1.先檢視linux下的防火牆配置
iptables -L -n
發現貌似windows能訪問的服務都包含在了裡面,於是猜測可能需要把伺服器這邊的埠開啟。
2.開啟防火牆配置檔案
vi /etc/sysconfig/iptables
3.新增如下一行後並儲存
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:9091
4.關閉後重新開啟防火牆
/etc/rc.d/init.d/iptables stop
/etc/rc.d/init.d/iptables start
再次使用windows下的客戶端進行訪問,發現真的成功了~好激動,撒花~✿✿ヽ(°▽°)ノ✿