zoukankan      html  css  js  c++  java
  • Hiredis 基本使用

    0. 前言

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

    1. 同步API

    redisContext,该库的上下文环境。

     1 /* Context for a connection to Redis */
     2 typedef struct redisContext {
     3     int err; /* Error flags, 0 when there is no error */
     4     char errstr[128]; /* String representation of error when applicable */
     5     int fd;
     6     int flags;
     7     char *obuf; /* Write buffer */
     8     redisReader *reader; /* Protocol reader */
     9 
    10     enum redisConnectionType connection_type;
    11     struct timeval *timeout;
    12 
    13     struct {
    14         char *host;
    15         char *source_addr;
    16         int port;
    17     } tcp;
    18 
    19     struct {
    20         char *path;
    21     } unix_sock;
    22 
    23 } redisContext;

    a. 连接Redis

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

     

    b. 同步执行Redis命令

    1 /*
    2 
    3 同步执行redis命令,和printf类似,%b传入二进制数据,要求有size_t参数指定长度。例如redisCommmand( c, "SET foo %b", arr, (size_t)len );
    4 失败:返回NULL,并且err字段会置1,一旦执行出错,该redisContext就不能再使用,需要重新连接
    5 成功:返回redisReply的指针
    6 
    7 */
    8 void *redisCommand(redisContext *c, const char *format, ...);
     1 /*
     2 发送一组命令,通过argv以及argvlen指定,当argvlen为NULL时,argv每个字符串的长度通过strlen来计算,所以当需要传输二进制数据时,整个argvlen数据都要输入。
     3 */
     4 void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
     5 
     6 /*
     7     Piplining,追加的命令后可以通过redisGetReply来获取命令的返回值。
     8 */
     9 void redisAppendCommand(redisContext *c, const char *format, ...);
    10 void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
    11 
    12 //获取命令返回值,注:使用freeReplyObject释放
    13 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字段

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

     

    d. 释放资源

    1 //释放reply结构
    2 void freeReplyObject(void *reply);
    //关闭连接并释放内存
    void redisFree(redisContext *c);

     

    e. 错误字段说明 redisContext.err

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

    2. 异步API

       待补充

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

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include "hiredis.h"
     4 
     5 void ProcessReply( redisReply * pReply )
     6 {
     7     redisReply * pSubReply = NULL;
     8 
     9     if ( pReply != NULL && pReply->elements == 3 )
    10     {
    11         pSubReply = pReply->element[2];
    12         printf( "Msg [%s]
    ", pSubReply->str );
    13     }
    14 }
    15 
    16 int main( int argc, char const *argv[] )
    17 {
    18     redisContext * pContext = redisConnect( "127.0.0.1", 6379 );
    19 
    20     if ( NULL == pContext || pContext->err == 1 )
    21     {
    22         printf( "%s
    ", pContext->errstr );
    23         exit( -1 );
    24     }
    25 
    26     char * pKey = "DATABUS:REQ";
    27 
    28     redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
    29     freeReplyObject( pReply );
    30     while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
    31     {
    32         ProcessReply( pReply );
    33         freeReplyObject( pReply );
    34     }
    35 
    36     redisFree( pContext );
    37 
    38     return 0;
    39 }

    运行结果如下: 

  • 相关阅读:
    多线程-死锁代码示例
    区块链技术:以太方学习文档
    svn 不能校验路径“XXX”的锁;没有匹配的可用锁令牌 故障解决方法
    Oracle ORA-27102的解决办法(out of memory)
    Linux常用命令语法+示例
    Java如何实现form表单提交的数据自动对应实体类(源码)
    Java分布式锁看这篇就够了
    quartz时间配置
    volatile 实现原理
    == 和 equals()的区别
  • 原文地址:https://www.cnblogs.com/jabnih/p/4814212.html
Copyright © 2011-2022 走看看