准备工作
- 下载源码
- make,会生成动态库和静态库文件。
- 将所需头文件和库文件引入自己的工程。
使用同步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
来保存连接状态。 redisContext
在每次操作后会修改其中的 err
和 errstr
字段来表示发生的错误码(大于0)和对应的描述。没有发生错误的话, err
会被设置为 REDIS_OK
(等于0)。
redisContext不是线程安全的。
断开连接
void redisFree(redisContext *c);
该接口用来断开连接并释放 redisContext
。
执行命令
void *redisCommand(redisContext *c, const char *format, ...);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
这两个接口使用类似 printf
的风格格式化命令,如果需要传入二进制安全的字符串,需要使用 %b
并传入 size_t
类型的字符串长度。
redisCommandArgv
中可以默认使用 strlen
来求得字符串长度而不需要传入第四个参数,但如果是二进制安全的字符串,需要提供所有字符串参数的长度。
示例:
redisCommand(context, "SET foo bar");
redisCommand(context, "SET foo %s", value);
redisCommand(context, "SET foo %b", value, (size_t) valuelen);
管道
这两个API除了不返回 redisReply
之外,与 redisCommand
一致。
void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
这个接口用来获取管道里的 redisReply
,返回值是 REDIS_OK
或者 REDIS_ERR
。发送错误时 redisContext
的 err
会被设置。
redisGetReply(context,&reply); // reply for SET
管道使用示例 —— 阻塞订阅者的一个实现:
reply = redisCommand(context,"SUBSCRIBE foo");
freeReplyObject(reply);
while(redisGetReply(context,&reply) == REDIS_OK) {
// consume message
freeReplyObject(reply);
}
错误
如果一个函数调用不成功,不同函数会返回 NULL
或 REDIS_ERR
。 redisContext
中的 err
字段会被设置为以下的非零值:
REDIS_ERR_IO
:
创建连接、通过socket读写数据时产生了错误。如果包括了errno.h
头文件,可以使用errno
检查出了什么错。REDIS_ERR_EOF
:
服务器关闭了连接导致的空读。REDIS_ERR_PROTOCOL
:
解析协议出错。REDIS_ERR_OTHER
:
任意其他错误。目前仅用于要连接的指定主机无法被解析的情况下。
每一种情况下, errstr
字段都会被设置为相应的文字说明。
redisReply
redisReply
是 redisCommand
返回值的实际类型。
redisCommand
发生错误时返回 NULL
,并设置 redisContext
错误。
一旦发生错误,这个 redisContext
就不能继续使用,必须建立新的连接。
可以通过 redisReply
的 type
字段来判断返回类型:
REDIS_REPLY_STATUS
:- 命令返回的是状态。可以用
reply->str
和reply->len
获得描述字符串及其长度。
- 命令返回的是状态。可以用
REDIS_REPLY_ERROR
:- 命令执行错误,错误字符串获取方法与
REDIS_REPLY_STATUS
一样。
- 命令执行错误,错误字符串获取方法与
REDIS_REPLY_INTEGER
:- 命令返回的是整数, 返回值是
long long
类型,通过reply->integer
获取。
- 命令返回的是整数, 返回值是
REDIS_REPLY_NIL
:- 命令返回的是 nil 对象,没有数据可取。
REDIS_REPLY_STRING
:- 命令返回字符串,可以通过
reply->str
和reply->len
获得字符串及其长度。
- 命令返回字符串,可以通过
REDIS_REPLY_ARRAY
:- 命令返回数组,元素个数存储在
reply->elements
中。 每个元素都是一个redisReply
, 并可以通过reply->element[..index..]
的方法获取。
- 命令返回数组,元素个数存储在
reply应该用 freeReplyObject
释放,数组和内嵌数组不需要被单独释放。
void freeReplyObject(void *reply);
hiredis(0.10.0)在异步api使用时自动释放replies。所以在调用异步api时不要调用freeReplyObject。hiredis会在回调返回之后释放reply。不过这个问题可能会在未来修改掉(issue #39)。
异步API
异步API包含的头文件是 async.h
连接
redisAsyncConnect
用来进行异步连接,不是线程安全的。
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
}
连接相关的回调函数:
typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); // 建立连接回调
typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); // 断开连接回调
status
为 REDIS_OK
表示是用户自己断开 ,其他值代表连接被其他错误断开。
redisContext
会在断开连接回调中被释放,此时可以进行需要的重连。
每个 redisContext
只能设置一次断开连接回调,后面的调用会返回 REDIS_ERR
。
设置断开连接的回调如下:
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
断开连接的接口:
void redisAsyncDisconnect(redisAsyncContext *ac);
执行异步命令
用法与同步API类型,除了需要传入回调函数以及自定义数据的 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);
命令成功被到输入缓冲区后会返回 REDIS_OK
,否则返回 REDIS_ERR
。
当命令执行结果返回时会调用注册的回调函数并传入对应的 redisReply
结构和自定义数据。
命令返回后读空回调函数(NULL callback
)会使reply立即释放。如果是非空回调,则会在回调函数执行完后释放reply。