202 lines
5.1 KiB
Dart
202 lines
5.1 KiB
Dart
import 'package:redis/redis.dart';
|
|
|
|
class Redis {
|
|
final RedisConfig _config;
|
|
Command? _command;
|
|
bool _connected = false;
|
|
|
|
Redis(this._config);
|
|
|
|
static late Redis _redis;
|
|
|
|
static Redis getInstance() {
|
|
return _redis;
|
|
}
|
|
|
|
static void setInstance(Redis redis) {
|
|
_redis = redis;
|
|
}
|
|
|
|
bool isConnected() {
|
|
return this._connected;
|
|
}
|
|
|
|
Future<void> connect({reconnect = false}) async {
|
|
_connected = false;
|
|
if (reconnect) {
|
|
print("尝试重连Redis");
|
|
}
|
|
Future.delayed(Duration(seconds: 1), () async {
|
|
try {
|
|
_command = await RedisConnection().connect(_config.host, _config.port);
|
|
print('Redis Connected successfully!');
|
|
if (_config.password != null) {
|
|
var authResult =
|
|
await _command!.send_object(['AUTH', _config.password]);
|
|
if (authResult == "OK") {
|
|
print('Redis Authentication successfully');
|
|
} else {
|
|
print('Redis Authentication failed');
|
|
connect(reconnect: reconnect);
|
|
}
|
|
}
|
|
if (_config.database != 0) {
|
|
var result = await _command!
|
|
.send_object(["SELECT", _config.database.toString()]);
|
|
if (result == "OK") {
|
|
print('Redis use db ${_config.database}');
|
|
}
|
|
}
|
|
|
|
_connected = true;
|
|
//定时检测是否断开连接
|
|
Future.delayed(Duration(seconds: 1), () async {
|
|
await Future.doWhile(() async {
|
|
await Future.delayed(Duration(seconds: 5));
|
|
try {
|
|
var r = await _command!.send_object(["PING"]);
|
|
if (r != "PONG") {
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
//发送数据失败
|
|
try {
|
|
print('Redis Connection check failed: $e');
|
|
_command!.get_connection().close();
|
|
} catch (o) {
|
|
//
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
// do {
|
|
// await Future.delayed(Duration(seconds: 5));
|
|
// try {
|
|
// var r = await _command!.send_object(["PING"]);
|
|
// if (r != "PONG") {
|
|
// break;
|
|
// }
|
|
// } catch (e) {
|
|
// //发送数据失败
|
|
// try {
|
|
// print('Redis Connection check failed: $e');
|
|
// _command!.get_connection().close();
|
|
// } catch (o) {
|
|
// //
|
|
// }
|
|
// break;
|
|
// }
|
|
// } while (true);
|
|
connect(reconnect: true);
|
|
});
|
|
} catch (e) {
|
|
print('Redis Connection error: $e');
|
|
connect(reconnect: reconnect);
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<bool> set(String key, String value) async {
|
|
try {
|
|
var response = await _command?.send_object(["SET", key, value]);
|
|
return response == "OK";
|
|
} catch (e) {
|
|
print(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> setData(String key, dynamic value, {int? ttl}) async {
|
|
try {
|
|
var response;
|
|
var val = value is String ? value : RedisBulk(value);
|
|
if (ttl != null) {
|
|
response =
|
|
await _command?.send_object(["SETEX", key, ttl.toString(), val]);
|
|
} else {
|
|
response = await _command?.send_object(["SET", key, val]);
|
|
}
|
|
return response == "OK";
|
|
} catch (e) {
|
|
print(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<String?> get(String key) async {
|
|
try {
|
|
return await _command?.send_object(["GET", key]);
|
|
} catch (e) {
|
|
print(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<dynamic> getData(String key) async {
|
|
try {
|
|
return await _command?.send_object(["GET", key]);
|
|
} catch (e) {
|
|
print(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<bool> delete(String key) async {
|
|
try {
|
|
return await _command?.send_object(["DEL", key]) == "OK";
|
|
} catch (e) {
|
|
print(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> setWithExpiry(String key, String value, int ttlInSeconds) async {
|
|
try {
|
|
var response = await _command
|
|
?.send_object(["SETEX", key, ttlInSeconds.toString(), value]);
|
|
return response == "OK";
|
|
} catch (e) {
|
|
print(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<List<String>> scanKeys(String key, {int timeout = 30}) async {
|
|
List<String> keys = [];
|
|
int cursor = 0;
|
|
try {
|
|
do {
|
|
final result = await _command
|
|
?.send_object(['SCAN', cursor.toString(), 'MATCH', key]);
|
|
final List<dynamic> scanResult = result as List<dynamic>;
|
|
cursor = int.parse(scanResult[0] as String);
|
|
final List<dynamic> foundKeys = scanResult[1] as List<dynamic>;
|
|
|
|
keys.addAll(foundKeys.map((k) => k.toString()));
|
|
} while (cursor != 0);
|
|
|
|
// return await scanKeys(cmd, pattern)
|
|
// .timeout(Duration(seconds: timeoutSeconds));
|
|
} catch (e) {
|
|
print('Scan failed: $e');
|
|
return [];
|
|
}
|
|
return keys;
|
|
}
|
|
}
|
|
|
|
class RedisConfig {
|
|
String host;
|
|
int port;
|
|
String? password;
|
|
int database;
|
|
|
|
RedisConfig({
|
|
required this.host,
|
|
this.port = 6379,
|
|
this.password,
|
|
this.database = 0,
|
|
});
|
|
}
|