二进制数据
使用二进制数据
默认情况下,触发器和函数会将所有数据解码为字符串,并在出现错误时引发错误。虽然对大多数用户来说很有用,但有时需要使用二进制数据。为此,库开发人员必须考虑以下内容
二进制函数参数
可以使用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]
}
);
上述示例将允许我们设置key
和val
,即使它们是二进制数据。运行示例
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
,它将作为批量字符串
返回给客户端。
数据库触发器上的二进制键名
在键空间触发器上,如果触发事件的键名是二进制的,则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
提供,并且可以在这种情况下使用。此外,如果流的内容是二进制的,它也会在data.record
下显示为null
。在这种情况下,可以使用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"