0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在服务器端使用内存来存储客户端发送过来的数据

工程师邓生 来源:coding到灯火阑珊 作者:李明 2022-09-29 10:03 次阅读

在这篇文章中,我们将在服务器端使用内存来存储客户端发送过来的数据。在实现数据存储之前,我们先在客户端使用Clap库来解析命令行参数,并封装成命令发送给服务器。

Clap解析命令行参数 在Cargo.toml文件中加入clap依赖:

clap = {version = "3.1", features = ["derive"]}

在src目录下新建args.rs文件,写入以下代码:
 1useclap::Parser;
 2
 3#[derive(Debug,Parser)]
 4#[clap(name="kv_client")]
 5pubenumClientArgs{
 6Get{
 7#[clap(long)]
 8key:String,
 9},
10Set{
11#[clap(long)]
12key:String,
13#[clap(long)]
14value:String,
15},
16Publish{
17#[clap(long)]
18topic:String,
19#[clap(long)]
20value:String,
21},
22Subscribe{
23#[clap(long)]
24topic:String,
25},
26Unsubscribe{
27#[clap(long)]
28topic:String,
29#[clap(long)]
30id:u32,
31}
32}
在src/lib.rs中加入以下代码:
1modargs;
2pubuseargs::*;
修改src/bin/kv_client.rs代码:
 1#[tokio::main]
 2asyncfnmain()->Result<(), Box>{
 3......
 4
 5letclient_args=ClientArgs::parse();
 6
 7//解析命令行参数,生成命令
 8letcmd=process_args(client_args).await?;
 9//命令编码
10cmd.encode(&mutbuf).unwrap();
11//发送命令
12stream.send(buf.freeze()).await.unwrap();
13info!("Send command successed!");
14
15loop{
16tokio::select!{
17Some(Ok(buf))=stream.next()=>{
18letcmd_res=CmdResponse::decode(&buf[..]).unwrap();
19info!("Receivearesponse:{:?}",cmd_res);
20}
21}
22}
23}
 1//生成CmdRequest命令
 2asyncfnprocess_args(client_args:ClientArgs)->Result>{
 3matchclient_args{
 4//生成GET命令
 5ClientArgs::Get{key}=>{
 6Ok(CmdRequest::get(key))
 7},
 8//生成SET命令
 9ClientArgs::Set{key,value}=>{
10Ok(CmdRequest::set(key,value.into()))
11},
12//生成PUBLISH命令
13ClientArgs::Publish{topic,value}=>{
14Ok(CmdRequest::publish(topic,value.into()))
15},
16//生成SUBSCRIBE命令
17ClientArgs::Subscribe{topic}=>{
18Ok(CmdRequest::subscribe(topic))
19},
20//生成UNSUBSCRIBE命令
21ClientArgs::Unsubscribe{topic,id}=>{
22Ok(CmdRequest::unsubscribe(topic,id))
23}
24}
25}

打开一个终端,启动kv_sever。打开另一个终端执行以下命令来测试客户端:

RUST_LOG=info cargo run --bin kv_client get --key mykeyRUST_LOG=info cargo run --bin kv_client set --key mykey --value myvalue

服务器和客户端都正常处理了收到的请求和响应。

内存存储

我们使用dashmap crate在内存中存储数据,dashmap是一个快速的并发map。

我们先创建src/storage目录,再创建src/storage/mod.rs文件,然后在src/lib.rs文件中引入storage模块。

在src/storage/mod.rs文件中定义一个storage trait,以便于以后不同存储方式的扩展,代码如下:

1usestd::Error;
2
3usebytes::Bytes;
4
5pubtraitStorage{
6fnget(&self,key:&str)->Result,Box>;
7fnset(&self,key:&str,value:Bytes)->Result<(), Box>;
8}

在src/storage目录下创建mem_storage.rs文件:

 1#[derive(Clone,Debug,Default)]
 2pubstructMemStorage{
 3map:DashMap
 4}
 5
 6implMemStorage{
 7pubfnnew()->Self{
 8Self{
 9map:Default::default(),
10}
11}
12}
13
14implStorageforMemStorage{
15fnget(&self,key:&str)->Result,Box>{
16Ok(self.map.get(key).map(|v|v.value().clone()))
17}
18
19fnset(&self,key:&str,value:Bytes)->Result,Box>{
20self.map.insert(key.to_string(),value.clone());
21Ok(Some(value))
22}
23}

修改kv_server.rs代码:

 1asyncfnmain()->Result<(), Box>{
 2......
 3
 4//初始化内存存储
 5letstorage=Arc::new(MemStorage::new());
 6
 7loop{
 8......
 9
10letstor=storage.clone();
11
12tokio::spawn(asyncmove{
13//使用Frame的LengthDelimitedCodec进行编解码操作
14letmutstream=Framed::new(stream,LengthDelimitedCodec::new());
15whileletSome(Ok(mutbuf))=stream.next().await{
16//对客户端发来的protobuf请求命令进行拆包
17letcmd_req=CmdRequest::decode(&buf[..]).unwrap();
18info!("Receiveacommand:{:?}",cmd_req);
19
20//处理请求命令
21letcmd_res=process_cmd(cmd_req,&stor).await.unwrap();
22
23buf.clear();
24
25//对protobuf的请求响应进行封包,然后发送给客户端。
26cmd_res.encode(&mutbuf).unwrap();
27stream.send(buf.freeze()).await.unwrap();
28}
29info!("Client{:?}disconnected",addr);
30});
31}
32}
33
34//处理请求命令,返回Response
35asyncfnprocess_cmd(req:CmdRequest,storage:&MemStorage)->Result>{
36matchreq{
37//处理GET命令
38CmdRequest{
39req_data:Get(Get{key})),
40}=>{
41letvalue=storage.get(&key)?;
42Ok(CmdResponse::new(200,"getsuccess".to_string(),value.unwrap_or_default()))
43},
44//处理SET命令
45CmdRequest{
46req_data:Set(Set{key,value})),
47}=>{
48letvalue=storage.set(&key,value)?;
49Ok(CmdResponse::new(200,"setsuccess".to_string(),value.unwrap_or_default()))
50},
51_=>Err("Invalidcommand".into())
52}
53}

测试

1,打开一个终端,运行kv_server:

RUST_LOG=info cargo run --bin kv_server

2,打开一个终端,运行kv_client,执行set命令:

RUST_LOG=info cargo run --bin kv_client set --key mykey --value myvalue

3,打开一个终端,运行kv_client,执行get命令:
RUST_LOG=info cargo run --bin kv_client get --key mykey

执行结果:

INFO kv_client: Send command successed!

INFO kv_client: Receive a response: CmdResponse { status: 200, message: "get success", value: b"myvalue" }




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8933

    浏览量

    85049
  • 数据存储
    +关注

    关注

    5

    文章

    956

    浏览量

    50826

原文标题:用Rust实现KV Server-3 命令行解析与内存存储

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    使用lwip socket udp功能,开发板为客户端时不能够接收服务器端发送过来数据

    请教下,使用 lwip socket udp 功能,开发板为客户端时不能够接收服务器端发送过来数据 ? 1,如果开发板为 服务器端,收发
    发表于 04-16 06:01

    用队列实现的1对N的TCP服务器端,自动回复信息总发错客户端

    本帖最后由 kaneiqi1210 于 2014-7-17 12:43 编辑 如题,我仿照教材用队列做的TCP一对多的服务器端1对1时,没问题,而在1对多时,就出现,自动回复信息至不正确的客户端(即非
    发表于 07-17 09:31

    labview TCP客户端

    最近在做一个labview 客户端测试小程序,服务器采用MFC编写,客户端采用TCP侦听函数,通信可以连接,数据也正确,但是服务器端检测
    发表于 06-30 23:15

    qt tcp程序服务器端发送数据之前能接收客户端发送数据吗?

    写了一个tcp的客户端服务器端,是服务器端客户端发送文件,但是我想在服务器端
    发表于 04-22 20:06

    labview怎么实现服务器端一直等待客户端发送数据

    我现在在做labview的服务器端,但是当客户端发送数据结束后,我的服务器端会报错。报错的意思就是说客户
    发表于 08-12 14:34

    labview和 读码的以太网通信 (没有服务器端的程序)

    像电脑一样能运行LABVIEW程序,两台读码扫描到的数据统一由主站通过以太网TCP直接发送过来的,现在不知道咋办,网络上关于这方面的资料太少了,都是有服务器端程序的,我摸索了好久仍然
    发表于 08-14 17:31

    LwIP调试问题,实现的是客户端过来数据直接原样返回

    最近在搞LwIP,裸跑,开发板做TCP服务器,电脑做客户端,程序实现的是客户端过来数据直接原样返回。调试的时候遇到下面问题:在建立连接的
    发表于 10-03 09:25

    怎么用key0,key2控制服务器端客户端知道有数据发送请求的?

    原子用key0,key2控制服务器端客户端有请求数据发送,是如何知道有数据发送请求的,没看明白
    发表于 07-29 04:17

    TCP:多个客户端服务器发送数据

    本帖最后由 埥茬適里瀭叺妏牸 于 2019-8-23 10:27 编辑 就是当多个客户端第一次连接上服务器发送数据没问题,但是途中更改客户
    发表于 08-22 15:05

    为什么LWIP的TCP客户端服务器端断开后继续发送数据就无法检测到连接状态?

    发现LWIP的TCP客户端有个BUG,当服务器端开之后,如果还继续发送数据,那就不能检测到连接状态。求助求助
    发表于 10-29 20:26

    使用Arduino编程和esp32的开发板,多个客户端连接服务器时怎么判断是哪个客户端发送过来数据

    我使用的是Arduino编程和esp32的开发板,当多个客户端连接服务器的时候,服务器怎么判断是哪个客户端发送过来
    发表于 05-23 15:39

    如何使用esp8266服务器客户端之间发送数据

    我是这个小组的新手,我刚刚写信,如果有人能帮助我,我需要一个指南甚至一本书学习如何使用 esp8266 服务器客户端之间发送
    发表于 04-27 07:05

    网络调试和串口调试集合UDP TCP客户端和TCP服务器端应用程序免费下载

    本文档的主要内容详细介绍的是网络调试和串口调试集合UDP TCP客户端和TCP服务器端应用程序免费下载。
    发表于 08-30 08:00 16次下载
    网络调试和串口调试集合UDP TCP<b class='flag-5'>客户端</b>和TCP<b class='flag-5'>服务器端</b>应用程序免费下载

    数据是怎么样保证准确的从客户端发送服务器端

    你有想过吗,计算机网络当中,数据是怎么样保证准确的从客户端发送服务器端的?中间涉及到了哪些理论?
    的头像 发表于 07-01 10:09 1974次阅读

    拒绝服务攻击的基本概念

    服务器端收到客户端发送过来的SYN请求包后,知道客户端想要建立连接,于是向客户端发送一个SYN请
    的头像 发表于 10-08 11:07 3332次阅读