二进制数据

使用二进制数据

默认情况下,触发器和函数会将所有数据解码为字符串,并在出现错误时引发错误。虽然对大多数用户来说很有用,但有时需要使用二进制数据。为此,库开发人员必须考虑以下内容

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

二进制函数参数

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

#!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函数还接受JSArrayBuffer参数。

二进制命令结果

获取函数参数作为二进制数据还不够。我们可能希望从 Redis 密钥读取二进制数据。为了做到这一点,我们可以使用callRaw函数,它不会将结果解码为JS字符串,而是将结果作为JSArrayBuffer返回。示例

#!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"

请注意,函数可以返回JSArrayBuffer,它将作为批量字符串返回给客户端。

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

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

#!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字段始终作为JSArrayBuffer提供,并且可以在这种情况下使用。此外,如果流的内容是二进制的,它也会在data.record下显示为null。在这种情况下,可以使用data.record(它始终存在),它包含作为JSArrayBuffer的数据。示例

#!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"
评价此页面