往期教程
如果觉得写的可以,请给一个点赞+关注支持一下
Redis URL的格式
redis://:password@host:port/dbnum?query#fragment
如果是SSL,则为:
rediss://:password@host:port/dbnum?query#fragment
password是可选项。port的缺省值是6379,dbnum缺省值0,范围0-15。
redis URL示例:
redis://127.0.0.1/
redis://:12345678@redis.some-host.com/1
创建并启动Redis任务
创建Redis任务与创建http任务并没有什么区别,少了redirect_max参数。
cpp
using redis_callback_t = std::function<void (WFRedisTask *)>;
WFRedisTask *create_redis_task(const std::string& url,
int retry_max,
redis_callback_t callback);
简单示例
cpp
#include <workflow/WFFacilities.h
void callback(){}
int main(){
//创建redis任务
WFRedisTask *redisTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",0,callback);
//设置redis任务的属性
protocol::RedisRequest *req = redisTask->get_req();
//req->set_request("SET",{"43key", "100"});
//req->set_request("GET",{"43key"});
req->set_request("HGETALL",{"43t"});
//启动redis任务
redisTask->start();
}
与http task的get_req()类似,redis task的get_req()返回任务对应的redis request。
RedisRequest提供的功能可以在RedisMessage.h查看。 其中,set_request接口用于设置redis命令。
**注意:这里一条redis指令分为cmmand
部分和params
部分,params
是个vector
,所以就算只有一个参数,也需要用{}**括起来
cpp
void set_request(const std::string& command, const std::vector<std::string>& params);
相信经常使用redis的人,对这个接口不会有什么疑问。但必须注意,我们的请求是禁止SELECT命令和AUTH命令的。
因为用户每次请求并不能指定具体连接,SELECT之后下一次请求并不能保证在同一个连接上发起,那么这个命令对用户来讲没有任何意义。
对数据库选择和密码的指定,请在redis URL里完成。并且,必须是每次请求的URL都带着这些信息。
另外,我们的redis client是支持cluster模式的,可以自动处理MOVED和ASK回复并重定向。用户不能自己发送ASKING命令。
处理请求结果
我们将上面的简单示例 添加一个 处理请求结果的lambda
函数,
cpp
#include <workflow/WFFacilities.h
void callback(){}
int main(){
//创建redis任务
WFRedisTask *redisTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",0,[](WFRedisTask *redisTask){
protocol::RedisRequest *req = redisTask->get_req();
protocol::RedisResponse *resp = redisTask->get_resp();
int state = redisTask->get_state();
int error = redisTask->get_error();
protocol::RedisValue value;//value对象专门用来存储redis任务的结果
switch (state){
case WFT_STATE_SYS_ERROR:
fprintf(stderr,"system error: %s\n", strerror(error));
break;
case WFT_STATE_DNS_ERROR:
fprintf(stderr,"dns error: %s\n", gai_strerror(error));
break;
case WFT_STATE_SUCCESS:
resp->get_result(value);
if(value.is_error()){
fprintf(stderr,"redis error\n");
state = WFT_STATE_TASK_ERROR;
}
break;
}
if (state != WFT_STATE_SUCCESS){
fprintf(stderr, "Failed\n");
return;
}
else{
fprintf(stderr, "Success!\n");
}
std::string cmd;
req->get_command(cmd);
fprintf(stderr,"redis request, cmd = %s\n", cmd.c_str());
if(value.is_string()){
fprintf(stderr,"value is a string, value = %s\n", value.string_value().c_str());
}
else if(value.is_array()){
fprintf(stderr,"value is string array\n");
for(size_t i = 0; i < value.arr_size(); ++i){
fprintf(stderr,"value at %lu = %s\n", i, value.arr_at(i).string_value().c_str());
}
}
});
//设置redis任务的属性
protocol::RedisRequest *req = redisTask->get_req();
//req->set_request("SET",{"43key", "100"});
//req->set_request("GET",{"43key"});
req->set_request("HGETALL",{"43t"});
//启动redis任务
redisTask->start();
}
-
RedisValue
是一次redis request
得到的结果,同样在RedisMessage.h里可以看到其接口。 -
通过
resp->get_result(value)
将redis response
的响应结果存储在value中, -
由于redis的响应结果可能是一个string,也可能是多行string,所以我们需要进行判断处理,
-
如果
value.is_string()
返回真,表示结果只有一行,那么可以调用value.string_value()
获取到std::string
-
如果
value.is_array()
返回真,表示结果有多行,可以通过value.arr_size()
获取行数,再通过value.arr_at(i).string_value()
获取到每一行的string
-
-
req->get_command(cmd);
获取到request
的command
部分