redis記憶體資料庫C客戶端hiredis API 中文說明
A)編譯安裝
make make install (/usr/local) make install PREFIX=$HOME/progs(可以自由指定安裝路徑)
B)同步的API介面
redisContext *redisConnect(const char *ip, int port); void *redisCommand(redisContext *c, const char *format, ...); void freeReplyObject(void *reply);
1)建立連線
redisContext *c = redisConnect("127.0.0.1", 6379); if (c != NULL && c->err) { printf("Error: %s\n", c->errstr); // handle error }
redisConnect函式用來建立一個叫redisContext的東西,它包含了連線相關的資訊,它裡面有個err欄位,0表示正常,其他表示出錯了!通過errstr欄位可以知曉錯誤資訊。
2)執行命令
reply = redisCommand(context, "SET key value"); reply = redisCommand(context, "SET key %s", value); reply = redisCommand(context, "SET key %b", value, (size_t) valuelen); reply = redisCommand(context, "SET key:%s %s", myid, value);
redisCommand的呼叫格式類似printf函式,上面的第二條呼叫語句的作用在於輸入二進位制格式的value內容,其後必須表明二進位制的位元組長度!
3)redisCommand函式返回一個東西叫redisReply,我們需要通過判斷它的type欄位來知道返回了具體什麼樣的內容:
REDIS_REPLY_STATUS 表示狀態,內容通過str欄位檢視,字串長度是len欄位 REDIS_REPLY_ERROR 表示出錯,查看出錯資訊,如上的str,len欄位 REDIS_REPLY_INTEGER 返回整數,從integer欄位獲取值 REDIS_REPLY_NIL 沒有資料返回 REDIS_REPLY_STRING 返回字串,檢視str,len欄位 REDIS_REPLY_ARRAY 返回一個數組,檢視elements的值(陣列個數),通過element[index]的方式訪問陣列元素,每個陣列元素是 一個redisReply物件的指標
4)另外有一個類似的函式,批量執行命令:
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
5)redisReply使用完畢後,需要使用函式freeReplyObject進行釋放銷燬
void redisFree(redisContext *c)的作用是斷開連線,並釋放redisContext的內容
6)redisCommand的函式執行流程說明:
a.格式化redis command
b.格式化後的命令內容放入redisContext的輸出緩衝區
c.呼叫redisGetReply函式執行命令,得到結果
7)管道的使用方式:
a.填入需要執行的命令
void redisAppendCommand(redisContext *c, const char *format, ...); void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
b.獲取命令的輸出結果
int redisGetReply(redisContext *c, void **reply);
c.釋放輸出結果
void freeReplyObject(void *reply);
例子:
redisReply *reply = NULL;
redisAppendCommand(context,"set key1 value");
redisAppendCommand(context,"get key2");
redisGetReply(context,&reply); // reply for set
freeReplyObject(reply);
redisGetReply(context,&reply); // reply for get
freeReplyObject(reply);
訂閱模式:
reply = redisCommand(context,"SUBSCRIBE test");
freeReplyObject(reply);
while(redisGetReply(context,&reply) == REDIS_OK) {
// consume message
freeReplyObject(reply);
}
8)redisReply返回結果處理:
REDIS_OK 正常
REDIS_ERR_IO IO讀/寫出現異常,通過errno檢視原因
REDIS_ERR_EOF 伺服器關閉了連結,讀結束
REDIS_ERR_PROTOCOL 分析redis協議內容出錯
EDIS_ERR_OTHER 其他未知的錯誤
上述錯誤型別都可以通過redisReply的errstr欄位檢視簡短的描述
C)非同步API(非同步API的使用方式和同步API差不多,在這兒列出不同的函式吧)
1.連線redis伺服器
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); if (c->err) { printf("Error: %s\n", c->errstr); // handle error }
2.設定連線、斷開的鉤子函式
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
3.插入命令資訊
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);
獲取命令輸出和同步API相同
4.關閉連線
void redisAsyncDisconnect(redisAsyncContext *ac);
D)輔助API
下面的API主要用於其他程式語言繫結的術後,可以讀取分析資料
redisReader *redisReaderCreate(void); void redisReaderFree(redisReader *reader); int redisReaderFeed(redisReader *reader, const char *buf, size_t len); int redisReaderGetReply(redisReader *reader, void **reply);
官方例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis.h>
int main(int argc, char **argv) {
unsigned int j;
redisContext *c;
redisReply *reply;
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
int port = (argc > 2) ? atoi(argv[2]) : 6379;
struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectWithTimeout(hostname, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection error: %s\n", c->errstr);
redisFree(c);
} else {
printf("Connection error: can't allocate redis context\n");
}
exit(1);
}
/* PING server */
reply = redisCommand(c,"PING");
printf("PING: %s\n", reply->str);
freeReplyObject(reply);
/* Set a key */
reply = redisCommand(c,"SET %s %s", "foo", "hello world");
printf("SET: %s\n", reply->str);
freeReplyObject(reply);
/* Set a key using binary safe API */
reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5);
printf("SET (binary API): %s\n", reply->str);
freeReplyObject(reply);
/* Try a GET and two INCR */
reply = redisCommand(c,"GET foo");
printf("GET foo: %s\n", reply->str);
freeReplyObject(reply);
reply = redisCommand(c,"INCR counter");
printf("INCR counter: %lld\n", reply->integer);
freeReplyObject(reply);
/* again ... */
reply = redisCommand(c,"INCR counter");
printf("INCR counter: %lld\n", reply->integer);
freeReplyObject(reply);
/* Create a list of numbers, from 0 to 9 */
reply = redisCommand(c,"DEL mylist");
freeReplyObject(reply);
for (j = 0; j < 10; j++) {
char buf[64];
snprintf(buf,64,"%d",j);
reply = redisCommand(c,"LPUSH mylist element-%s", buf);
freeReplyObject(reply);
}
/* Let's check what we have inside the list */
reply = redisCommand(c,"LRANGE mylist 0 -1");
if (reply->type == REDIS_REPLY_ARRAY) {
for (j = 0; j < reply->elements; j++) {
printf("%u) %s\n", j, reply->element[j]->str);
}
}
freeReplyObject(reply);
/* Disconnects and frees the context */
redisFree(c);
return 0;
}