在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

使用Protobuf實(shí)現(xiàn)客戶(hù)端與服務(wù)器之間的通信協(xié)議層

我快閉嘴 ? 來(lái)源:coding到燈火闌珊 ? 作者:李明 ? 2022-09-14 09:26 ? 次閱讀
本系列是關(guān)于用Rust構(gòu)建一個(gè)KV Server的系列文章,內(nèi)容包括用tokio做底層異步網(wǎng)絡(luò)通訊、使用toml文件做配置、protobuf做傳輸協(xié)議、內(nèi)存/RockDB做數(shù)據(jù)存儲(chǔ)、事件通知、優(yōu)雅關(guān)機(jī)、并發(fā)連接限制及測(cè)量監(jiān)控等。
在上一篇文章中,我們用tokio實(shí)現(xiàn)了客戶(hù)端和服務(wù)器的基本框架并設(shè)置了toml格式的配置文件。在這一篇文章中,我們參考Redis的命令:GET、SET、PUBLISH和SUBSCRIBE,使用Protobuf來(lái)實(shí)現(xiàn)客戶(hù)端與服務(wù)器之間的通信協(xié)議層。為了處理Protobuf,我們加入了post庫(kù)。同時(shí)加入了tracing庫(kù)用于日志處理。Cargo.toml如下:
[dependencies]anyhow = "1"tokio = { version = "1.19", features = ["full"] }serde = { version = "1", features = ["derive"] }toml = "0.5"tracing = "0.1"tracing-subscriber = "0.3"bytes = "1"prost = "0.11"
[build-dependencies]prost-build = "0.11"
Protobuf在項(xiàng)目根目錄下新建cmd.proto,加入如下代碼:
 1syntax="proto3";
 2
 3packagecmd;
 4
 5//命令請(qǐng)求
 6messageCmdRequest{
 7oneofreq_data{
 8Getget=1;
 9Setset=2;
10Publishpublish=3;
11Subscribesubscribe=4;
12Unsubscribeunsubscribe=5;
13}
14}
15
16//服務(wù)器的響應(yīng)
17messageCmdResponse{
18uint32status=1;
19stringmessage=2;
20bytesvalue=3;
21}
22
23//請(qǐng)求值命令
24messageGet{
25stringkey=1;
26}
27
28//存儲(chǔ)值命令
29messageSet{
30stringkey=1;
31bytesvalue=2;
32uint32expire=3;
33}
34
35//向Topic發(fā)布值命令
36messagePublish{
37stringtopic=1;
38bytesvalue=2;
39}
40
41//訂閱Topic命令
42messageSubscribe{
43stringtopic=1;
44}
45
46//取消訂閱命令
47messageUnsubscribe{
48stringtopic=1;
49uint32id=2;
50}
在src目錄下創(chuàng)建pb目錄,在根目錄下創(chuàng)建build.rs文件,加入如下代碼:
1fnmain(){
2letmutconf=prost_build::new();
3conf.bytes(&["."]);
4conf.type_attribute(".","#[derive(PartialOrd)]");
5conf.out_dir("src/pb")
6.compile_protos(&["cmd.proto"],&["."])
7.unwrap();
8}
在src/pb目錄下已經(jīng)自動(dòng)生成了cmd.rs文件。在src/pb目錄下創(chuàng)建mod.rs文件,加入如下代碼:
 1usebytes::Bytes;
 2
 3usecrate::{cmd_request::ReqData,CmdRequest,Get,Publish,Set,Subscribe,Unsubscribe};
 4
 5pubmodcmd;
 6
 7implCmdRequest{
 8//GET命令
 9pubfnget(key:implInto)->Self{
10Self{
11req_data:Some(ReqData::Get(Get{key:key.into()})),
12}
13}
14
15//SET命令
16pubfnset(key:implInto,value:Bytes,expire:u32)->Self{
17Self{
18req_data:Some(ReqData::Set(Set{
19key:key.into(),
20value,
21expire,
22})),
23}
24}
25
26//PUBLISH命令
27pubfnpublish(topic:implInto,value:Bytes)->Self{
28Self{
29req_data:Some(ReqData::Publish(Publish{
30topic:topic.into(),
31value,
32})),
33}
34}
35
36//訂閱命令
37pubfnsubscribe(topic:implInto)->Self{
38Self{
39req_data:Some(ReqData::Subscribe(Subscribe{
40topic:topic.into(),
41})),
42}
43}
44
45//解除訂閱命令
46pubfnunsubscribe(topic:implInto,id:u32)->Self{
47Self{
48req_data:Some(ReqData::Unsubscribe(Unsubscribe{
49topic:topic.into(),
50id,
51})),
52}
53}
54}
55
56implCmdResponse{
57pubfnnew(status:u32,message:String,value:Bytes)->Self{
58Self{
59status,
60message,
61value,
62}
63}
64}
在 src/lib.rs 中,引入pb模塊:
1modpb;
2pubusepb::*;
客戶(hù)端 & 服務(wù)器我們使用tokio-util庫(kù)的Frame里的LengthDelimitedCodec(根據(jù)長(zhǎng)度進(jìn)行編解碼)對(duì)protobuf協(xié)議進(jìn)行封包解包。在Cargo.toml里加入tokio-util依賴(lài):
[dependencies]......futures = "0.3"tokio-util = {version = "0.7", features = ["codec"]}......
修改src/bin/kv_server.rs代碼:
 1#[tokio::main]
 2asyncfnmain()->Result<(),Box>{
 3tracing_subscriber::init();
 4
 5......
 6
 7loop{
 8......
 9
10tokio::spawn(asyncmove{
11//使用Frame的LengthDelimitedCodec進(jìn)行編解碼操作
12letmutstream=Framed::new(stream,LengthDelimitedCodec::new());
13whileletSome(Ok(mutbuf))=stream.next().await{
14//對(duì)客戶(hù)端發(fā)來(lái)的protobuf請(qǐng)求命令進(jìn)行拆包
15letcmd_req=CmdRequest::decode(&buf[..]).unwrap();
16info!("Receiveacommand:{:?}",cmd_req);
17
18buf.clear();
19
20//對(duì)protobuf的請(qǐng)求響應(yīng)進(jìn)行封包,然后發(fā)送給客戶(hù)端。
21letcmd_res=CmdResponse::new(200,"success".to_string(),Bytes::default());
22cmd_res.encode(&mutbuf).unwrap();
23stream.send(buf.freeze()).await.unwrap();
24}
25info!("Client{:?}disconnected",addr);
26});
27}
28}
修改src/bin/kv_client.rs代碼:
 1#[tokio::main]
 2asyncfnmain()->Result<(),Box>{
 3tracing_subscriber::init();
 4
 5......
 6
 7//使用Frame的LengthDelimitedCodec進(jìn)行編解碼操作
 8letmutstream=Framed::new(stream,LengthDelimitedCodec::new());
 9letmutbuf=BytesMut::new();
10
11//創(chuàng)建GET命令
12letcmd_get=CmdRequest::get("mykey");
13cmd_get.encode(&mutbuf).unwrap();
14
15//發(fā)送GET命令
16stream.send(buf.freeze()).await.unwrap();
17info!("Send info successed!");
18
19//接收服務(wù)器返回的響應(yīng)
20whileletSome(Ok(buf))=stream.next().await{
21letcmd_res=CmdResponse::decode(&buf[..]).unwrap();
22info!("Receivearesponse:{:?}",cmd_res);
23}
24
25Ok(())
26}
我們打開(kāi)二個(gè)終端,分別輸入以下命令:
RUST_LOG=info cargo run --bin kv_serverRUST_LOG=info cargo run --bin kv_client
服務(wù)器執(zhí)行結(jié)果:
INFO kv_server: Listening on 127.0.0.1:19999 ......INFO kv_server: Client: 127.0.0.1:50655 connectedINFO kv_server: Receive a command: CmdRequest { req_data: Some(Get(Get { key: "mykey" })) }
客戶(hù)端執(zhí)行結(jié)果:
INFO kv_client: Send info successedINFO kv_client: Receive a response: CmdResponse { status: 200, message: "success", value: b"" }

服務(wù)器和客戶(hù)端都正常處理了收到的請(qǐng)求和響應(yīng)。 下一篇文章我們將在服務(wù)器端使用內(nèi)存來(lái)存儲(chǔ)客戶(hù)端發(fā)送過(guò)來(lái)的數(shù)據(jù)。 完整代碼:https://github.com/Justin02180218/kv_server_rust


審核編輯:湯梓紅


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

    關(guān)注

    28

    文章

    1008

    瀏覽量

    40998
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    13

    文章

    9727

    瀏覽量

    87431
  • 客戶(hù)端
    +關(guān)注

    關(guān)注

    1

    文章

    298

    瀏覽量

    17016

原文標(biāo)題:用Rust實(shí)現(xiàn)KV Server-2 協(xié)議層

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    一個(gè)服務(wù)器,多個(gè)客戶(hù)端,怎么向指定的客戶(hù)端發(fā)數(shù)據(jù)

    我用labview做服務(wù)器,單片機(jī)做客戶(hù)端客戶(hù)端幾百個(gè),怎么區(qū)分客戶(hù)端,給指定的客戶(hù)發(fā)發(fā)數(shù)據(jù)
    發(fā)表于 06-01 09:26

    如何實(shí)現(xiàn)服務(wù)器對(duì)指定客戶(hù)端的監(jiān)聽(tīng)?

    我現(xiàn)在能做出的是單服務(wù)器接收單客戶(hù)端的采集信息,想要實(shí)現(xiàn)RT所述,有沒(méi)有大佬指點(diǎn)一二!!!(最好是有源碼)
    發(fā)表于 05-29 16:17

    labview-TCP多客戶(hù)端服務(wù)器

    labview-TCP多客戶(hù)端服務(wù)器一個(gè)服務(wù)器上位機(jī),多個(gè)下位機(jī)客戶(hù)端
    發(fā)表于 03-26 16:58

    怎么使用Paho來(lái)實(shí)現(xiàn)和MQTT服務(wù)器的基本通信?

    MQTT協(xié)議的全稱(chēng)叫“消息隊(duì)列遙測(cè)傳輸”協(xié)議。它是一個(gè)輕量級(jí)的通信協(xié)議。旨在為低帶寬、高延時(shí)、不穩(wěn)定網(wǎng)絡(luò)中的物聯(lián)網(wǎng)設(shè)備提供消息傳輸服務(wù)。它運(yùn)行在TCP/IP
    發(fā)表于 09-11 11:52

    BTC設(shè)備服務(wù)器的系統(tǒng)搭建

    ?:Node.js通信協(xié)議:HTTP、Socket3. Node.js 實(shí)現(xiàn) Socket 通信________________________________________Socket 主要作?是
    發(fā)表于 09-24 09:05

    4412開(kāi)發(fā)板Qt網(wǎng)絡(luò)編程-TCP實(shí)現(xiàn)服務(wù)器客戶(hù)端

    Protocol)是一種面向連接的,可靠的,基于字節(jié)流的傳輸通信協(xié)議,傳輸數(shù)據(jù)穩(wěn)定可靠。在 help 索引中搜索到如圖 兩個(gè)重要類(lèi):服務(wù)器編程中兩個(gè)類(lèi)都會(huì)用到,客戶(hù)端編程中只會(huì)用到
    發(fā)表于 04-28 15:33

    如何實(shí)現(xiàn)服務(wù)器客戶(hù)端數(shù)據(jù)交互?

    如何實(shí)現(xiàn)服務(wù)器客戶(hù)端數(shù)據(jù)交互?
    發(fā)表于 10-26 07:22

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

    我是這個(gè)小組的新手,我剛剛寫(xiě)信,如果有人能幫助我,我需要一個(gè)指南甚至一本書(shū)來(lái)學(xué)習(xí)如何使用 esp8266 在服務(wù)器客戶(hù)端之間發(fā)送數(shù)據(jù)(例如:我有2 esp8266 一個(gè)我想將它用作服務(wù)器
    發(fā)表于 04-27 07:05

    當(dāng)WiFi信號(hào)變低時(shí),服務(wù)器客戶(hù)端之間的TCP通信丟失,如何使客戶(hù)端重新連接?

    大家好, 當(dāng) WiFi 信號(hào)變低時(shí),服務(wù)器客戶(hù)端之間的 TCP 通信丟失,比如超過(guò) -80dBm。一旦客戶(hù)端斷開(kāi)連接,它就無(wú)法重新連接并正
    發(fā)表于 05-15 07:31

    服務(wù)器客戶(hù)端之間的TCP通信丟失怎么處理?

    嗨, 當(dāng) WiFi 信號(hào)變低時(shí),比如超過(guò) -80dBm,我面臨服務(wù)器客戶(hù)端之間的 TCP 通信丟失。一旦客戶(hù)端斷開(kāi)連接,它就無(wú)法重新連接并
    發(fā)表于 05-16 08:19

    TCP通信服務(wù)器端客戶(hù)端同機(jī)互傳的簡(jiǎn)單示例程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是TCP通信服務(wù)器端客戶(hù)端同機(jī)互傳的簡(jiǎn)單示例程序免費(fèi)下載初學(xué)者學(xué)習(xí)。本例子是本計(jì)算機(jī)labview程序之間通信,如果要想
    發(fā)表于 10-25 08:00 ?9次下載
    TCP<b class='flag-5'>通信服務(wù)器端</b>和<b class='flag-5'>客戶(hù)端</b>同機(jī)互傳的簡(jiǎn)單示例程序免費(fèi)下載

    Linux下TCP網(wǎng)絡(luò)編程-創(chuàng)建服務(wù)器客戶(hù)端

    這篇文章介紹在Linux下的socket編程,完成TCP服務(wù)器客戶(hù)端的創(chuàng)建,實(shí)現(xiàn)數(shù)據(jù)通信。
    的頭像 發(fā)表于 08-14 09:26 ?2767次閱讀
    Linux下TCP網(wǎng)絡(luò)編程-創(chuàng)建<b class='flag-5'>服務(wù)器</b>與<b class='flag-5'>客戶(hù)端</b>

    MQTT中服務(wù)端客戶(hù)端

    MQTT 是一種基于客戶(hù)端-服務(wù)端架構(gòu)(C/S)的消息傳輸協(xié)議,所以在 MQTT 協(xié)議通信中,有兩個(gè)最為重要的角色,它們便是
    的頭像 發(fā)表于 07-30 14:55 ?3128次閱讀

    服務(wù)端如何控制客戶(hù)端之間的信息通訊

    服務(wù)端如何通過(guò)“主題”來(lái)控制客戶(hù)端之間的信息通訊,看下圖實(shí)例: 在以上圖示中一共有三個(gè) MQTT 客戶(hù)端,它們分別是開(kāi)發(fā)板、手機(jī)和電腦。MQTT
    的頭像 發(fā)表于 07-30 15:10 ?1084次閱讀
    <b class='flag-5'>服務(wù)端</b>如何控制<b class='flag-5'>客戶(hù)端</b><b class='flag-5'>之間</b>的信息通訊

    服務(wù)器Server和客戶(hù)端Client的區(qū)別

    例如在使用TCP通訊建立連接時(shí)采用客戶(hù)端服務(wù)器模式,這種模式又常常被稱(chēng)為主從式架構(gòu),簡(jiǎn)稱(chēng)為C/S結(jié)構(gòu),屬于一種網(wǎng)絡(luò)通訊架構(gòu),將通訊的雙方以客戶(hù)端(Client )與服務(wù)器 (Serve
    的頭像 發(fā)表于 09-06 16:13 ?1869次閱讀
    <b class='flag-5'>服務(wù)器</b>Server和<b class='flag-5'>客戶(hù)端</b>Client的區(qū)別
    主站蜘蛛池模板: 亚洲黄色激情网 | 欧美色综合高清视频在线 | www.免费| 优优优色| 黄色一级大片视频 | 思思久久好好热精品国产 | 美女扒开尿口给男人爽免费视频 | 手机看片国产免费 | 国产三及 | 亚洲伊人tv综合网色 | 精品三级三级三级三级三级 | 久久青青成人亚洲精品 | 性色爽爱性色爽爱网站 | 四虎影院在线免费观看视频 | 精品欧美一区二区三区在线观看 | 永久免费看www色视频 | 1024在线观看你懂的 | 午夜性爽视频男人的天堂在线 | 最新色视频 | 日本不卡一区二区三区在线观看 | 色香视频首页 | 久久亚洲欧美成人精品 | 性欧美欧美之巨大69 | 青青青青久久精品国产h | 女人夜夜春 | 亚洲综合亚洲综合网成人 | 欧美zoozzooz在线观看 | 国内精品久久影视免费 | 天天爱天天做色综合 | 国产天天色 | 成人午夜啪啪免费网站 | 青草视频久久 | 99久久99久久免费精品蜜桃 | 一区免费 | 丁香六月五月婷婷 | 98pao强力打造高清免费 | 国产精品免费观看网站 | 亚洲精品第一 | 男女爱爱福利 | 亚洲成人在线免费观看 | 男啪女色黄无遮挡免费视频 |