2. 扩展Redis仓颉语言客户端
2.1 Redis命令处理模块的架构
Redis命令处理的架构图如下:
RedisCommand类
Redis命令的实现类
包含以下成员:
commandType: Redis命令的名称
commandArgs: Redis命令的参数列表
response: Redis命令的响应消息,类型为RedisMessage
exception: 执行Redis命令发生的异常
CommandArg类
封装Redis命令的基本类型参数,包括Array、String、Integer、Double
CommandArgs类
Redis命令的参数列表,包含CommandArg的列表
CompositeArgs类
封装Redis命令参数列表中存在关联关系的多个参数
调用buildArgs(CommandArgs)方法将多个存在关联的参数添加到CommandArgs的参数列表中
RedisMessage类
封装Redis命令的响应消息
RESP2协议对应的RedisMessage:
SIMPLE_STRINGS: StringRedisMessage
SIMPLE_ERRORS: ErrorRedisMessage
INTEGERS: IntegerRedisMessage
BULK_STRINGS: BulkStringRedisMessage
ARRAYS: ArraysRedisMessage
RESP3协议对应的RedisMessage:
NULLS:NullArraysRedisMessage
BOOLEANS:BooleanRedisMessage
DOUBLES:DoubleRedisMessage
BIG_NUMBERS:BigNumberRedisMessage
BULK_ERRORS:BulkErrorRedisMessage
VERBATIM_STRINGS:VerbatimRedisMessage
MAPS:MapRedisMessage
SETS:SetRedisMessage
PUSHES:PushesRedisMessage
ResponseBuilder类
将RedisMessage转换为命令执行的结果
基本数据类型的RepsonseBuilder实现:
StringResponseBuilder
IntegerResponseBuilder
DoubleResponseBuilder
BoolResponseBuilder
NillableStringResponseBuilder
集合类型的RepsonseBuilder实现:
ListResponseBuilder
SetOfResponseBuilder
PrimitiveMapResponseBuilder<String, T>
ListOfAnyResponseBuilder
MapOfAnyResponseBuilder
ParameterizedRedisCommand类
RedisCommand的子类,支持将Redis命令的响应构建为类型T,包含成员RepsonseBuilder用于处理响应
注意: 需要返回响应的命令,可以使用RedisCommand类, 也可以使用ParameterizedRedisCommand类;
不需要返回响应的命令,只能使用RedisCommand类
2.2 Redis编解码模块的架构
Redis编解码处理的架构图如下:
MessageCompletedHandler接口
解码二进制报文时,判断二进制报文是否包含完整的消息报文
ByteToRedisMessageDecoder类
RESP协议解码器实现,将RESP协议的二进制报文转换为RedisMessage
该类实现了MessageCompletedHandler接口
RedisCommandToByteEncoder类
RESP协议编码器实现,将RedisCommand编码为RESP协议的二进制报文
RedisCodec类
实现了Hyperion TCP框架的IOFilter接口,处理Redis命令和Redis响应的编解码
RedisCommandHandler类
实现了Hyperion TCP框架的IOFilter接口,处理RedisMessage和RedisCommand的关联
RedisSubscriberHandler类
实现了Hyperion TCP框架的IOFilter接口,处理RedisMessage和Redis订阅者的关联
在未切换成订阅模式之前,处理方式和RedisCommandHandler类一致(处理认证和握手相关命令)
切换成订阅模式之后,只能执行以下命令:
SUBSCRIBE channel [channel …]
PSUBSCRIBE pattern [pattern …]
UNSUBSCRIBE channel [channel …]
PUNSUBSCRIBE pattern [pattern …]
UNSUBSCRIBE
PUNSUBSCRIBE
PING
PING message
RedisClientConfig
记录Redis客户端的参数配置
RedisClientBuilder类
用于创建RedisClient对象,RedisClient可以执行Redis命令
RedisClient类
执行Redis命令,并返回命令执行的结果
RedisSubscriberBuilder类
用于创建RedisSubscriber对象,RedisSubscriber可以订阅消息
RedisSubscriber类
订阅Redis频道的消息
2.3 编写Redis命令的实现
对于一个特定的数据类型,例如String类型,需要提供以下2个接口:
StringCommands接口:定义String类型的操作命令对应的接口
StringCommansBuidldler接口:构建Sting类型相关命令对应的ParameterizedRedisCommand对象
需要实现以上2个接口:
StringCommandsImpl类:提供String类型的操作命令对应的实现
StringCommansBuidlerImpl类:构建Sting类型相关命令对应的ParameterizedRedisCommand对象
RedisClient类需要实现StringCommands接口,并将String类型的相关方法委托给StringCommandsImpl类
String类型,支持超时参数的SET命令按如下方式构建(参考StringCommansBuidlerImpl类):
public func set(key: String, value: String, params: SetParams): ParameterizedRedisCommand<?String> {let commandArgs = CommandArgs().add(StringArg(key)).add(StringArg(value))let command = ParameterizedRedisCommand<?String>(CommandType.SET,commandArgs,params,ResponseBuilderFactory.nillableStringBuilder)return command}
String类型,支持超时参数的SET命令的实现如下:
public func set(key: String, value: String, params: SetParams): ?String {let redisCommand = RedisCommandBuilder.set(key, value, params)return executeCommand<String>(redisCommand)}
调用String类型,支持超时参数的SET命令:
let client = RedisClientBuilder.builder().host(servHost).port(servPort).password(servPass).build()// 500秒后超时let result = client.set(myKey, myValue, SetParams().exAt(DateTime.now().addSeconds(500).toUnixTimeStamp().toSeconds())
↓↓↓