二进制数据

使用二进制数据

Redis开源 Redis Enterprise 软件 Redis云 Redis开源 用于 Kubernetes 的 Redis Enterprise 客户端

默认情况下,触发器和函数会将所有数据解码为字符串,并在失败时引发错误。虽然对大多数用户有用,但有时需要处理二进制数据。为了做到这一点,库开发人员必须考虑以下因素

  1. 二进制函数参数
  2. 二进制命令结果
  3. 键空间触发器上的二进制键名
  4. 流触发器上的二进制数据

二进制函数参数

可以使用redis.functionFlags.RAW_ARGUMENTS函数标志,指示触发器和函数不要将函数参数解码为JS 字符串。 在这种情况下,函数参数将作为JS ArrayBuffer给出。 例子

#!js api_version=1.0 name=lib
redis.registerFunction("my_set",
    (c, key, val) => {
        return c.call("set", key, val);
    },
    {
        flags: [redis.functionFlags.RAW_ARGUMENTS]
    }
);

上面的例子允许我们设置keyval,即使它们是二进制数据。 运行例子

127.0.0.1:6379> TFCALL lib.my_set 1 "\xaa" "\xaa"
"OK"
127.0.0.1:6379> get "\xaa"
"\xaa"

请注意,call函数也接受JS ArrayBuffer参数。

二进制命令结果

将函数参数作为二进制数据获取是不够的。 我们可能想要从 Redis 键中读取二进制数据。 为了做到这一点,我们可以使用callRaw函数,它不会将结果解码为JS 字符串,而是将结果作为JS ArrayBuffer返回。 例子

#!js api_version=1.0 name=lib
redis.registerFunction("my_get", 
    (c, key) => {
        return c.callRaw("get", key);
    },
    {
        flags: [redis.functionFalgs.RAW_ARGUMENTS]
    }
);

上面的例子将能够获取二进制数据并将其返回给用户。 例如

27.0.0.1:6379> set "\xaa" "\xaa"
OK
127.0.0.1:6379> TFCALL lib.my_get 1 "\xaa"
"\xaa"

请注意,JS ArrayBuffer可以由函数返回,它将作为bulk string返回给客户端。

数据库触发器上的二进制键名

键空间触发器上,如果触发事件的键名是二进制的,则data.key字段将为 NULL。 data.key_raw字段始终作为JS ArrayBuffer提供,并且可以像以下示例中使用

#!js api_version=1.0 name=lib
/* The following is just an example, in general it is discourage to use globals. */
var n_notifications = 0;
var last_key = null;
var last_key_raw = null;
redis.registerKeySpaceTrigger("consumer", "", function(client, data) {
    if (data.event == "set") {
        n_notifications += 1;
        last_data = data.key;
        last_key_raw = data.key_raw;
    }
});

redis.registerFunction("notifications_stats", async function(){
    return [
        n_notifications,
        last_key,
        last_key_raw
    ];
});

运行例子

127.0.0.1:6379> set "\xaa" "\xaa"
OK
127.0.0.1:6379> TFCALL lib.notifications_stats 0
1) (integer) 1
2) (nil)
3) "\xaa"

有关更多信息,请参见键空间触发器

流消费者上的二进制数据

流触发器上,如果键名是二进制的。 data.stream_name字段将为 NULL。 data.stream_name_raw字段始终作为JS ArrayBuffer提供,可以在这种情况下使用。 此外,如果 steam 的内容是二进制的,它也会显示为nulldata.record下。 在这种情况下,可以使用data.record(它始终存在)并包含作为JS ArrayBuffer的数据。 例子

#!js api_version=1.0 name=lib
/* The following is just an example, in general it is discourage to use globals. */
var last_key = null;
var last_key_raw = null;
var last_data = null;
var last_data_raw = null;
redis.registerFunction("stats", function(){
    return [
        last_key,
        last_key_raw,
        last_data,
        last_data_raw
    ];
})
redis.registerStreamTrigger("consumer", new Uint8Array([255]).buffer, function(c, data){
    last_key = data.stream_name;
    last_key_raw = data.stream_name_raw;
    last_data = data.record;
    last_data_raw = data.record_raw;
})

运行例子

127.0.0.1:6379> xadd "\xff\xff" * "\xaa" "\xaa"
"1659515146671-0"
127.0.0.1:6379> TFCALL foo.stats 0
1) (nil)
2) "\xff\xff"
3) 1) 1) (nil)
      2) (nil)
4) 1) 1) "\xaa"
      2) "\xaa"
为本页评分
返回顶部 ↑