LIB-ZC, 一个跨平台(Linux)平台通用C/C++扩展库,redis 客户端
- 支持单点(standalone)和集群(cluster)
- 支持引擎, 可以自己开发代理
- 必须了解 redis 的命令和协议才能顺利使用本客户端, 请参阅 http://doc.redisfans.com/
redis 客户端规律
redis命令返回结果可以抽象为json, 绝大部分可以简化为4类:
- 成功/失败
- 整数
- 字符串
- 字符串 list
作者也写过几个版本的客户端, 都不满意, 封装的东西很难满足使用者包括本人的需求. 哪怕仅仅是 GET 协议也是如此.
最后采用如下类似通用封装:
// zcc::redis_client rc;
std::string sval;
rc.exec_command(sval, {"GET", "abc"});
返回值
redis_client 类里面所有的操作类方法,其返回值规范
- -2: 网络错误/系统错误/协议错误
- -1: 逻辑错误
- 0: 失败/不存在/逻辑错误/等
- >0: 成功/存在/逻辑正确/等
zcc::redis_client
类方法介绍
连接
// class zcc::redis_client
// 这个方法用于自己提供引擎, 比如其他的 socket/stream等
void open(redis_client_basic_engine *engine);
// 信息, 错误信息等
const std::string &get_info_msg();
// 设置超时
void set_timeout(int wait_timeout);
// 自动重连
void set_auto_reconnect(bool tf = true);
// 密码
virtual void set_password(const char *password);
virtual void inline set_password(const std::string &password) { set_password(password.c_str()); }
// 连接服务器, 如 localhost:6379, times: 重试次数
int connect(const char *destination, int times = 1);
int connect(const std::string &destination, int times = 1)
{
return connect(destination.c_str(), times);
}
// 连接集群
int cluster_connect(const char *destinations, int times = 1);
int cluster_connect(const std::string &destination, int times = 1)
{
return cluster_connect(destination.c_str(), times);
}
// 关闭, release_engine 为真则释放引擎
void close(bool release_engine = true);
基本命令
// class zcc::redis_client
// 返回 -1: 错; 0: 失败/不存在/逻辑错误/...; 1: 成功/存在/逻辑正确
int exec_command(const std::list<std::string> &query_tokens);
// 返回: 如上; 一些命令, 适合得到一个整数结果并赋值给 number_ret, 如 klen/incrby/ttl
int exec_command(int64_t &number_ret, const std::list<std::string> &query_tokens);
// 返回: 如上; 一些命令, 适合得到一个字符串结果赋值给 string_ret, 如 GET/HGET
// rc.exec_command(sval, {"GET", "abc"});
int exec_command(std::string &string_ret, const std::list<std::string> &query_tokens);
// 返回: 如上; 一些命令, 适合得到一串字符串结果并赋值给 list_ret, 如 MGET/HMGET/ */
int exec_command(std::list<std::string> &list_ret, const std::list<std::string> &query_tokens);
// 返回: 如上; 所有命令都可以
int exec_command(json &json_ret, const std::list<std::string> &query_tokens);
info 命令
// class zcc::redis_client
int info(std::map<std::string, std::string> &name_value_dict, std::string &string_ret);
scan
// class zcc::redis_client
int scan(std::list<std::string> &list_ret, int64_t &cursor_ret, int64_t cursor)
{
return _general_scan(list_ret, cursor_ret, "SCAN", cursor);
}
int hscan(std::list<std::string> &list_ret, int64_t &cursor_ret, int64_t cursor)
{
return _general_scan(list_ret, cursor_ret, "HSCAN", cursor);
}
int sscan(std::list<std::string> &list_ret, int64_t &cursor_ret, int64_t cursor)
{
return _general_scan(list_ret, cursor_ret, "SSCAN", cursor);
}
int zscan(std::list<std::string> &list_ret, int64_t &cursor_ret, int64_t cursor)
{
return _general_scan(list_ret, cursor_ret, "ZSCAN", cursor);
}
订阅相关
// class zcc::redis_client
int subscribe(const char *channel);
int subscribe(const std::string &channel);
int unsubscribe(const char *channel = nullptr);
int unsubscribe(const std::string &channel = var_blank_string);
int psubscribe(const char *channel);
int psubscribe(const std::string &channel);
int punsubscribe(const char *channel = nullptr);
int punsubscribe(const std::string &channel = var_blank_string);
// 读取频道, 返回 -1: 出错, 返回 0: 超时, 返回 1, 有数据
int fetch_channel_message(std::string &type, std::string &channel, std::string &data, int timeout);
简单的用法
zcc::redis_client rc;
rc.set_password("123456");
if (rc.connect("127.0.0.1:6379") < 1)
{
if (c_ret == 0)
{
std::printf("auth failed\n");
}
else if (c_ret == -1)
{
std::printf("unknown error\n");
}
else
{
std::printf("open error\n");
}
zcc::exit(1);
}
std::string sval;
int64_t lval;
zcc::json jval;
rc.exec_command({"SET", "", "ssssss"});
rc.exec_command({"GET", "abc"});
rc.exec_command(sval, {"GET", "abc"});
rc.exec_command(sval, {"HGET", "xxx.com_u", "ac.tai"});
rc.exec_command({"STRLEN", "abc"});
rc.exec_command({"STRLEN", "abc"});
rc.exec_command(lval, {"mget", "abc", "fasdfdsaf"});
rc.exec_command(jval, {"MGET", "abc", "sss"});
rc.exec_command(jval, {"SCAN", "0"});
rc.exec_command(jval, {"EVAL", "return {1,2,{3,'Hello World!'}}", "0"});
rc.exec_command(jval, {"fffSCAN", "0"});