在上一篇《mini-redis项目-4-服务端》中,我们实现了mini-redis的服务端,这一篇来实现客户端;
源代码:
系列文章:
- 《mini-redis项目-1-简介》
- 《mini-redis项目-2-存储层》
- 《mini-redis项目-3-连接层》
- 《mini-redis项目-4-服务端》
- 《mini-redis项目-5-客户端》
- 《mini-redis项目-6-测试与示例》
mini-redis项目-5-客户端
客户端入口
和服务端相同,客户端的入口也是 bin 目录下的可执行文件,具体实现如下:
首先来看客户端命令行的定义:
src/bin/cli.rs
1 | use mini_redis::client::cmd::Command; |
我们定义了客户端的命令行参数 Cli,包括:
- command:子命令,同时使用了
#[clap(subcommand)]标注;注意:这里的 Command 是客户端命令行 Command 不是我们上一节讲述的 mini-redis 中的命令! - host:服务端地址,默认为
127.0.0.1; - port:服务端端口地址,默认为
DEFAULT_PORT=6379;
main 函数的定义如下:
1 | /// Entry point for CLI tool. |
和服务端类似,也是:
- 首先初始化了 env、logger、cli;
- 随后通过
client::connect(&addr).await建立了和服务端之间的 TCP 连接; - 最后通过 match 执行命令行指定的对应的命令;
上面的 Command、Client 都在 client 模块中定义,下面我们具体来看;
Client模块概述
client 模块的目录结构如下:
1 | $ tree ./src/client |
各个文件内容:
- mod:对外暴露了 connect 函数,获取 TCP 连接并创建 Client;
- cmd:定义客户端命令行工具的 Command 命令;
- cli:定义 Client 实现;
- subscriber:客户端 channel 订阅者;
下面分别来看;
命令行子命令
在 cmd.rs 中定义了上文中使用 #[clap(subcommand)] 宏标注的子命令 command 字段;
下面是具体实现:
src/client/cmd.rs
1 |
|
可以看到各个子命令基本上是和 mini-redis 中的命令一一对应;
同时,有几个命令通过 from_str 指定了类型转换,完成的对应格式的解析;
这里可以学到 clap 命令行库的用法;
创建客户端
在 mod.rs 中定义了创建客户端的函数 connect:
src/client/mod.rs
1 | /// Establish a connection with the Redis server located at `addr`. |
函数通过获取 socket 创建了我们之前第三篇中定义的 Connection(发送一整个 Frame),并返回;
逻辑非常简单,不再赘述;
客户端实现Client
先来看 Client 的定义:
src/client/cli.rs
1 | pub struct Client { |
非常简单,就是包装了我们之前定义的 Connection;
下面来看 Client 中的方法:
1 | impl Client { |
逻辑都非常类似,都是:
- 先通过创建对应命令,然后调用
into_frame转为具体的 frame; - 然后通过 connection 中封装好的 write_frame 方法,将数据发送给 Server;
- 最后再调用内部的 read_response 方法,解析响应并输出;
Channel订阅Subscriber
当执行了 subscribe 命令后,会创建对应的 Subscriber 来订阅各个 channel;
具体实现如下:
1 | /// A client that has entered pub/sub mode. |
实现逻辑也很清晰:主要就是将 Client 封装了一层,然后通过 connection 提供的 stream 读取消息;
同时也能接收 sub/unsub 命令,并且处理逻辑和服务端非常相似;
小结
本篇讲解了客户端的实现,由于前面几个部分的封装,使得客户端的实现变得非常简单;
下一篇也会是本系列的最后一篇,主要是对我们的实现进行测试;
附录
源代码:
系列文章:
- 《mini-redis项目-1-简介》
- 《mini-redis项目-2-存储层》
- 《mini-redis项目-3-连接层》
- 《mini-redis项目-4-服务端》
- 《mini-redis项目-5-客户端》
- 《mini-redis项目-6-测试与示例》