Orientação gerada a partir de informações públicas. Apenas para referência.
Um cliente Redis de alto desempenho para Flutter e Dart, projetado para simplicidade e eficiência. Permite integração perfeita com bancos de dados Redis em múltiplas plataformas, incluindo Android, iOS, macOS, Windows e Linux. O pacote fornece uma API limpa e intuitiva para interagir com o Redis, suportando operações comuns como armazenamento chave-valor, mensagens pub/sub e comandos atômicos. Construído com desempenho em mente, é ideal para aplicações em tempo real que exigem acesso rápido aos dados e operações de baixa latência.
Casos de uso
Cache de dados em tempo real
Mensageria com pub/sub
Gerenciamento de sessão
Limitação de taxa
Recuperação de dados de alta velocidade
Principais recursos
Suporte multiplataforma
Operações de baixa latência
Design de API simples
Mensageria Pub/Sub
execução de comando atômico
Indicado para
Aplicativos em tempo real
Serviços de alto tráfego
Camadas de cache
Integrações de backend
Considerações
Requer um servidor Redis em execução
Limitado a comandos básicos do Redis
Sem pooling de conexão embutido
Não adequado para módulos Redis complexos
Dependência de rede para instâncias remotas
README original
Snapshot do README original do repositório-fonte vinculado. Consulte o repositório para o conteúdo mais recente.
Another way is to execute commands without waiting for the previous command to
complete, and we can still be sure that the response handled by Future will be
completed in the correct order.
Difference is that there are five commands in last examples
and only one in the previous example.
Generic
Redis responses and requests can be arbitrarily nested.
Mapping
Redis
Dart
String
String
Integer
Integer
Array
List
Error
RedisError
Bulk
String or Binary
* Both simple string and bulk string from Redis are serialized to Dart string.
Strings from Dart to Redis are converted to bulk string. UTF8 encoding is used
in both directions.
New feature since 3.0: Support for converting received data as [binary data](#Binary data).
Lists can be nested. This is useful when executing the EVAL command.
or by passing any other Socket to
RedisConnection.connectWithSocket(Socket s) in similar fashion.
Fast
Tested on a laptop, we can execute and process 180K INCR operations per second.
Example
constint N = 200000;
int start;
final conn = RedisConnection();
conn.connect('localhost',6379).then((Command command){
print("test started, please wait ...");
start = DateTime.now().millisecondsSinceEpoch;
command.pipe_start();
command.send_object(["SET","test","0"]);
for(int i=1;i<=N;i++){
command.send_object(["INCR","test"])
.then((v){
if(i != v)
throw("wrong received value, we got $v");
});
}
//last command will be executed and then processed last
command.send_object(["GET","test"]).then((v){
print(v);
double diff = (newDateTime.now().millisecondsSinceEpoch - start)/1000.0;
double perf = N/diff;
print("$N operations done in $diff s\nperformance $perf/s");
});
command.pipe_end();
});
We are not just sending 200K commands here, but also checking result of every send command.
Using command.pipe_start(); and command.pipe_end(); does nothing more
than enabling and disabling the Nagle's algorhitm on socket. By default it is disabled to achieve shortest
possible latency at the expense of more TCP packets and extra overhead. Enabling
Nagle's algorithm during transactions can achieve greater data throughput and
less overhead.
Transactions by redis protocol are started by MULTI command and completed with
EXEC command. .multi(), .exec() and class Transaction are implemented as
helpers for checking the result of each command executed during transaction.
Future<Transaction> Command.multi();
Executing multi() returns a Future<Transaction>. This class should be used
to execute commands by calling .send_object. It returns a Future that is
called after calling .exec().
import'package:redis/redis.dart';
...
final conn = RedisConnection();
conn.connect('localhost',6379).then((Command command){
command.multi().then((Transaction trans){
trans.send_object(["SET","val","0"]);
for(int i=0;i<200000;++i){
trans.send_object(["INCR","val"]).then((v){
assert(i==v);
});
}
trans.send_object(["GET","val"]).then((v){
print("number is now $v");
});
trans.exec();
});
});
It's impossible to write code that depends on the result of the previous command
during a transaction, because all commands are executed at once. To overcome
this, user should use the CAS.
Cas requires a Command as a constructor argument. It implements two methods:
watch and multiAndExec.
watch takes two arguments: a list of keys to watch and a handler to call and
to proceed with CAS.
Example:
cas.watch(["key1,key2,key3"],(){
//body of CAS
});
Failure happens if the watched key is modified outside of the transaction. When
this happens the handler is called until final transaction completes.
multiAndExec is used to complete a transaction with a handler where
the argument is Transaction.
Example:
//last part in body of CAS
cas.multiAndExec((Transaction trans){
trans.send_object(["SET","key1",v1]);
trans.send_object(["SET","key2",v2]);
trans.send_object(["SET","key2",v2]);
});
Lets imagine we need to atomically increment the value of a key by 1 (and that
Redis does not have the INCR command).
Cas cas = newCas(command);
cas.watch(["key"], (){
command.send_object(["GET","key"]).then((String val){
int i = int.parse(val);
i++;
cas.multiAndExec((Transaction trans){
trans.send_object(["SET","key",i.toString()]);
});
});
});
Unicode
By default UTF8 encoding/decoding for string is used. Each string is converted
in binary array using UTF8 encoding. This makes ascii string compatible in both
direction.
Binary data
Default conversion response from Redis of Bulk data is converted to utf-8 string.
In case when binary interpretation is needed, there is option to request such parsing.
final conn = RedisConnection();
Command cmd = await conn.connect('localhost',6379);
Command cmd_bin = Command.from(cmd).setParser(RedisParserBulkBinary());
List<int> d = [1,2,3,4,5,6,7,8,9];
// send binaryawait cmd_bin.send_object(["SET", key, RedisBulk(d)]);
// receive binary from binary command handlervar r = await cmd_bin.send_object(["GET", key])
// r is now same as d