準(zhǔn)備工作
- 下載源碼
- make,會(huì)生成動(dòng)態(tài)庫和靜態(tài)庫文件城舞。
- 將所需頭文件和庫文件引入自己的工程。
使用同步API
建立連接
// redisContext *redisConnect(const char *ip, int port);
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c != NULL && c->err)
{
printf("Error: %s\n", c->errstr);
// handle error
}
建立連接后使用 redisContext
來保存連接狀態(tài)矾策。 redisContext
在每次操作后會(huì)修改其中的 err
和 errstr
字段來表示發(fā)生的錯(cuò)誤碼(大于0)和對應(yīng)的描述窑睁。沒有發(fā)生錯(cuò)誤的話, err
會(huì)被設(shè)置為 REDIS_OK
(等于0)枢贿。
redisContext不是線程安全的嘁圈。
斷開連接
void redisFree(redisContext *c);
該接口用來斷開連接并釋放 redisContext
省骂。
執(zhí)行命令
void *redisCommand(redisContext *c, const char *format, ...);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
這兩個(gè)接口使用類似 printf
的風(fēng)格格式化命令,如果需要傳入二進(jìn)制安全的字符串最住,需要使用 %b
并傳入 size_t
類型的字符串長度钞澳。
redisCommandArgv
中可以默認(rèn)使用 strlen
來求得字符串長度而不需要傳入第四個(gè)參數(shù),但如果是二進(jìn)制安全的字符串涨缚,需要提供所有字符串參數(shù)的長度轧粟。
示例:
redisCommand(context, "SET foo bar");
redisCommand(context, "SET foo %s", value);
redisCommand(context, "SET foo %b", value, (size_t) valuelen);
管道
這兩個(gè)API除了不返回 redisReply
之外,與 redisCommand
一致脓魏。
void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
這個(gè)接口用來獲取管道里的 redisReply
兰吟,返回值是 REDIS_OK
或者 REDIS_ERR
。發(fā)送錯(cuò)誤時(shí) redisContext
的 err
會(huì)被設(shè)置茂翔。
redisGetReply(context,&reply); // reply for SET
管道使用示例 —— 阻塞訂閱者的一個(gè)實(shí)現(xiàn):
reply = redisCommand(context,"SUBSCRIBE foo");
freeReplyObject(reply);
while(redisGetReply(context,&reply) == REDIS_OK) {
// consume message
freeReplyObject(reply);
}
錯(cuò)誤
如果一個(gè)函數(shù)調(diào)用不成功混蔼,不同函數(shù)會(huì)返回 NULL
或 REDIS_ERR
。 redisContext
中的 err
字段會(huì)被設(shè)置為以下的非零值:
REDIS_ERR_IO
:
創(chuàng)建連接珊燎、通過socket讀寫數(shù)據(jù)時(shí)產(chǎn)生了錯(cuò)誤惭嚣。如果包括了errno.h
頭文件,可以使用errno
檢查出了什么錯(cuò)悔政。REDIS_ERR_EOF
:
服務(wù)器關(guān)閉了連接導(dǎo)致的空讀晚吞。REDIS_ERR_PROTOCOL
:
解析協(xié)議出錯(cuò)。REDIS_ERR_OTHER
:
任意其他錯(cuò)誤卓箫。目前僅用于要連接的指定主機(jī)無法被解析的情況下载矿。
每一種情況下, errstr
字段都會(huì)被設(shè)置為相應(yīng)的文字說明烹卒。
redisReply
redisReply
是 redisCommand
返回值的實(shí)際類型闷盔。
redisCommand
發(fā)生錯(cuò)誤時(shí)返回 NULL
,并設(shè)置 redisContext
錯(cuò)誤旅急。
一旦發(fā)生錯(cuò)誤逢勾,這個(gè) redisContext
就不能繼續(xù)使用,必須建立新的連接藐吮。
可以通過 redisReply
的 type
字段來判斷返回類型:
-
REDIS_REPLY_STATUS
:- 命令返回的是狀態(tài)溺拱。可以用
reply->str
和reply->len
獲得描述字符串及其長度谣辞。
- 命令返回的是狀態(tài)溺拱。可以用
-
REDIS_REPLY_ERROR
:- 命令執(zhí)行錯(cuò)誤迫摔,錯(cuò)誤字符串獲取方法與
REDIS_REPLY_STATUS
一樣。
- 命令執(zhí)行錯(cuò)誤迫摔,錯(cuò)誤字符串獲取方法與
-
REDIS_REPLY_INTEGER
:- 命令返回的是整數(shù), 返回值是
long long
類型泥从,通過reply->integer
獲取句占。
- 命令返回的是整數(shù), 返回值是
-
REDIS_REPLY_NIL
:- 命令返回的是 nil 對象,沒有數(shù)據(jù)可取躯嫉。
-
REDIS_REPLY_STRING
:- 命令返回字符串纱烘,可以通過
reply->str
和reply->len
獲得字符串及其長度。
- 命令返回字符串纱烘,可以通過
-
REDIS_REPLY_ARRAY
:- 命令返回?cái)?shù)組祈餐,元素個(gè)數(shù)存儲(chǔ)在
reply->elements
中擂啥。 每個(gè)元素都是一個(gè)redisReply
, 并可以通過reply->element[..index..]
的方法獲取帆阳。
- 命令返回?cái)?shù)組祈餐,元素個(gè)數(shù)存儲(chǔ)在
reply應(yīng)該用 freeReplyObject
釋放哺壶,數(shù)組和內(nèi)嵌數(shù)組不需要被單獨(dú)釋放。
void freeReplyObject(void *reply);
hiredis(0.10.0)在異步api使用時(shí)自動(dòng)釋放replies蜒谤。所以在調(diào)用異步api時(shí)不要調(diào)用freeReplyObject山宾。hiredis會(huì)在回調(diào)返回之后釋放reply。不過這個(gè)問題可能會(huì)在未來修改掉(issue #39)芭逝。
異步API
異步API包含的頭文件是 async.h
連接
redisAsyncConnect
用來進(jìn)行異步連接塌碌,不是線程安全的。
redisAsyncContext *redisAsyncConnect(const char *ip, int port);
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err)
{
printf("Error: %s\n", c->errstr);
// handle error
}
連接相關(guān)的回調(diào)函數(shù):
typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); // 建立連接回調(diào)
typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); // 斷開連接回調(diào)
status
為 REDIS_OK
表示是用戶自己斷開 旬盯,其他值代表連接被其他錯(cuò)誤斷開台妆。
redisContext
會(huì)在斷開連接回調(diào)中被釋放,此時(shí)可以進(jìn)行需要的重連胖翰。
每個(gè) redisContext
只能設(shè)置一次斷開連接回調(diào)接剩,后面的調(diào)用會(huì)返回 REDIS_ERR
。
設(shè)置斷開連接的回調(diào)如下:
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
斷開連接的接口:
void redisAsyncDisconnect(redisAsyncContext *ac);
執(zhí)行異步命令
用法與同步API類型萨咳,除了需要傳入回調(diào)函數(shù)以及自定義數(shù)據(jù)的 void*
類型指針懊缺。
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);
typedef void (redisCallbackFn)(redisAsyncContext*, void* reply, void* privdata);
命令成功被到輸入緩沖區(qū)后會(huì)返回 REDIS_OK
,否則返回 REDIS_ERR
。
當(dāng)命令執(zhí)行結(jié)果返回時(shí)會(huì)調(diào)用注冊的回調(diào)函數(shù)并傳入對應(yīng)的 redisReply
結(jié)構(gòu)和自定義數(shù)據(jù)鹃两。
命令返回后讀空回調(diào)函數(shù)(NULL callback
)會(huì)使reply立即釋放遗座。如果是非空回調(diào),則會(huì)在回調(diào)函數(shù)執(zhí)行完后釋放reply俊扳。