二进制数据
使用二进制数据
默认情况下,触发器和函数会将所有数据解码为字符串,并在失败时引发错误。虽然这对大多数用户很有用,但有时需要处理二进制数据。为此,库开发者需要考虑以下几点:
二进制函数参数
可以使用redis.functionFlags.RAW_ARGUMENTS函数标记来指示触发器和函数不要将函数参数解码为JS
Strings
。在这种情况下,函数参数将作为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
String
,而是会将结果作为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
提供,可以在这种情况下使用。此外,如果流的内容是二进制的,它也会在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"