您的位置:首页 > 数据库 > Redis

Hiredis 基本使用

2015-09-16 19:29 676 查看
0. 前言

  Hiredis是一个Redis的C客户端库函数,基本实现了Redis的协议的最小集。这里对hiredis的api作基本的介绍以及应用,主要参考hiredis的README文件以及相关源码。

1. 同步API

redisContext,该库的上下文环境。

/* Context for a connection to Redis */
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;


a. 连接Redis

//连接redis,若出错redisContext.err会设置为1,redisContext.errstr会包含描述错误信息
redisContext *redisConnect(const char *ip, int port);


b. 同步执行Redis命令

/*

同步执行redis命令,和printf类似,%b传入二进制数据,要求有size_t参数指定长度。例如redisCommmand( c, "SET foo %b", arr, (size_t)len );
失败:返回NULL,并且err字段会置1,一旦执行出错,该redisContext就不能再使用,需要重新连接
成功:返回redisReply的指针

*/
void *redisCommand(redisContext *c, const char *format, ...);


/*
发送一组命令,通过argv以及argvlen指定,当argvlen为NULL时,argv每个字符串的长度通过strlen来计算,所以当需要传输二进制数据时,整个argvlen数据都要输入。
*/
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

/*
Piplining,追加的命令后可以通过redisGetReply来获取命令的返回值。
*/
void redisAppendCommand(redisContext *c, const char *format, ...);
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

//获取命令返回值,注:使用freeReplyObject释放
int redisGetReply(redisContext *c, void **reply);


c. 响应的数据结构

typedef struct redisReply {
  int type; /* REDIS_REPLY_* */ //指明返回的类型
  long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
  int 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;


Redis返回数据的类型,redisReply.type字段

#define REDIS_REPLY_STRING 1 //字符串
#define REDIS_REPLY_ARRAY 2    //数组,多个reply,通过element数组以及elements数组大小访问
#define REDIS_REPLY_INTEGER 3    //整型, integer字段
#define REDIS_REPLY_NIL 4    //空,没有数据
#define REDIS_REPLY_STATUS 5    //状态,str字符串以及len
#define REDIS_REPLY_ERROR 6    //错误,同STATUS


d. 释放资源

//释放reply结构
void freeReplyObject(void *reply);


//关闭连接并释放内存
void redisFree(redisContext *c);


e. 错误字段说明 redisContext.err

//错误字段,会设置为以下其中一个值
#define REDIS_ERR_IO 1 /* Error in read or write */
#define REDIS_ERR_EOF 3 /* End of file */
#define REDIS_ERR_PROTOCOL 4 /* Protocol error */
#define REDIS_ERR_OOM 5 /* Out of memory */
#define REDIS_ERR_OTHER 2 /* Everything else... */


2. 异步API

  待补充

3. 同步API示例(实现订阅功能)

#include <stdio.h>
#include <stdlib.h>
#include "hiredis.h"

void ProcessReply( redisReply * pReply )
{
redisReply * pSubReply = NULL;

if ( pReply != NULL && pReply->elements == 3 )
{
pSubReply = pReply->element[2];
printf( "Msg [%s]\n", pSubReply->str );
}
}

int main( int argc, char const *argv[] )
{
redisContext * pContext = redisConnect( "127.0.0.1", 6379 );

if ( NULL == pContext || pContext->err == 1 )
{
printf( "%s\n", pContext->errstr );
exit( -1 );
}

char * pKey = "DATABUS:REQ";

redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
freeReplyObject( pReply );
while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
{
ProcessReply( pReply );
freeReplyObject( pReply );
}

redisFree( pContext );

return 0;
}


运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: