hiredis主要有以下同步API:
/**连接数据库*/
redisContext *redisConnect(const char *ip, int port);
/**发送命令请求*/
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);
redisContext *redisConnect(const char *ip, int port);
返回值是一个指向redisContext对象,下面是redisContext对象的定义。
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;
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");
}
}
这个redisContext不是一个线程安全的对象,也就是说,多个线程同时访问这一个对象可能会出现问题。
void *redisCommand(redisContext *c, const char *format, ...);
返回值是一个void类型的指针,实际为指向一个redisReply类型的指针,redisReply的定义如下:
/* This is the reply object returned by redisCommand() */
typedef struct redisReply {
/*命令执行结果的返回类型*/
int type; /* REDIS_REPLY_* */
/*存储执行结果返回为整数*/
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
/*字符串值的长度*/
size_t len; /* Length of string */
/*存储命令执行结果返回是字符串*/
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
/*返回结果是数组的大小*/
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
/*存储执行结果返回是数组*/
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
} redisReply;
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
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);
void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
与redisCommand()和redisCommandArgv()不同的是,这两个函数是把多个命令存放在缓冲区内,然后一起发送给redis服务器,一次执行。可以通过redisGetReply函数从redisContext中取出返回的结果。
redisReply *reply;
/*添加命令set */
redisAppendCommand(context,"SET foo bar");
/*添加命令get */
redisAppendCommand(context,"GET foo");
/*获取set命令结果*/
redisGetReply(context,&reply); // reply for SET
freeReplyObject(reply);
/*获取get命令结果*/
redisGetReply(context,&reply); // reply for GET
freeReplyObject(reply);
也可以使用这个功能来实现发布订阅功能
reply = redisCommand(context,"SUBSCRIBE foo");
freeReplyObject(reply);
while(redisGetReply(context,&reply) == REDIS_OK) {
// 处理所订阅频道的消息
freeReplyObject(reply);
}
所有的返回结果都需要释放资源调用freeReplyObject函数。这个函数会递归的释放数组中的资源,不需要手动释放数组资源。
redisGetReply函数用来获得执行的结果的一条返回,并存储在reply所指的对象当中。成功返回REDIS_OK,否则返回REIDS_ERR。多条命令的一次性返回结果都存放在redisContext里面。
int redisGetReply(redisContext *context,redisReply** reply);
redisReply *reply = nullptr;
while (REDIS_OK == redisGetReply(this->_subcribe_context, (void **)&reply))
{
//订阅收到的消息是一个带三元素的数组
if (reply != nullptr && reply->element[2] != nullptr && reply->element[2]->str != nullptr)
{
//给业务层上报通道上发生的消息
_notify_message_handler(atoi(reply->element[1]->str) , reply->element[2]->str);
}
freeReplyObject(reply);
}
void freeReplyObject(void *reply);
void redisFree(redisContext *c);
异步API的使用方式和同步API差不多,下面列出不同的函数:
//连接redis服务器
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
printf("Error: %s\n", c->errstr);
// handle error
}
//设置连接、断开的钩子函数
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
//插入命令信息
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);
//关闭连接
void redisAsyncDisconnect(redisAsyncContext *ac);