/* redisConnect()函数返回结构体,代表该Redis的连接句柄 */
typedef struct redisContext {
int err; /* Error flags, 0 when there is no error */
char errstr[128]; /* String representation of error */
int fd;
int flags;
char *obuf; /* Write buffer */
redisReader *reader; /* Protocol reader */
} redisContext;
/* redisCommand()函数返回结构体,代表该Redis命令操作的返回结果,通过type成员变量处理此结构体*/
typedef struct redisReply {
int type;
long long integer;
int len;
char *str;
size_t elements;
struct redisReply **element;
} redisReply;
redisReply结构体处理方式如下截图:
#define REDIS_REPLY_STRING 1
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3
#define REDIS_REPLY_NIL 4
#define REDIS_REPLY_STATUS 5
#define REDIS_REPLY_ERROR 6
#ifndef __LINK_REDIS__
#define __LINK_REDIS__
#include
#include
#include
#include
#include
using namespace std;
/*连接redis必须要的信息*/
struct LinkRedisInfo
{
string ip;
unsigned short port;
unsigned int timeOut; //超时时间
LinkRedisInfo(string ip_, unsigned short port_, unsigned int timeOut_):ip(ip_),\
port(port_),timeOut(timeOut_){}
};
class LinkRedis
{
private:
typedef map<string, pair > mp_redis;
typedef map<string, pair >::iterator mp_redis_iter;
mp_redis mp_link;
map<string,string > mp_error_str;
public:
LinkRedis();
~LinkRedis();
//注册Redis连接
bool RegisterLink(string name,string ip,unsigned short port,unsigned int timeOut);
//连接Redis
bool ConnectRedis();
bool ConnectSingleRedis(string name);
//Redis操作错误信息打印
void RedisError(string name);
//Redis操作结果集同意处理函数
int RedisReplyDeal(redisReply *pReply);
//Redis命令执行函数(不支持二进制)
redisReply* RedisExce(const char *name,const char *pCommand);
//Redis命令执行函数(支持二进制)
redisReply* RedisExceBinSafe(const char *name,const char *pCommand,char *pNode,unsigned int len);
//Redis命令执行&结果导出函数(结果导出至int动态数组)
bool RedisCommand2Int(const char *name,const char *pCommand,vector<int> *pVer);
//Redis命令执行&结果导出函数(结果导出至string动态数组)
bool RedisCommand2String(const char *name,const char *pCommand,vector<string> *pVer);
};
#endif
#include "linkRedis.h"
LinkRedis::LinkRedis()
{
}
//释放所有的连接资源
LinkRedis::~LinkRedis()
{
for(mp_redis_iter it= mp_link.begin();it!= mp_link.end();it++)
{
if(it->second.second!= NULL)
{
redisFree(it->second.second);
}
if(it->second.first!= NULL)
{
delete it->second.first;
}
}
}
/*
*@funs: 注册Redis连接信息
*@param name: 自定义连接名
*@param ip: Redis IP地址
*@param port: Redis PORT端口
*@param timeOut: Redis连接超时时间
*@ret: true/注册成功 false/注册失败
*/
bool LinkRedis::RegisterLink(string name,string ip,unsigned short port,unsigned int timeOut)
{
bool bRet= false;
LinkRedisInfo *pInfo= new LinkRedisInfo(ip,port,timeOut);
if(pInfo!= NULL)
{
mp_link[name].first= pInfo;
mp_link[name].second= NULL;
mp_error_str[name]= "";
bRet= true;
}
return bRet;
}
/*
*@funs: 连接name对应信息的Redis
*@param name: 自定义连接名
*@ret: true/连接成功 false/连接失败
*/
bool LinkRedis::ConnectSingleRedis(string name)
{
bool bRet= false;
mp_redis_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
struct timeval tv;
tv.tv_sec= it->second.first->timeOut;
tv.tv_usec= 0;
if(NULL!= (it->second.second= redisConnectWithTimeout(it->second.first->ip.c_str(),\
it->second.first->port,tv)))
{
bRet= true;
}
}
return bRet;
}
/*
*@funs: 连接注册过的所有Redis信息
*@ret: true/连接成功 false/连接失败
*/
bool LinkRedis::ConnectRedis()
{
bool bRet= true;
for(mp_redis_iter it= mp_link.begin();it!= mp_link.end();it++)
{
if(!ConnectSingleRedis(it->first))
{
bRet= false;
}
}
return bRet;
}
void LinkRedis::RedisError(string name)
{
map<string,string >::iterator it= mp_error_str.find(name);
if(it!= mp_error_str.end())
{
cout<< it->second.c_str()<< endl;
}
}
/*
*@funs: redis查询结果统一处理函数
*@param 1: redisCommand函数返回结果
*@ret: -1/reids操作错误 0/返回结果为空 >0/redis操作正常
*/
int LinkRedis::RedisReplyDeal(redisReply *pReply)
{
int ret= -1;
if(pReply!= NULL)
{
switch(pReply->type)
{
case REDIS_REPLY_NIL:
ret= 0;
break;
case REDIS_REPLY_ERROR:
ret= -1;
break;
default:
ret= pReply->type;
break;
}
}
return ret;
}
/*
*@funs: redis查询函数
*@param 1: redis连接名
*@param 2: redis Command操作指令
*@ret: NULL/reids操作错误 非NULL/返回redis操作正常结果
*/
redisReply* LinkRedis::RedisExce(const char *name,const char *pCommand)
{
redisReply* pReply= NULL;
if(name!= NULL && pCommand!= NULL)
{
mp_redis_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
//执行command命令
pReply =(redisReply*) redisCommand(it->second.second,pCommand);
if(pReply!= NULL)
{
//如果返回结果错误,则直接释放返回资源并记录错误信息
if(RedisReplyDeal(pReply)< 0)
{
//释放出错的操作结果集
freeReplyObject(pReply);
mp_error_str[name]= pReply->str;
mp_error_str[name].append(pCommand);
pReply= NULL;
}
}
}
}
return pReply;
}
/*
*@funs: redis二进制安全查询函数
*@param 1: redis连接名
*@param 2: redis Command操作指令
*@param 3: 二进制数据存储数组
*@param 4: 二进制数据长度
*@ret: NULL/reids操作错误 非NULL/返回redis操作正常结果
*/
redisReply* LinkRedis::RedisExceBinSafe(const char *name,const char *pCommand,char *pNode,unsigned int len)
{
redisReply* pReply= NULL;
if(name!= NULL && pCommand!= NULL && pNode!= NULL && len> 0)
{
mp_redis_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
pReply =(redisReply*) redisCommand(it->second.second,pCommand,pNode,len);
if(pReply!= NULL)
{
//如果返回结果错误,则直接释放返回资源并记录错误信息
if(RedisReplyDeal(pReply)< 0)
{
//释放出错的操作结果集
freeReplyObject(pReply);
mp_error_str[name]= pReply->str;
mp_error_str[name].append(pCommand);
pReply= NULL;
}
}
}
}
return pReply;
}
/*
*@funs: redis查询&结果导出函数
*@param 1: redis连接名
*@param 2: redis Command操作指令
*@param 3: redis Command操作结果存放地址
*@ret: true/reids操作成功 false/redis操作失败
*/
bool LinkRedis::RedisCommand2Int(const char *name,const char *pCommand,vector<int> *pVer)
{
bool bRet= false;
if(pVer!= NULL && name!= NULL && pCommand!= NULL)
{
redisReply* pReply= RedisExce(name,pCommand);
if(pReply== NULL)
{
return bRet;
}
//如果返回单个数值,则直接放至动态数组
if(pReply->type== REDIS_REPLY_INTEGER)
{
pVer->push_back(pReply->integer);
bRet= true;
}
else if(pReply->type== REDIS_REPLY_ARRAY)
{
redisReply* pTmp= NULL;
//如果返回数组,则取出每个数组中值并存放至动态数组
for(int i= 0;i< pReply->elements;i++)
{
pTmp= pReply->element[i];
if(RedisReplyDeal(pTmp)> 0 && pTmp->type== REDIS_REPLY_INTEGER)
{
pVer->push_back(pTmp->integer);
freeReplyObject(pTmp);
}
else
{
continue;
}
}
if(pVer->size()== pReply->elements)
bRet= true;
}
freeReplyObject(pReply);
}
return bRet;
}
/*
*@funs: redis查询&结果导出函数
*@param 1: redis连接名
*@param 2: redis Command操作指令
*@param 3: redis Command操作结果存放地址
*@ret: true/reids操作成功 false/redis操作失败
*/
bool LinkRedis::RedisCommand2String(const char *name,const char *pCommand,vector<string> *pVer)
{
bool bRet= false;
if(pVer!= NULL && name!= NULL && pCommand!= NULL)
{
redisReply* pReply= RedisExce(name,pCommand);
if(pReply== NULL)
{
return bRet;
}
if(pReply->type== REDIS_REPLY_STRING)
{
pVer->push_back(pReply->str);
bRet= true;
}
else if(pReply->type== REDIS_REPLY_ARRAY)
{
redisReply* pTmp= NULL;
for(int i= 0;i< pReply->elements;i++)
{
pTmp= pReply->element[i];
if(RedisReplyDeal(pTmp)> 0 && pTmp->type== REDIS_REPLY_STRING)
{
pVer->push_back(pTmp->str);
freeReplyObject(pTmp);
}
else
{
continue;
}
}
if(pVer->size()== pReply->elements)
bRet= true;
}
freeReplyObject(pReply);
}
return bRet;
}
#include "linkRedis.h"
#include
#include
#include
int main()
{
using namespace std;
LinkRedis test;
vector<string> info;
string name= "test1";
string ip= "172.16.4.70";
unsigned short= 7000;
int timeOut= 5;
test.RegisterLink(name,ip,port,timeOut);
//连接redis
if(test.ConnectRedis())
{
//执行redis命令,并将返回结果存储至动态字符串数组中
if(test.RedisCommand2String(name.c_str(),"hget 31196:3 Ip",&info))
{
for(int i= 0;i< info.size();i++)
{
cout<< info[i].c_str()<< endl;
}
}
else
{
test.RedisError(name);
}
}
else
{
cout<< "error !"<< endl;
}
return 1;
}