发出命令

构造命令并将它们发送到 Redis 服务器。

与其他客户端库不同,hiredis 没有提供用于构造各种 Redis 命令的广泛 API。但是,它确实提供了一个轻量级且灵活的 API,可以帮助您从自己的代码中构造命令并解析其回复。

以下部分详细描述了可用函数。

构造同步命令

使用 redisCommand() 函数向服务器发送命令

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

此函数接收一个 redisContext 指针和一个指向包含命令的字符串的指针(参阅 连接 了解如何获取上下文指针)。命令文本与等效的 redis-cli 命令相同。例如,要发出命令

SET foo bar

您将使用现有 redisContext* c 执行以下命令

redisReply *reply = redisCommand(c, "SET foo bar");

参阅 命令参考 以获取可与 hiredis 一起使用的 CLI 命令示例。文档其他部分的大多数代码示例也有一个 CLI 标签,显示与代码等效的命令序列。

命令字符串的解释方式类似于 printf() 的格式字符串,因此您可以使用 %s 格式说明符轻松地将代码中的字符串值插入到命令中

char *myKeyNumber = "1";
char *myValue = "Hello";

// This issues the command 'SET key:1 Hello'.
redisReply *reply = redisCommand(c, "SET key:%s %s", myKeyNumber, myValue);

您可能需要在命令中包含二进制数据(例如,将 向量嵌入 存储到 哈希 对象的字段中)。为此,请使用 %b 格式说明符并传递指向数据缓冲区的指针,后跟一个指示其长度(以字节为单位)的 size_t 值。如下面的示例所示,您可以在同一个格式字符串中自由混合使用 %s%b 说明符。此外,您可以使用序列 %% 表示字面百分号,但不支持其他 printf() 说明符,例如 %d

char *entryNumber = "1";
char *embedding = "<binary data>";
char *url = "https://redis.ac.cn/";
size_t embLength = 13;

redisReply *reply = redisCommand(c,
    "HSET entry:%s embedding %b  url %s",
    entryNumber,
    embedding, embLength,
    url
);

redisCommand() 函数有一个名为 redisCommandArgv() 的变体

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

这不接受格式字符串,而是从 argv 参数中传递的字符串数组构建命令。

使用 argc 值指定此数组的长度,并使用 argvlen 数组指定数组中每个字符串的长度。如果您为 argvlen 传递 NULL,则该函数将尝试使用 strlen() 获取每个字符串的长度。但是,如果任何字符串包含二进制数据,则此方法无效,因此在这种情况下您应显式传递 argvlen。下面的示例展示了如何使用 redisCommandArgv() 发送简单命令

const char *argv[3] = { "SET", "greeting", "hello"};
int argc = 3;
const size_t argvlen[] = {3, 8, 5};

redisReply *reply = redisCommandArgv(c, argc, argv, argvlen);

构造异步命令

使用 redisAsyncCommand()redisAsyncCommandArgv() 函数异步向服务器发送命令

#include <hiredis/async.h>
    .
    .
    .
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);

这些函数的工作方式与 redisCommand()redisCommandArgv() 相同(参见上方的 构造同步命令),但它们有两个额外参数。第一个是指向可选回调函数的指针,第二个是指向您自定义数据的指针,执行时会将其传递给回调函数。如果您不需要使用它们,请为这两个指针传递 NULL

回调函数具有以下签名

void(redisAsyncContext *c, void *reply, void *privdata);

第一个参数是异步连接上下文,第二个是指向回复对象的指针。使用强制类型转换为 (redisReply *) 可以以通常的方式访问回复(参阅 处理命令回复 获取 redisReply 的完整描述)。最后一个参数是您在 redisAsyncCommand() 调用期间提供的自定义数据指针。它将不做任何修改地传递给您的函数。

以下示例展示了如何使用 redisAsyncCommand(),无论是否带回复回调函数

// The callback expects the key for the data in the `privdata`
// custom data parameter.
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
    redisReply *reply = r;
    char *key = privdata;

    if (reply == NULL) {
        if (c->errstr) {
            printf("errstr: %s\n", c->errstr);
        }
        return;
    }

    printf("Key: %s, value: %s\n", key, reply->str);

    /* Disconnect after receiving the reply to GET */
    redisAsyncDisconnect(c);
}
    .
    .
    .

// Key and string value to pass to `SET`.
char *key = "testkey";
char *value = "testvalue";

// We aren't interested in the simple status reply for
// `SET`, so use NULL for the callback and custom data
// pointers.
redisAsyncCommand(c, NULL, NULL, "SET %s %s", key, value);

// The reply from `GET` is essential, so set a callback
// to retrieve it. Also, pass the key to the callback
// as the custom data.
redisAsyncCommand(c, getCallback, key, "GET %s", key);

请注意,当您使用完连接后,通常应在回调函数中异步断开连接。使用 redisAsyncDisconnect() 优雅地断开连接,让待处理命令执行并激活其回调函数。使用 redisAsyncFree() 立即断开连接。如果这样做,则已执行命令的任何待处理回调函数将以 NULL 回复指针调用。

命令回复

redisReply 对象中的信息有几种格式,特定回复的格式取决于生成它的命令。参阅 处理回复 了解不同的回复格式以及如何使用它们。

评价本页
回到顶部 ↑