1.redis_client.hpp

#ifndef REDIS_CLIENT_HPP_
#define REDIS_CLIENT_HPP_
#include <hiredis/hiredis.h>
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
class redis_client {
public:
redis_client() {
conn_ = nullptr;
}
redis_client(const redis_client &) = delete;
redis_client & operator = (const redis_client &) = delete;
virtual ~redis_client() {
if (nullptr != conn_) {
redisFree(conn_);
conn_ = nullptr;
}
}
inline bool connect(const char *ip, int port) {
conn_ = redisConnect(ip, port);
if (nullptr == conn_) {
cerr << "connection is null...!" << endl;
return false;
}
if (conn_->err) {
cerr << "connection failed err = " << conn_->errstr << endl;
return false;
}
return true;
}
bool set_value(const char *key, const string &value) {
if (nullptr == conn_) {
cerr << "redis client conn is null...!" << endl;
return false;
}
if (value.size() > MAXVALUESIZE) {
cerr << "value size is over 1M...!" << endl;
return false;
}
size_t keylen = strlen(key);
if (keylen > MAXKEYSIZE) {
cerr << "key size is over 1k...!" << endl;
return false;
}
redisReply *reply = (redisReply *)redisCommand(conn_, "set %b %b", key, keylen, value.c_str(), value.size());
if (nullptr == reply) {
cerr << "reply is null...!" << endl;
return false;
}
bool succ = true;
if (nullptr == reply->str) {
succ = false;
cerr << "reply string is null...!" << endl;
}
else if (strcasecmp(reply->str, "ok")) {
succ = false;
cerr << "reply error = " << reply->str << endl;
}
freeReplyObject(reply);
reply = nullptr;
return succ;
}
bool get_value(const char *key, string &value) {
if (nullptr == conn_) {
cerr << "redis client conn is null...!" << endl;
return false;
}
size_t keylen = strlen(key);
if (keylen > MAXKEYSIZE) {
cerr << "key size is over 1k...!" << endl;
return false;
}
redisReply *reply = (redisReply *)redisCommand(conn_, "get %s", key);
if (nullptr == reply) {
cerr << "reply is null...!" << endl;
return false;
}
bool succ = true;
if (nullptr == reply->str) {
succ = false;
cerr << "reply string is null...!" << endl;
}
else if (REDIS_REPLY_NIL == reply->type) {
succ = false;
cerr << "reply error = " << reply->str << endl;
}
else {
value.assign(reply->str, reply->len);
}
freeReplyObject(reply);
reply = nullptr;
return succ;
}
private:
redisContext *conn_;
private:
static const size_t MAXVALUESIZE = 1024 * 1024;
static const size_t MAXKEYSIZE = 1024;
static const size_t MAXCHANNELSIZE = 10;
};

#endif /* REDIS_CLIENT_HPP_ */

2.redis_client_pool.hpp

#ifndef REDIS_CLIENT_POOL_HPP_
#define REDIS_CLIENT_POOL_HPP_
#include <vector>
#include <memory>
#include <functional>
#include <mutex>
#include "redis_client.hpp"
struct redis_client_pool_config {
redis_client_pool_config() {
poolsize_ = 32;
port_ = 6379;
ip_ = "127.0.0.1";
}
size_t poolsize_;
string ip_;
int port_;
};
using delete_type = function<void(redis_client *)>;
class redis_client_pool {
public:
redis_client_pool() = default;
virtual ~redis_client_pool() = default;
public:
bool init(const redis_client_pool_config &config) {
if (config.poolsize_ > POOLCAPACITY) {
cerr << "pool size is over limit...!" << endl;
return false;
}
for (size_t i = 0;i < config.poolsize_;i++) {
unique_ptr<redis_client>ptr(new redis_client);
if (!ptr->connect(config.ip_.c_str(), config.port_)) {
return false;
}
clients_.push_back(move(ptr));
}
return true;
}
unique_ptr<redis_client, delete_type>get_client() {
lock_guard<mutex>lock(pool_lock_);
if (clients_.empty()) {
return nullptr;
}
unique_ptr<redis_client, delete_type>ptr(clients_.back().release(), [this](redis_client *client) {
pool_lock_.lock();
clients_.push_back(unique_ptr<redis_client>(client));
pool_lock_.unlock();
});
clients_.pop_back();
return move(ptr);
}

private:
vector<unique_ptr<redis_client> >clients_;
mutex pool_lock_;
private:
static const size_t POOLCAPACITY = 128;


};

#endif /* REDIS_CLIENT_POOL_HPP_ */

3.main.cpp

#include "redis_client_pool.hpp"
int main() {
redis_client_pool mypool;
redis_client_pool_config config;
if (false == mypool.init(config)) {
return -1;
}
const char *key = "key0";
string value = "value0";
auto client_ptr = mypool.get_client();
if (nullptr == client_ptr) {
return -1;
}
if (client_ptr->set_value(key, value)) {
cout << "set value to redis server ok." << endl;
}
string new_value;
if (client_ptr->get_value(key, new_value)) {
cout << "get value = " << new_value << " from redis server ok." << endl;
}

return 0;
}

4.make.sh

g++ -std=c++14 -g -o Test main.cpp  redis_client.hpp -lhiredis