0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在服務(wù)器端使用內(nèi)存來存儲客戶端發(fā)送過來的數(shù)據(jù)

工程師鄧生 ? 來源:coding到燈火闌珊 ? 作者:李明 ? 2022-09-29 10:03 ? 次閱讀

在這篇文章中,我們將在服務(wù)器端使用內(nèi)存來存儲客戶端發(fā)送過來的數(shù)據(jù)。在實(shí)現(xiàn)數(shù)據(jù)存儲之前,我們先在客戶端使用Clap庫來解析命令行參數(shù),并封裝成命令發(fā)送給服務(wù)器。

Clap解析命令行參數(shù) 在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//解析命令行參數(shù),生成命令
 8letcmd=process_args(client_args).await?;
 9//命令編碼
10cmd.encode(&mutbuf).unwrap();
11//發(fā)送命令
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。打開另一個終端執(zhí)行以下命令來測試客戶端:

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

服務(wù)器和客戶端都正常處理了收到的請求和響應(yīng)。

內(nèi)存存儲

我們使用dashmap crate在內(nèi)存中存儲數(shù)據(jù),dashmap是一個快速的并發(fā)map。

我們先創(chuàng)建src/storage目錄,再創(chuàng)建src/storage/mod.rs文件,然后在src/lib.rs文件中引入storage模塊。

在src/storage/mod.rs文件中定義一個storage trait,以便于以后不同存儲方式的擴(kuò)展,代碼如下:

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

在src/storage目錄下創(chuàng)建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//初始化內(nèi)存存儲
 5letstorage=Arc::new(MemStorage::new());
 6
 7loop{
 8......
 9
10letstor=storage.clone();
11
12tokio::spawn(asyncmove{
13//使用Frame的LengthDelimitedCodec進(jìn)行編解碼操作
14letmutstream=Framed::new(stream,LengthDelimitedCodec::new());
15whileletSome(Ok(mutbuf))=stream.next().await{
16//對客戶端發(fā)來的protobuf請求命令進(jìn)行拆包
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的請求響應(yīng)進(jìn)行封包,然后發(fā)送給客戶端。
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,打開一個終端,運(yùn)行kv_server:

RUST_LOG=info cargo run --bin kv_server

2,打開一個終端,運(yùn)行kv_client,執(zhí)行set命令:

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

3,打開一個終端,運(yùn)行kv_client,執(zhí)行g(shù)et命令:
RUST_LOG=info cargo run --bin kv_client get --key mykey

執(zhí)行結(jié)果:

INFO kv_client: Send command successed!

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




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8842

    瀏覽量

    84946
  • 數(shù)據(jù)存儲
    +關(guān)注

    關(guān)注

    5

    文章

    950

    瀏覽量

    50810

原文標(biāo)題:用Rust實(shí)現(xiàn)KV Server-3 命令行解析與內(nèi)存存儲

文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    使用lwip socket udp功能,開發(fā)板為客戶端時不能夠接收服務(wù)器端發(fā)送過來數(shù)據(jù) ?

    請教下,使用 lwip socket udp 功能,開發(fā)板為客戶端時不能夠接收服務(wù)器端發(fā)送過來數(shù)據(jù) ? 1,如果開發(fā)板為 服務(wù)器端,收發(fā)
    發(fā)表于 04-16 06:01

    用隊列實(shí)現(xiàn)的1對N的TCP服務(wù)器端,自動回復(fù)信息總發(fā)錯客戶端

    本帖最后由 kaneiqi1210 于 2014-7-17 12:43 編輯 如題,我仿照教材用隊列做的TCP一對多的服務(wù)器端,1對1時,沒問題,而在1對多時,就出現(xiàn),自動回復(fù)信息至不正確的客戶端(即非
    發(fā)表于 07-17 09:31

    labview TCP客戶端

    最近在做一個labview 客戶端測試小程序,服務(wù)器采用MFC編寫,客戶端采用TCP偵聽函數(shù),通信可以連接,數(shù)據(jù)也正確,但是服務(wù)器端檢測
    發(fā)表于 06-30 23:15

    qt tcp程序服務(wù)器端發(fā)送數(shù)據(jù)之前能接收客戶端發(fā)送數(shù)據(jù)嗎?

    寫了一個tcp的客戶端服務(wù)器端,是服務(wù)器端客戶端發(fā)送文件,但是我想在服務(wù)器端
    發(fā)表于 04-22 20:06

    labview怎么實(shí)現(xiàn)服務(wù)器端一直等待客戶端發(fā)送數(shù)據(jù)

    我現(xiàn)在在做labview的服務(wù)器端,但是當(dāng)客戶端發(fā)送數(shù)據(jù)結(jié)束后,我的服務(wù)器端會報錯。報錯的意思就是說客戶
    發(fā)表于 08-12 14:34

    labview和 讀碼的以太網(wǎng)通信 (沒有服務(wù)器端的程序)

    像電腦一樣能運(yùn)行LABVIEW程序,兩臺讀碼掃描到的數(shù)據(jù)統(tǒng)一由主站通過以太網(wǎng)TCP直接發(fā)送過來的,現(xiàn)在不知道咋辦,網(wǎng)絡(luò)上關(guān)于這方面的資料太少了,都是有服務(wù)器端程序的,我摸索了好久仍然
    發(fā)表于 08-14 17:31

    LwIP調(diào)試問題,實(shí)現(xiàn)的是客戶端發(fā)過來數(shù)據(jù)直接原樣返回

    最近在搞LwIP,裸跑,開發(fā)板做TCP服務(wù)器,電腦做客戶端,程序?qū)崿F(xiàn)的是客戶端發(fā)過來數(shù)據(jù)直接原樣返回。調(diào)試的時候遇到下面問題:在建立連接的
    發(fā)表于 10-03 09:25

    怎么用key0,key2控制服務(wù)器端客戶端知道有數(shù)據(jù)發(fā)送請求的?

    原子用key0,key2控制服務(wù)器端客戶端有請求數(shù)據(jù)發(fā)送,是如何知道有數(shù)據(jù)發(fā)送請求的,沒看明白
    發(fā)表于 07-29 04:17

    TCP:多個客戶端服務(wù)器發(fā)送數(shù)據(jù)

    本帖最后由 埥茬適里瀭叺妏牸 于 2019-8-23 10:27 編輯 就是當(dāng)多個客戶端第一次連接上服務(wù)器發(fā)送數(shù)據(jù)沒問題,但是途中更改客戶
    發(fā)表于 08-22 15:05

    為什么LWIP的TCP客戶端服務(wù)器端斷開后繼續(xù)發(fā)送數(shù)據(jù)就無法檢測到連接狀態(tài)?

    發(fā)現(xiàn)LWIP的TCP客戶端有個BUG,當(dāng)服務(wù)器端開之后,如果還繼續(xù)發(fā)送數(shù)據(jù),那就不能檢測到連接狀態(tài)。求助求助
    發(fā)表于 10-29 20:26

    使用Arduino編程和esp32的開發(fā)板,多個客戶端連接服務(wù)器時怎么判斷是哪個客戶端發(fā)送過來數(shù)據(jù)?

    我使用的是Arduino編程和esp32的開發(fā)板,當(dāng)多個客戶端連接服務(wù)器的時候,服務(wù)器怎么判斷是哪個客戶端發(fā)送過來
    發(fā)表于 05-23 15:39

    如何使用esp8266服務(wù)器客戶端之間發(fā)送數(shù)據(jù)

    我是這個小組的新手,我剛剛寫信,如果有人能幫助我,我需要一個指南甚至一本書學(xué)習(xí)如何使用 esp8266 服務(wù)器客戶端之間發(fā)送
    發(fā)表于 04-27 07:05

    網(wǎng)絡(luò)調(diào)試和串口調(diào)試集合UDP TCP客戶端和TCP服務(wù)器端應(yīng)用程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是網(wǎng)絡(luò)調(diào)試和串口調(diào)試集合UDP TCP客戶端和TCP服務(wù)器端應(yīng)用程序免費(fèi)下載。
    發(fā)表于 08-30 08:00 ?16次下載
    網(wǎng)絡(luò)調(diào)試和串口調(diào)試集合UDP TCP<b class='flag-5'>客戶端</b>和TCP<b class='flag-5'>服務(wù)器端</b>應(yīng)用程序免費(fèi)下載

    數(shù)據(jù)是怎么樣保證準(zhǔn)確的從客戶端發(fā)送服務(wù)器端

    你有想過嗎,計算機(jī)網(wǎng)絡(luò)當(dāng)中,數(shù)據(jù)是怎么樣保證準(zhǔn)確的從客戶端發(fā)送服務(wù)器端的?中間涉及到了哪些理論?
    的頭像 發(fā)表于 07-01 10:09 ?1946次閱讀

    拒絕服務(wù)攻擊的基本概念

    服務(wù)器端收到客戶端發(fā)送過來的SYN請求包后,知道客戶端想要建立連接,于是向客戶端發(fā)送一個SYN請
    的頭像 發(fā)表于 10-08 11:07 ?3286次閱讀