LinuxC/C++编程基础(31) 使用thrift/rpc开发简单实例(续3)
来源:互联网 发布:上海网络布线点位价格 编辑:程序博客网 时间:2024/05/08 22:56
写在前面:本篇文字在前面几篇的基础上,做了很大部分深入的改动,但thrift/rpc的通信原理是一样的
thrift-client的实现:
一.thrift_pool类:
1.TTransport类的创建,如下:
shared_ptr<TTransport> ThriftPool::CreateConnection(const string ip, int port)
{
/*采用TCP Socket进行数据传输*/
shared_ptr<TSocket> socket(new TSocket(ip, port));
/*设置超时*/
socket->setConnTimeout(THRIFT_TIME_OUT);
socket->setSendTimeout(THRIFT_TIME_OUT);
socket->setRecvTimeout(THRIFT_TIME_OUT);
/*对Transport的数据进行buffer*/
shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
shared_ptr<TTransport> transport = bufferedSocket;
transport->open();
return transport;
}
2.TTransport类的关闭,如下:
void ThriftPool::TerminateConnection(shared_ptr<TTransport> transport)
{
/*NULL_PTR即为静态的空智能指针*/
if(transport != NULL_PTR)
{
transport->close();
}
}
3.获取连接的TTransport,如下:
shared_ptr<TTransport> ThriftPool::GetConnection(const string ip, int port)
{
shared_ptr<TTransport> conn;
scoped_lock lock(m_mutex);
if(conns.size() > 0)
/*调用CreateConnection获取TTransport类的实例,这里略去*/
/*conns的定义为queue< shared_ptr<TTransport> > conns;*/
return conn;
}
else{
/*调用CreateConnection获取TTransport类的实例,这里略去*/
/*与上述的不同之处在与是否判断conn是否打开*/
}
}
转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/8510479
二.QueueWithPool类
1.消息队列的定义及读写,如下:
queue< string > msgQueue;
void QueueWithPool::pushMsg(string msg)
{
boost::recursive_mutex::scoped_lock lock(m_queue_mutex);
msgQueue.push(msg);
}
string QueueWithPool::popMsg()
{
boost::recursive_mutex::scoped_lock lock(m_queue_mutex);
string tmp_msg = msgQueue.front();//返回第一个元素
msgQueue.pop();
return tmp_msg;
}
2.queueMsgProcessor的实现,如下:
void QueueWithPool::queueMsgProcessor(vector<std::string> &sp_salmon_servers)
{
bool isFirstConn = true;
string pre_server_addr = "";
unsigned int pre_server_count = -1;
int pre_idx = -1;
while (true)
{
/*读取消息队列中的消息并返回,实现简单,这里略去*/
boost::xtime nowTime;
boost::xtime_get(&nowTime, boost::TIME_UTC_);
if (nowTime.sec - lastLogTime.sec > 10)
{
printf("[QueueWithPool::queueMsgProcessor] Thrift message queue[%d] left size: %u\n", id, msgQueue.size());
lastLogTime = nowTime; // lastLogTime is the member variable
}
vector<std::string> ptr_salmon_servers = sp_salmon_servers;//服务器地址vector
if (ptr_salmon_servers.size() > 0)
{
/* salmon_servers is an argument. */
int retrycount = 0;
while (retrycount < 3)
{
/*根据具体策略选择服务器地址,实现简单,这里略去*/
string server_addr = ptr_salmon_servers[idx];
string::size_type pos = server_addr.find(':');
if (pos != string::npos)
{
ip = server_addr.substr(0, pos);//解析ip地址和端口
port = atoi(server_addr.substr(pos+1).c_str());
}
shared_ptr<TTransport> transport = thriftPool.NULL_PTR;
try
{
transport = thriftPool.GetConnection(ip, port);
if(transport == thriftPool.NULL_PTR || transport == 0x0)
{
printf("[QueueWithPool::queueMsgProcessor] Transport is invalid when sending thrift message\n");
retrycount++;
continue;
}
/*设置二进制的传输格式*/
shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
LinyanwenServletClient client(protocol);
/*发送消息*/
client.sendMessage(msg);
printf("[QueueWithPool::queueMsgProcessor] Received msg and send to server: %s\n", msg.c_str());
break;
}
catch(apache::thrift::TException e)
{
thriftPool.TerminateConnection(transport);
printf("[QueueWithPool::queueMsgProcessor] Send thrift message error\n");
}
retrycount ++;
}
}
else
{
printf("[QueueWithPool::queueMsgProcessor]No salmon server found!!!\n");
}
}
}
3.queueMsgProcessor的启动,如下:
void QueueWithPool::initialize(int qpid, vector<std::string> sp_salmon_servers, int arg_queueNum)
{
printf("[QueueWithPool::initialize] id=%d.\n",qpid);
id = qpid;
queueNum = arg_queueNum;
/*创建新线程启动*/
boost::thread thrd(boost::bind(&QueueWithPool::queueMsgProcessor, this, sp_salmon_servers));
}
转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/8510479
三.ServiceContainer类
1.类的定义,如下:
#ifndef _SERVICE_CONTAINER_H_
#define _SERVICE_CONTAINER_H_
#include "queue_with_pool.h"
#define QUEUE_NUM 3
class ServiceContainer{
public:
ServiceContainer(){}
~ServiceContainer(){}
void pushMsg(std::string& message);
public:
static const int queueNum = QUEUE_NUM;
QueueWithPool queue_pool[queueNum];
};
#endif
2.pushMsg方法的实现,如下:
void ServiceContainer::pushMsg(std::string& message){
printf("[ServiceContainer::pushMsg]\n");
int queue_no = 1;
queue_pool[queue_no].pushMsg(message);
}
四.main.cpp的实现,如下:
#include <vector>
#include <string>
using boost::shared_ptr;
int main(int argc,char** argv){
std::vector<std::string> servers;
servers.push_back("localhost:5555");
servers.push_back("localhost:9999");
servers.push_back("localhost:3333");
ServiceContainer container;
for(int i=0;i<container.queueNum;++i){
printf("[main] Initialize queue_pool[%d].\n",i);
container.queue_pool[i].initialize(i,servers,container.queueNum);
}
while(true){
std::string msg = "linyanwen";
container.pushMsg(msg);
sleep(1);
}
return 0;
}
参考文字:柳大,http://my.csdn.net/Poechant
转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/8510479
- LinuxC/C++编程基础(31) 使用thrift/rpc开发简单实例(续3)
- LinuxC/C++编程基础(23) 使用thrift/rpc开发简单实例(续1)
- LinuxC/C++编程基础(24) 使用thrift/rpc开发简单实例(续2)
- LinuxC/C++编程基础(32) 使用thrift/rpc开发简单实例(续4)
- LinuxC/C++编程基础(22) 使用thrift/rpc开发简单实例
- LinuxC/C++编程基础(21) 使用boost::asio搭建服务器简单实例(续)
- LinuxC/C++编程基础(20) 使用boost::asio搭建服务器简单实例
- LinuxC/C++编程基础(7) boost::mutex的简单实例
- LinuxC/C++编程基础(13) shell脚本简单实例
- LinuxC/C++编程基础(35) std::istream使用实例
- thrift 简单安装以及rpc使用心得
- linuxc编程一站式学习(c基础)
- RPC-Thrift简单应用
- LinuxC/C++编程基础(34) 虚函数编程实例
- linuxC编程基础
- LinuxC基础编程
- LinuxC/C++编程基础(29) syslog-ng配置实例
- LinuxC/C++编程基础(10) quicksort的简单实现
- Ten sentences that will give you courage
- erlang四大behaviour之一gen_server
- C Export 读书笔记
- MySQL主从复制与读写分离
- 澳大利亚兽医伏特加酒当点滴救活给中毒小狗
- LinuxC/C++编程基础(31) 使用thrift/rpc开发简单实例(续3)
- 黑客反击战(全)
- 关于游戏中的特效
- freopen (stdin stdout ) 详解+实例 (转)
- 在vim中去掉^M
- 手把手叫你玩转网络编程系列之三 ---------完成端口(Completion Port)详解
- erlang四大behaviour之二-gen_fsm
- 浅谈SQL Server中的快照
- 返回局部变量指针的问题