0.hiredis的使用

Hiredis是一個(gè)Redis的C客戶(hù)端庫(kù)函數(shù),基本實(shí)現(xiàn)了Redis的協(xié)議的最小集。這里對(duì)hiredis的api作基本的介紹以及應(yīng)用,主要參考hiredis的README文件以及相關(guān)源碼。

  1. hiredis的安裝,這個(gè)就不贅述了,很簡(jiǎn)單。

  2. 同步API接口的使用

我們的項(xiàng)目中使用的hireds接口都是同步的API,所謂同步意思就是使用阻塞的方式向redis server下發(fā)消息。

接口的主要部分為下面三個(gè)部分,下面分別介紹。

/**連接數(shù)據(jù)庫(kù)*/
redisContext *redisConnect(const char *ip, int port);
/**發(fā)送命令請(qǐng)求*/
void *redisCommand(redisContext *c, const char *format, ...);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
/*釋放資源*/
void freeReplyObject(void *reply);
void redisFree(redisContext *c);

2.1連接redis數(shù)據(jù)庫(kù)
2.1.1函數(shù)原型:

redisContext *redisConnect(const char *ip, int port);

2.1.2參數(shù)說(shuō)明:
port:為redis數(shù)據(jù)監(jiān)聽(tīng)的端口號(hào),redis默認(rèn)監(jiān)聽(tīng)的端口號(hào)為6379
ip:為redis數(shù)據(jù)庫(kù)的IP地址,可以是遠(yuǎn)程的,也可以是本地的127.0.0.1

2.1.3返回值
返回值是一個(gè)指向redisContext對(duì)象,可以不用了解這個(gè)對(duì)象的具體組成部分,只需要知道怎么使用就可以了。下面是其定義。

typedef struct redisContext {
    int err; /* Error flags, 0 when there is no error */
    char errstr[128]; /* String representation of error when applicable */
    int fd;
    int flags;
    char *obuf; /* Write buffer */
    redisReader *reader; /* Protocol reader */
    enum redisConnectionType connection_type;
    struct timeval *timeout;
    struct {
        char *host;
        char *source_addr;
        int port;
    } tcp;
    struct {
        char *path;
    } unix_sock;
} redisContext;

2.1.4 使用例子

redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
    if (c) {
        printf("Error: %s\n", c->errstr);
        // handle error
    } else {
        printf("Can't allocate redis context\n");
    }
}

這個(gè)redisContext不是一個(gè)線程安全的對(duì)象,也就是說(shuō),多個(gè)線程同時(shí)訪問(wèn)這一個(gè)對(duì)象可能會(huì)出現(xiàn)問(wèn)題。

2.2 發(fā)送需要執(zhí)行的命令
2.2.1發(fā)送命令函數(shù)原型

void *redisCommand(redisContext *c, const char *format, ...);

2.2.2參數(shù)說(shuō)明
這個(gè)函數(shù)是一個(gè)帶有不定參數(shù)的??梢园粗鴉ormat格式給出對(duì)應(yīng)的參數(shù),這就和printf函數(shù)類(lèi)似。
c 是一個(gè)reidsConnect函數(shù)返回的一個(gè)對(duì)象。

2.2.3返回值
返回值是一個(gè)void類(lèi)型的指針,實(shí)際為指向一個(gè)redisReply類(lèi)型的指針。
redisReply的定義

/* This is the reply object returned by redisCommand() */
typedef struct redisReply {
    /*命令執(zhí)行結(jié)果的返回類(lèi)型*/
    int type; /* REDIS_REPLY_* */
    /*存儲(chǔ)執(zhí)行結(jié)果返回為整數(shù)*/
    long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
    /*字符串值的長(zhǎng)度*/
    size_t len; /* Length of string */
    /*存儲(chǔ)命令執(zhí)行結(jié)果返回是字符串*/
    char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
    /*返回結(jié)果是數(shù)組的大小*/
    size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
    /*存儲(chǔ)執(zhí)行結(jié)果返回是數(shù)組*/
    struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
} redisReply;

返回結(jié)果的類(lèi)型reply->type,reply 為redisReply* 類(lèi)型。
REDIS_REPLY_STRING == 1:返回值是字符串,字符串儲(chǔ)存在redis->str當(dāng)中,字符串長(zhǎng)度為redis->len。
REDIS_REPLY_ARRAY == 2:返回值是數(shù)組,數(shù)組大小存在redis->elements里面,數(shù)組值存儲(chǔ)在redis->element[i]里面。數(shù)組里面存儲(chǔ)的是指向redisReply的指針,數(shù)組里面的返回值可以通過(guò)redis->element[i]->str來(lái)訪問(wèn),數(shù)組的結(jié)果里全是type==REDIS_REPLY_STRING的redisReply對(duì)象指針。
REDIS_REPLY_INTEGER == 3:返回值為整數(shù) long long。
REDIS_REPLY_NIL==4:返回值為空表示執(zhí)行結(jié)果為空。
REDIS_REPLY_STATUS ==5:返回命令執(zhí)行的狀態(tài),比如set foo bar 返回的狀態(tài)為OK,存儲(chǔ)在str當(dāng)中 reply->str == "OK"。
REDIS_REPLY_ERROR ==6 :命令執(zhí)行錯(cuò)誤,錯(cuò)誤信息存放在 reply->str當(dāng)中。

redisCommandArgv函數(shù)
函數(shù)原型

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

參數(shù)說(shuō)明
argvlen這個(gè)數(shù)組存儲(chǔ)了命令參數(shù)中,每一個(gè)參數(shù)的長(zhǎng)度,包含命令本身,比如 set foo bar 則argvlen ={3,3,3},如果argvlen為空,那么這個(gè)函數(shù)內(nèi)部會(huì)自動(dòng)調(diào)用strlen函數(shù)對(duì)每個(gè)參數(shù)進(jìn)行求長(zhǎng)度。
argv 存放每個(gè)命令參數(shù)的指針,argv={"set","foo","bar"}
argc 存放命令參數(shù)的個(gè)數(shù)上面的例子中argc=3
c 為redisContext對(duì)象。
為每一個(gè)參數(shù)指定長(zhǎng)度,可以是二進(jìn)制安全的函數(shù)。函數(shù)會(huì)按著長(zhǎng)度來(lái)決定字符串的終止,而不是'\0'.

char hkey[] = "123456";
char hset[] = "hset";
char key[] = "testkey";
char hvalue[] = "3210";
int argc = 4;
char *argv[] = {hset,key,hkey,hvalue};
size_t argvlen[] = {4,6,4,3};
redisCommandArgv(context,argc,argv,argvlen);

hgetall testkey
會(huì)得到321并不會(huì)得到和hvalue一樣的值"3210",因?yàn)樵趆set命令中指定了長(zhǎng)度,只會(huì)讀取前面的三個(gè)字符。

redisAppendCommand*函數(shù)支持管道命令
函數(shù)原型:

void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
int redisGetReply(redisContext *context,redisReply** reply);

參數(shù)說(shuō)明:
redisAppendCommand函數(shù)和redisCommand函數(shù)參數(shù)一致,format可以指定特定參數(shù)的類(lèi)型。
c 為redisContext對(duì)象
redisAppendCommandArgv函數(shù)和redisCommandArgv函數(shù)類(lèi)似,參數(shù)含義也相同。
redisGetReply函數(shù)用來(lái)獲得執(zhí)行的結(jié)果的一條返回,并存儲(chǔ)在reply所指的對(duì)象當(dāng)中。成功返回REDIS_OK,否則返回REIDS_ERR。多條命令的一次性返回結(jié)果都存放在redisContext里面。
所不同的是,這個(gè)兩個(gè)命令的結(jié)果。這兩個(gè)函數(shù)是把多個(gè)命令存放在緩沖區(qū)內(nèi),然后一起發(fā)送給redis服務(wù)器,一次執(zhí)行。可以通過(guò)redisGetReply函數(shù)從
redisContext中取出返回的結(jié)果。

使用例子:

redisReply *reply;
/*添加命令set */
redisAppendCommand(context,"SET foo bar");
/*添加命令get */
redisAppendCommand(context,"GET foo");
/*獲取set命令結(jié)果*/
redisGetReply(context,&reply); // reply for SET
freeReplyObject(reply);
/*獲取get命令結(jié)果*/
redisGetReply(context,&reply); // reply for GET
freeReplyObject(reply);

2.3 釋放資源
2.3.1函數(shù)原型

void freeReplyObject(void *reply);
void redisFree(redisContext *c);

2.3.2參數(shù)說(shuō)明
freeReplyObject函數(shù)中reply 實(shí)際為指向redisReply結(jié)構(gòu)體的指針,可能是redisCommand的返回值,后續(xù)可以看到以也能是管道命令執(zhí)行結(jié)果的返回值。
redisFree函數(shù)中c實(shí)際為指向redisContext對(duì)象,這個(gè)函數(shù)會(huì)清理連接資源并釋放連接。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,707評(píng)論 0 5
  • 《男盜女娼》 在這個(gè)男盜女娼的世界,總有人叫囂著自己就是真流氓,而不愿意承認(rèn)自己就是偽君子。 《陌路》 原來(lái)相愛(ài)的...
    何鯨洛閱讀 248評(píng)論 0 1
  • 是什么讓我鼓起勇氣重新讀一遍孫子兵法,暫且不細(xì)說(shuō),究竟是什么能讓我有此膽量將這手字流露出來(lái),不得而知哈哈,第一...
    Amber0128閱讀 710評(píng)論 0 0
  • 最近看了一本神奇的書(shū),《秘密》。里面介紹了一個(gè)玄而又玄的理論:吸引力法則。你頭腦中所想的事情、場(chǎng)景,總能被吸...
    言小海閱讀 1,006評(píng)論 0 4

友情鏈接更多精彩內(nèi)容