二进制数据
使用二进制数据
Redis 堆栈 | Redis 社区版 | Redis 企业软件 | Redis 云 | Redis 社区版 | 适用于 Kubernetes 的 Redis Enterprise | 客户 |
---|
默认情况下,触发器和函数会将所有数据解码为字符串,并在失败时引发错误。尽管对大多数用户很有用,但有时需要处理二进制数据。为此,库开发人员必须考虑以下事项:
二进制函数参数
可以指示触发器和函数不要将函数参数解码为JS
Strings
使用 redis.functionFlags.RAW_ARGUMENTS 函数标志。在这种情况下,函数参数将作为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]
}
);
The above example will allow us to set
key
and val
even if those are binary data. Run example:
127.0.0.1:6379> TFCALL lib.my_set 1 "\xaa" "\xaa"
"OK"
127.0.0.1:6379> get "\xaa"
"\xaa"
Notice that the call
function also accepts JS
ArrayBuffer
arguments.
Binary command results
Getting function arguments as binary data is not enough. We might want to read binary data from a Redis key. In order to do this we can use the callRaw
function, which will not decode the result as a JS
String
and instead will return the result as a JS
ArrayBuffer
. Example:
#!js api_version=1.0 name=lib
redis.registerFunction("my_get",
(c, key) => {
return c.callRaw("get", key);
},
{
flags: [redis.functionFalgs.RAW_ARGUMENTS]
}
);
The above example will be able to fetch binary data and return it to the user. For example:
27.0.0.1:6379> set "\xaa" "\xaa"
OK
127.0.0.1:6379> TFCALL lib.my_get 1 "\xaa"
"\xaa"
Notice that a JS
ArrayBuffer
can be returned by a function, it will be returned to the client as bulk string
.
Binary keys names on database triggers
On keyspace triggers, if the key name that triggered the event is binary, the data.key
field will be NULL. The data.key_raw
field is always provided as a JS
ArrayBuffer
and can be used as in the following example:
#!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
];
});
Run example:
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"
For more information see keyspace triggers.
Binary data on stream consumers
On stream triggers, if the key name is binary. The data.stream_name
field will be NULL. The data.stream_name_raw
field is always provided as a JS
ArrayBuffer
and can be used in this case. In addition, if the content of the steam is binary, it will also appear as null
under data.record
. In this case, it is possible to use data.record
(which always exists) and contains the data as a JS
ArrayBuffer
. Example:
#!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;
})
Run Example:
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"
On this page