最近一个C++项目中使用Redis作为主要存储工具,在代码中直接调用Hiredis的C API不方便。对其简单做了一下封装,主要目的是更方便的使用HGet、HMGet这样一些哈希操作,支持错误重连,当然通过封装也提高了代码的复用。
RedisHelper.h
1 #ifndef _REDIS_HELPER_H 2 #define _REDIS_HELPER_H 3 4 #include <mutex> 5 #include <map> 6 #include <vector> 7 #include <string> 8 #include <hiredis/hiredis.h> 9 10 #define REDIS_IP "xxx.xxx.xxx.xxx" 11 #define REDIS_PORT "6379" 12 13 typedef std::vector<std::string> StrVec; 14 typedef std::map<std::string, std::string> StrMap; 15 16 class RedisHelper 17 { 18 public: 19 RedisHelper(const std::string& ip_, const std::string& port_); 20 ~RedisHelper(); 21 22 void Connecting(); 23 StrMap HMGet(const std::string& key, const StrVec& vec); 24 ... ... 25 26 private: 27 redisContext *redis_conn; 28 std::mutex conn_mutex; 29 30 redisReply *redis_reply; 31 std::mutex reply_mutex; 32 33 std::string ip; 34 int port; 35 }; 36 37 inline RedisHelper& GetRedisHelper() 38 { 39 static RedisHelper helper(REDIS_IP, REDIS_PORT); 40 return helper; 41 } 42 43 #endif
RedisHelper.cpp
1 #include "RedisHelper.h" 2 #include <cstdlib> 3 #include <sstream> 4 5 6 RedisHelper::RedisHelper(const std::string& ip_, const std::string& port_) 7 : redis_conn(NULL), redis_reply(NULL), ip(ip_) 8 { 9 port = std::atoi(port_.c_str()); 10 Connecting(); 11 } 12 13 RedisHelper::~RedisHelper() 14 { 15 if(redis_conn) { 16 redisFree(redis_conn); 17 } 18 } 19 20 void RedisHelper::Connecting() 21 { 22 std::lock_guard<std::mutex> l(conn_mutex); 23 if(redis_conn) { 24 redisFree(redis_conn); 25 } 26 redis_conn = redisConnect(ip.c_str(), port); 27 if(redis_conn!=NULL && redis_conn->err) { 28 ... ... 29 } 30 } 31 32 StrMap RedisHelper::HMGet(const std::string& key, const StrVec& vec) 33 { 34 StrMap map; 35 std::lock_guard<std::mutex> l(reply_mutex); 36 size_t vecSize = vec.size(); 37 if(vecSize == 0) return map; 38 39 std::stringstream sm; 40 sm << "HMGET " << key; 41 for(size_t i=0; i<vecSize; i++) { 42 sm << " " << vec[i]; 43 } 44 45 redis_reply = static_cast<redisReply*>(redisCommand(redis_conn, sm.str().c_str() )); 46 47 if (redis_reply->type == REDIS_REPLY_ARRAY) { 48 if(vecSize != redis_reply->elements) { 49 ... ... 50 } 51 else { 52 for (size_t i=0; i<redis_reply->elements; ++i) { 53 map[vec[i]] = redis_reply->element[i]->str; 54 } 55 } 56 } 57 else if (redis_reply->type == REDIS_REPLY_ERROR) { 58 Connecting(); 59 } 60 61 freeReplyObject(redis_reply); 62 return map; 63 }
时间: 2024-12-15 13:56:47