C++异步网络库workflow系列教程(2)redis任务

往期教程

如果觉得写的可以,请给一个点赞+关注支持一下

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);获取到requestcommand部分

相关推荐
JJJJ_iii8 分钟前
【深度学习03】神经网络基本骨架、卷积、池化、非线性激活、线性层、搭建网络
网络·人工智能·pytorch·笔记·python·深度学习·神经网络
海阳宜家电脑20 分钟前
SQL Server连接字符串
服务器·网络
无限进步_33 分钟前
C语言字符串与内存操作函数完全指南
c语言·c++·算法
闻缺陷则喜何志丹1 小时前
【C++贪心】P10537 [APIO2024] 九月|普及+
c++·算法·贪心·洛谷
QiZhang | UESTC1 小时前
JAVA算法练习题day27
java·开发语言·c++·算法·leetcode·hot100
努力学习的小廉1 小时前
深入了解linux网络—— 自定义协议(上)
linux·服务器·网络
Stanford_11062 小时前
关于嵌入式硬件需要了解的基础知识
开发语言·c++·嵌入式硬件·微信小程序·微信公众平台·twitter·微信开放平台
野犬寒鸦2 小时前
从零起步学习Redis || 第十一章:主从切换时的哨兵机制如何实现及项目实战
java·服务器·数据库·redis·后端·缓存
要做朋鱼燕2 小时前
【AES加密专题】1.AES的原理详解和加密过程
运维·网络·密码学·c·加密·aes·嵌入式工具
是那盏灯塔2 小时前
16.C++三大重要特性之多态
开发语言·c++