您好,欢迎来到华拓科技网。
搜索
您的当前位置:首页RediscAPI

RediscAPI

来源:华拓科技网
RediscAPI

Hiredis是redis数据库⼀个轻量的C语⾔客户端库。

之所以轻量是由于它只是简单的提供了对redis操作语句⽀持的接⼝,并没有实现具体的操作语句的功能。但正是由于这种设计使我们只要熟悉了通⽤的redis操作语句就可以很容易的使⽤该库和redis数据库进⾏交互。

除了⽀持发送命令和接收应答/应答数据,它提供了对应答数据的解析操作。⽽且这个基于I/O层的数据流解析操作设计考虑到了复⽤性,可以对应答数据进⾏通⽤的解析操作。

Hirides仅仅⽀持⼆进制安全的redis协议,所以你只能针对版本号⼤于等于1.2.0的redis服务端使⽤。库包含多种API,包括同步命令操作API、异步命令操作API和对应答数据进⾏解析的API。

升级

版本0.9.0是hiredis很多特性⼀次⼤的更新。但是对现有代码进⾏升级应该不会造成⼤的问题。升级时,要记住的关键⼀点是⼤于等于0.9.0的版本是使⽤redisContext*来保持连接状态,之前的版本只是使⽤了⽆状态的⽂件描述符。

同步API

有⼏个API需要介绍

redisContext *redisConnect(const char *ip, int port);

void *redisCommand(redisContext *c, const char *format, ...);void freeReplyObject(void *reply); 【lsj注】

1.⼀旦redisCommand()发⽣错误,会返回NULL,也会导致redisContext失效,使其不能再⽤于执⾏其他操作。2.必须调⽤freeReplyObject()来释放reply对象,不然会造成内存泄露。

3.redisCommand()返回的是void *类型,需要⼿动进⾏类型转换(reply = (redisReply *)redisCommand(…))

连接redis数据库

函数 redisConnect 被⽤来创建⼀个 redisContext。这个 context 是hiredis持有的连接状态。redisConnect 结构体有⼀个整型的 err 变量来标识连接错误码,如果连接错误则为⾮零值。变量 errstr 标识连接结果的⽂字描述。更多这⽅⾯的信息会在以下Errors章节说明。当你使⽤redisConnect 来创建连接时应该检查err变量来判断是否连接正常建⽴。

redisContext *c = redisConnect(\"127.0.0.1\if (c != NULL && c->err) {

printf(\"Error: %s\\n\

发送命令到redis

有多种⽅法可以发送命令到redis。

⾸先介绍的是redisCommand。此函数类似于printf的使⽤⽅式,如

reply = redisCommand(context, \"SET foo bar\");类似于printf的s%格式化⽅式,如

reply = redisCommand(context, \"SET foo %s\

当你需要发送⼆进制安全的命令可以采⽤%b的格式化⽅式,同时需要⼀个字符串指针和size_t类型的字符串长度参数,如下

reply = redisCommand(context, \"SET foo %b\

在API内部,Hiredis根据不同的参数分割命令转化为操作redis数据库的标准命令,你可以格式化多个参数来构造redis的命令,如下

reply = redisCommand(context, \"SET key:%s %s\

处理redis应答

当命令被成功执⾏后redisCommand会有相应的返回值。如果有错误发⽣,返回值为NULL并且redisReply结构体中的err变量将会被设置成相应的值(请参照Errors章节)。⼀旦有错误发⽣context不能被重⽤并且你需要建⽴⼀个新的连接。

redisCommand执⾏后返回值类型为redisReply。通过redisReply结构体中的type变量可以确定命令执⾏的情况。

REDIS_REPLY_STATUS:

返回执⾏结果为状态的命令。⽐如set命令的返回值的类型是REDIS_REPLY_STATUS,然后只有当返回信息是\"OK\"时,才表⽰该命令执⾏成功。可以通过reply->str得到⽂字信息,通过reply->len得到信息长度。REDIS_REPLY_ERROR:

返回错误。错误信息可以通过reply->str得到⽂字信息,通过reply->len得到信息长度。REDIS_REPLY_INTEGER:

返回整型标识。可以通过reply->integer变量得到类型为long long的值。REDIS_REPLY_NIL:

返回nil对象,说明不存在要访问的数据。REDIS_REPLY_STRING:

返回字符串标识。可以通过reply->str得到具体值,通过reply->len得到信息长度。REDIS_REPLY_ARRAY:

返回数据集标识。数据集中元素的数⽬可以通过reply->elements获得,每个元素是个redisReply对象,元素值可以通过reply->element[..index..].*形式获得,⽤在获取多个数据结果的操作。

执⾏完命令调⽤后应该通过freeReplyObject()释放redisReply,对于嵌套对象(⽐如数组)要注意,并不需要嵌套进⾏释放,这样是有害的会造成内存破坏。

Important:hiredis当前版本 (0.10.0)当使⽤异步API时会⾃⼰释放replies对象。这意味着你使⽤异步API时并不需要主动调⽤freeReplyObject。relpy对象当回调返回时将会被⾃动释放。但是这种⾏为也许会在将来的版本中改变,所以升级时请密切关注升级⽇志。

清理连接资源

断开连接并且释放context使⽤以下函数

void redisFree(redisContext *c);

此函数⽴马关闭socket并且释放创建context时分配的资源。

发送多个命令参数

和redisCommand函数相似,redisCommandArgv函数可以⽤于传输多个命令参数。函数原型为

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

,类似于 lpush, del key1 key2..., zadd key score1 member1 score2 member2...这类命令, 其中 argc是传递参数的个数, argv主要⽤于传递的string的value, ⽽argvlen 是每个string的size。

管线(Pipelining)

为了搞清楚Hiredis在阻塞连接下的管线操作,需要理解其内部执⾏过程。

当任何类似于redisCommand的函数被调⽤,Hiredis⾸先将命令格式化为redis⽀持的命令协议。被格式化后的命令被放⼊context的输出缓冲区,这个缓冲区是动态的,所以它可以容纳任意数量的命令。在命令进⼊输出缓冲区后,redisGetReply 函数被调⽤。这个函数有以下两种执⾏⽅式:

1. 输⼊缓冲区⾮空:

从输⼊缓冲区中尝试解析单独的reply对象并且返回reply如果没有reply能被解析,执⾏步骤2

2. 输⼊缓冲区为空:

将整个输出缓冲区写⼊socket

从socket中读取数据直到有⼀个reply能被解析

Hiredis为了有效利⽤socket还提供了redisGetReply的接⼝。对于管线命令,需要完成的唯⼀事情就是填充输出缓冲区。有两个函数被⽤于执⾏此操作,这两个函数基本与redisCommand函数功能类似,但是他们不返回reply

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

void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

当这两个函数被⼀次或多次调⽤时,通过redisGetReply依次返回replies。redisGetReply的返回值要么是REDISOK或是REDISERR,REDIS_ERR意味着获得reply发⽣了错误,想要得到具体的错误原因可以通过err变量来获取。以下通过⼀个简单例⼦说明管线的使⽤:

redisReply *reply;

redisAppendCommand(context,\"SET foo bar\");redisAppendCommand(context,\"GET foo\");redisGetReply(context,&reply); // reply for SETfreeReplyObject(reply);

redisGetReply(context,&reply); // reply for GETfreeReplyObject(reply);

redisGetReply这个API也可以被⽤来实现阻塞的订阅模式

reply = redisCommand(context,\"SUBSCRIBE foo\");freeReplyObject(reply);

while(redisGetReply(context,&reply) == REDIS_OK) {

// consume messagefreeReplyObject(reply);}

Errors

如果某些函数(如redisConnect, redisCommand(调⽤不成功,函数返回值为NULL或者REDIS_ERR,此时context结构体中的err成员为⾮零值,可能为以下⼏种常量

REDIS_ERR_IO:当创建连接时(试着写socket或者读socket)发⽣的I/O错误。如果你在代码中包含了errno.h头⽂件,你便能得到准确的错误码。

REDIS_ERR_EOF:redis服务端已经关闭了此连接。REDIS_ERR_PROTOCOL:服务端解析协议时发⽣了错误。

REDIS_ERR_OTHER:其他错误。⽬前仅仅表⽰⽆法解析⽬标主机名的错误。在错误情况下,可以通过context结构体中的errstr成员得到错误的确切描述。

异步API

Hiredis⾃带的异步API很容易和⼀些基于事件的库结合使⽤。⽐如和libev、ibevent的结合使⽤。

连接

函数redisAsyncConnect被⽤来和redis建⽴⾮阻塞连接。它返回redisAsyncContext的结构体,结构体的err成员⽤来检查在创建连接的过程中是否发⽣了错误。因为创建的是⾮阻塞的连接,内核并不能⽴马返回⼀个连接指定主机的结果。

redisAsyncContext *c = redisAsyncConnect(\"127.0.0.1\if (c->err) {

printf(\"Error: %s\\n\// handle error}

异步Context可设置⼀个响应断开连接事件的回调函数,当连接断开时会相应执⾏。回调函数的原型为

void(const redisAsyncContext *c, int status);

在断开连接的情况下,当连接是由⽤户⾃⼰断开的status参数为REDISOK,如果出现了其他错误status参数为REDISERR,当错误时通过err成员可以得到准确的错误码。

当回调执⾏完毕后context对象会⾃⼰释放资源。此事件的回调函数给你创建⼀个新连接提供了便利。

⼀个context对象仅能设置⼀次断开连接的回调,如果再进⾏下⼀次设置将会返回REDIS_ERR。设置断开连接回调函数的原型为:

int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);

发送操作命令并且响应回调事件

在异步的情况下,redis的操作指令将会被⾃动加⼊事件循环队列。由于发送命令执⾏的过程是异步的,当命令执⾏完毕后将会调⽤相应的回

调函数。回调函数的原型为

void(redisAsyncContext *c, void *reply, void *privdata);privdata参数是由调⽤者⾃⼰定义的数据类型。以下是进⾏异步命令操作的函数:

int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,const char *format, ...);

int redisAsyncCommandArgv( redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, constsize_t *argvlen);

命令的使⽤⽅式和上⾯所讲的同步接⼝类似。执⾏成功返回REDIS_OK,否则返回REDIS_ERR。⽐如连接已经关闭的情况下再使⽤redisAsyncCommand向此连接执⾏命令就会返回REDIS_ERR。

回调执⾏完毕后如果reply不为空,回调执⾏完毕后将⾃动对reply的资源进⾏回收。当context发⽣错误时回调得到的reply将为空。

断开连接

⼀个异步的连接可以通过下⾯这个函数终⽌

void redisAsyncDisconnect(redisAsyncContext *ac);

当这个函数被调⽤时,连接并不会被⽴即关闭,⽽是等待所有这个连接的异步命令操作执⾏完毕,并且回调事件已经执⾏完毕后才关闭此连接,这时在响应关闭连接事件的回调函数中得到的状态为REDIS_OK,此连接的资源也将会被⾃动回收。

将其挂接到事件库X

在context对象被创建后进⾏很少的⼏步操作就可以进⾏挂接。参看⽬录adapters/下是如何挂接到libev 和 libevent下的。

应答解析API

Hiredis⾃带的答复解析API ,可以很容易与更⾼层次的语⾔进⾏绑定。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo6.cn 版权所有 赣ICP备2024042791号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务