还记得我们测试链接的例子吗?
代码如下:
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
let stream = TcpStream::connect("127.0.0.1:6379").await?;
let mut buf = [0u8; 1024];
let mut resp = BytesMut::with_capacity(1024);
let (mut reader, mut writer) = (&stream, &stream);
// 向服务器发送 PING
let mut request = request::Request::new();
request.add_arg("set");
request.add_arg("mykey1");
request.add_arg("myvalue1");
writer.write(&request.to_bytes()).await?;
let n = reader.read(&mut buf).await?;
resp.put(&buf[0..n]);
// 返回结果应该是 PONG
println!("{:?}", resp);
Ok(())
}
我们改造一下其中的代码应用在我们现在写的代码中。
我们现在已经取得了终端的输入,并将其解析为请求-这一数据。我们还可以解析字符数组为回复。现在我们要根据请求,向服务器发送数据,并取得回复。
首先我们建立一个和redis服务器的链接。代码如下:
let stream = TcpStream::connect("127.0.0.1:6379").await?;
在建立链接后,我们建立一个缓存区,来存储从套接字获取的数据。
let mut buf = [0u8; 1024];
在缓存区建立后,我们将链接分为读与写的两部分。
let (mut reader, mut writer) = (&stream, &stream);
在前置的缓存区和redis链接建立后,我们需要向服务器发送请求。
在我们获取请求后,我们便可以向服务器发送请求。代码写入的位置如下:
let (_, request) = request::Request::parer_request(&line).unwrap();
println!("{:?}", request);
代码如下:
let mut resp = BytesMut::with_capacity(1024);
writer.write(&request.to_bytes()).await?;
let n = reader.read(&mut buf).await?;
resp.put(&buf[0..n]);
// 返回结果应该是 PONG
println!("{:?}", resp);
第一行我们新建了一个BytesMut实例,这个实例用于字节数据的操作。第3行我们将请求写入套接字中。然后我们读取redis服务器的回复。我们在这里将回复携带的数据打印出来。
在获得回复数据之后,我们将其装箱到字符串中,并通过已经写好的解析程序解析数据,最终将回复这一类型打印出来。
let resp = String::from_utf8_lossy(&resp);
let (_, reply) = reply::parse(&resp).unwrap();
println!("{:?}", reply);
至此,我们已经完成了一个十分简陋的版本,但核心功能已经实现的redis-cli,后面我们逐步完善这个redis-cli.