国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Redis C語(yǔ)言客戶端庫(kù)hiredis文檔翻譯

2019-11-11 00:03:04
字體:
供稿:網(wǎng)友
Redis C語(yǔ)言客戶端庫(kù)hiredis文檔翻譯2013-09-14 14:00:29標(biāo)簽:redis hiredis原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章 原始出處 、作者信息和本聲明。否則將追究法律責(zé)任。http://yaocoder.blog.51cto.com/2668309/1297031

Hiredis是redis數(shù)據(jù)庫(kù)一個(gè)輕量的C語(yǔ)言客戶端庫(kù)。

之所以輕量是由于它只是簡(jiǎn)單的提供了對(duì)redis操作語(yǔ)句支持的接口,并沒有實(shí)現(xiàn)具體的操作語(yǔ)句的功能。但正是由于這種設(shè)計(jì)使我們只要熟悉了通用的redis操作語(yǔ)句就可以很容易的使用該庫(kù)和redis數(shù)據(jù)庫(kù)進(jìn)行交互。

除了支持發(fā)送命令和接收應(yīng)答/應(yīng)答數(shù)據(jù),它提供了對(duì)應(yīng)答數(shù)據(jù)的解析操作。而且這個(gè)基于I/O層的數(shù)據(jù)流解析操作設(shè)計(jì)考慮到了復(fù)用性,可以對(duì)應(yīng)答數(shù)據(jù)進(jìn)行通用的解析操作。

Hirides僅僅支持二進(jìn)制安全的redis協(xié)議,所以你只能針對(duì)版本號(hào)大于等于1.2.0的redis服務(wù)端使用。

庫(kù)包含多種API,包括同步命令操作API、異步命令操作API和對(duì)應(yīng)答數(shù)據(jù)進(jìn)行解析的API。

升級(jí)

版本0.9.0是hiredis很多特性一次大的更新。但是對(duì)現(xiàn)有代碼進(jìn)行升級(jí)應(yīng)該不會(huì)造成大的問題。升級(jí)時(shí),要記住的關(guān)鍵一點(diǎn)是大于等于0.9.0的版本是使用redisContext*來保持連接狀態(tài),之前的版本只是使用了無狀態(tài)的文件描述符。

同步API

有幾個(gè)API需要介紹

redisContext *redisConnect(const char *ip, int port);void *redisCommand(redisContext *c, const char *format, ...);void freeReplyObject(void *reply);

連接redis數(shù)據(jù)庫(kù)

函數(shù) redisConnect 被用來創(chuàng)建一個(gè) redisContext。這個(gè) context 是hiredis持有的連接狀態(tài)。redisConnect 結(jié)構(gòu)體有一個(gè)整型的 err 變量來標(biāo)識(shí)連接錯(cuò)誤碼,如果連接錯(cuò)誤則為非零值。變量 errstr 標(biāo)識(shí)連接結(jié)果的文字描述。更多這方面的信息會(huì)在以下Errors章節(jié)說明。當(dāng)你使用 redisConnect 來創(chuàng)建連接時(shí)應(yīng)該檢查err變量來判斷是否連接正常建立。

redisContext *c = redisConnect("127.0.0.1", 6379);if (c != NULL && c->err) {PRintf("Error: %s/n", c->errstr); // handle error }

發(fā)送命令到redis

有多種方法可以發(fā)送命令到redis。

首先介紹的是redisCommand。此函數(shù)類似于printf的使用方式,如

reply = redisCommand(context, "SET foo bar");

類似于printf的s%格式化方式,如

reply = redisCommand(context, "SET foo %s", value);

當(dāng)你需要發(fā)送二進(jìn)制安全的命令可以采用%b的格式化方式,同時(shí)需要一個(gè)字符串指針和size_t類型的字符串長(zhǎng)度參數(shù),如下

reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen);

在API內(nèi)部,Hiredis根據(jù)不同的參數(shù)分割命令轉(zhuǎn)化為操作redis數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)命令,你可以格式化多個(gè)參數(shù)來構(gòu)造redis的命令,如下

reply = redisCommand(context, "SET key:%s %s", myid, value);

處理redis應(yīng)答

當(dāng)命令被成功執(zhí)行后redisCommand會(huì)有相應(yīng)的返回值。如果有錯(cuò)誤發(fā)生,返回值為NULL并且redisReply結(jié)構(gòu)體中的err變量將會(huì)被設(shè)置成相應(yīng)的值(請(qǐng)參照Errors章節(jié))。一旦有錯(cuò)誤發(fā)生context不能被重用并且你需要建立一個(gè)新的連接。

redisCommand執(zhí)行后返回值類型為redisReply。通過redisReply結(jié)構(gòu)體中的type變量可以確定命令執(zhí)行的情況。

REDIS_REPLY_STATUS:

返回執(zhí)行結(jié)果為狀態(tài)的命令。比如set命令的返回值的類型是REDIS_REPLY_STATUS,然后只有當(dāng)返回信息是"OK"時(shí),才表示該命令執(zhí)行成功。可以通過reply->str得到文字信息,通過reply->len得到信息長(zhǎng)度。

REDIS_REPLY_ERROR:

返回錯(cuò)誤。錯(cuò)誤信息可以通過reply->str得到文字信息,通過reply->len得到信息長(zhǎng)度。

REDIS_REPLY_INTEGER:

返回整型標(biāo)識(shí)。可以通過reply->integer變量得到類型為long long的值。

REDIS_REPLY_NIL:

返回nil對(duì)象,說明不存在要訪問的數(shù)據(jù)。

REDIS_REPLY_STRING:

返回字符串標(biāo)識(shí)。可以通過reply->str得到具體值,通過reply->len得到信息長(zhǎng)度。

REDIS_REPLY_ARRAY:

返回?cái)?shù)據(jù)集標(biāo)識(shí)。數(shù)據(jù)集中元素的數(shù)目可以通過reply->elements獲得,每個(gè)元素是個(gè)redisReply對(duì)象,元素值可以通過reply->element[..index..].*形式獲得,用在獲取多個(gè)數(shù)據(jù)結(jié)果的操作。

執(zhí)行完命令調(diào)用后應(yīng)該通過freeReplyObject()釋放redisReply,對(duì)于嵌套對(duì)象(比如數(shù)組)要注意,并不需要嵌套進(jìn)行釋放,這樣是有害的會(huì)造成內(nèi)存破壞。

Important:hiredis當(dāng)前版本 (0.10.0)當(dāng)使用異步API時(shí)會(huì)自己釋放replies對(duì)象。這意味著你使用異步API時(shí)并不需要主動(dòng)調(diào)用freeReplyObject 。relpy對(duì)象當(dāng)回調(diào)返回時(shí)將會(huì)被自動(dòng)釋放。但是這種行為也許會(huì)在將來的版本中改變,所以升級(jí)時(shí)請(qǐng)密切關(guān)注升級(jí)日志。

清理連接資源

斷開連接并且釋放context使用以下函數(shù)

void redisFree(redisContext *c);

此函數(shù)立馬關(guān)閉socket并且釋放創(chuàng)建context時(shí)分配的資源。

發(fā)送多個(gè)命令參數(shù)

和redisCommand函數(shù)相似,redisCommandArgv函數(shù)可以用于傳輸多個(gè)命令參數(shù)。函數(shù)原型為

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

,類似于 lpush, del key1 key2..., zadd key score1 member1 score2 member2...這類命令, 其中 argc是傳遞參數(shù)的個(gè)數(shù), argv主要用于傳遞的string的value, 而argvlen 是每個(gè)string的size。

此函數(shù)返回值與redisCommand相似。參考https://gist.github.com/dspezia/1455082

管線(Pipelining)

為了搞清楚Hiredis在阻塞連接下的管線操作,需要理解其內(nèi)部執(zhí)行過程。

當(dāng)任何類似于redisCommand的函數(shù)被調(diào)用,Hiredis首先將命令格式化為redis支持的命令協(xié)議。被格式化后的命令被放入context的輸出緩沖區(qū),這個(gè)緩沖區(qū)是動(dòng)態(tài)的,所以它可以容納任意數(shù)量的命令。在命令進(jìn)入輸出緩沖區(qū)后,redisGetReply 函數(shù)被調(diào)用。這個(gè)函數(shù)有以下兩種執(zhí)行方式:

輸入緩沖區(qū)非空:

從輸入緩沖區(qū)中嘗試解析單獨(dú)的reply對(duì)象并且返回reply

如果沒有reply能被解析,執(zhí)行步驟2

輸入緩沖區(qū)為空:

將整個(gè)輸出緩沖區(qū)寫入socket

從socket中讀取數(shù)據(jù)直到有一個(gè)reply能被解析

Hiredis為了有效利用socket還提供了redisGetReply的接口。對(duì)于管線命令,需要完成的唯一事情就是填充輸出緩沖區(qū)。有兩個(gè)函數(shù)被用于執(zhí)行此操作,這兩個(gè)函數(shù)基本與redisCommand函數(shù)功能類似,但是他們不返回reply

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

當(dāng)這兩個(gè)函數(shù)被一次或多次調(diào)用時(shí),通過redisGetReply依次返回replies。redisGetReply的返回值要么是REDISOK或是REDISERR,REDIS_ERR意味著獲得reply發(fā)生了錯(cuò)誤,想要得到具體的錯(cuò)誤原因可以通過err變量來獲取。

以下通過一個(gè)簡(jiǎn)單例子說明管線的使用:

redisReply *reply;redisAppendCommand(context,"SET foo bar");redisAppendCommand(context,"GET foo");redisGetReply(context,&reply); // reply for SETfreeReplyObject(reply);redisGetReply(context,&reply); // reply for GETfreeReplyObject(reply);

redisGetReply這個(gè)API也可以被用來實(shí)現(xiàn)阻塞的訂閱模式

reply = redisCommand(context,"SUBSCRIBE foo");freeReplyObject(reply);while(redisGetReply(context,&reply) == REDIS_OK) {// consume messagefreeReplyObject(reply);}

Errors

如果某些函數(shù)(如redisConnect, redisCommand(調(diào)用不成功,函數(shù)返回值為NULL或者REDIS_ERR,此時(shí)context結(jié)構(gòu)體中的err成員為非零值,可能為以下幾種常量

REDIS_ERR_IO:當(dāng)創(chuàng)建連接時(shí)(試著寫socket或者讀socket)發(fā)生的I/O錯(cuò)誤。如果你在代碼中包含了errno.h頭文件,你便能得到準(zhǔn)確的錯(cuò)誤碼。

REDIS_ERR_EOF:redis服務(wù)端已經(jīng)關(guān)閉了此連接。

REDIS_ERR_PROTOCOL:服務(wù)端解析協(xié)議時(shí)發(fā)生了錯(cuò)誤。

REDIS_ERR_OTHER:其他錯(cuò)誤。目前僅僅表示無法解析目標(biāo)主機(jī)名的錯(cuò)誤。

在錯(cuò)誤情況下,可以通過context結(jié)構(gòu)體中的errstr成員得到錯(cuò)誤的確切描述。

異步API

Hiredis自帶的異步API很容易和一些基于事件的庫(kù)結(jié)合使用。比如和libev、ibevent的結(jié)合使用。

連接

函數(shù)redisAsyncConnect被用來和redis建立非阻塞連接。它返回redisAsyncContext的結(jié)構(gòu)體,結(jié)構(gòu)體的err成員用來檢查在創(chuàng)建連接的過程中是否發(fā)生了錯(cuò)誤。因?yàn)閯?chuàng)建的是非阻塞的連接,內(nèi)核并不能立馬返回一個(gè)連接指定主機(jī)的結(jié)果。

redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);if (c->err) {printf("Error: %s/n", c->errstr);// handle error}

異步Context可設(shè)置一個(gè)響應(yīng)斷開連接事件的回調(diào)函數(shù),當(dāng)連接斷開時(shí)會(huì)相應(yīng)執(zhí)行。回調(diào)函數(shù)的原型為

void(const redisAsyncContext *c, int status);

在斷開連接的情況下,當(dāng)連接是由用戶自己斷開的status參數(shù)為REDISOK,如果出現(xiàn)了其他錯(cuò)誤status參數(shù)為REDISERR,當(dāng)錯(cuò)誤時(shí)通過err成員可以得到準(zhǔn)確的錯(cuò)誤碼。

當(dāng)回調(diào)執(zhí)行完畢后context對(duì)象會(huì)自己釋放資源。此事件的回調(diào)函數(shù)給你創(chuàng)建一個(gè)新連接提供了便利。

一個(gè)context對(duì)象僅能設(shè)置一次斷開連接的回調(diào),如果再進(jìn)行下一次設(shè)置將會(huì)返回REDIS_ERR。設(shè)置斷開連接回調(diào)函數(shù)的原型為:

int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);

發(fā)送操作命令并且響應(yīng)回調(diào)事件

在異步的情況下,redis的操作指令將會(huì)被自動(dòng)加入事件循環(huán)隊(duì)列。由于發(fā)送命令執(zhí)行的過程是異步的,當(dāng)命令執(zhí)行完畢后將會(huì)調(diào)用相應(yīng)的回調(diào)函數(shù)。回調(diào)函數(shù)的原型為

void(redisAsyncContext *c, void *reply, void *privdata);

privdata參數(shù)是由調(diào)用者自己定義的數(shù)據(jù)類型。

以下是進(jìn)行異步命令操作的函數(shù):

int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,const char *format, ...);

int redisAsyncCommandArgv( redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);

命令的使用方式和上面所講的同步接口類似。執(zhí)行成功返回REDIS_OK,否則返回REDIS_ERR。比如連接已經(jīng)關(guān)閉的情況下再使用redisAsyncCommand向此連接執(zhí)行命令就會(huì)返回REDIS_ERR。

回調(diào)執(zhí)行完畢后如果reply不為空,回調(diào)執(zhí)行完畢后將自動(dòng)對(duì)reply的資源進(jìn)行回收。

當(dāng)context發(fā)生錯(cuò)誤時(shí)回調(diào)得到的reply將為空。

斷開連接

一個(gè)異步的連接可以通過下面這個(gè)函數(shù)終止

void redisAsyncDisconnect(redisAsyncContext *ac);

當(dāng)這個(gè)函數(shù)被調(diào)用時(shí),連接并不會(huì)被立即關(guān)閉,而是等待所有這個(gè)連接的異步命令操作執(zhí)行完畢,并且回調(diào)事件已經(jīng)執(zhí)行完畢后才關(guān)閉此連接,這時(shí)在響應(yīng)關(guān)閉連接事件的回調(diào)函數(shù)中得到的狀態(tài)為REDIS_OK,此連接的資源也將會(huì)被自動(dòng)回收。

將其掛接到事件庫(kù)X

在context對(duì)象被創(chuàng)建后進(jìn)行很少的幾步操作就可以進(jìn)行掛接。參看目錄adapters/下是如何掛接到libev 和 libevent下的。

應(yīng)答解析API

Hiredis自帶的答復(fù)解析API ,可以很容易與更高層次的語(yǔ)言進(jìn)行綁定


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 曲麻莱县| 黔南| 霸州市| 安陆市| 北碚区| 逊克县| 乌审旗| 上林县| 宣化县| 平顺县| 通州市| 沈丘县| 宜城市| 光泽县| 睢宁县| 丹凤县| 西畴县| 民县| 津南区| 叶城县| 恩施市| 临猗县| 贵阳市| 象山县| 三都| 池州市| 勐海县| 泽普县| 灵寿县| 邢台县| 台江县| 山东| 漳州市| 广饶县| 周口市| 洪泽县| 丰顺县| 孙吴县| 遂溪县| 吴桥县| 通化市|