.netcore grpc的proto文件字段詳解

一、.proto文件字段概述

  1. grpc的接口傳輸參數都是根據.proto文件約定的字段格式進行傳輸的
  2. grpc提供了多種類型字段;主要包括標量值類型(基礎類型)、日期時間、可為null類型、字節、列表、字典、Any類型(任意類型)、Oneof等
  3. 字段嚴格規范,是一種強類型文件協議

二、案例介紹

  1. 標量值類型
  2. 日期時間
  3. 可為null類型
  4. 字節
  5. 列表
  6. 字典
  7. Any類型
  8. Oneof:一種語言特性,可以通過該特性進行對象切換處理;使用?oneof?指定可能返回 A對象或B對象?的響應消息

三、服務端定義

  1. 定義通用消息實體
  2. 根據不同的類型創建對應的案例實體
  3. 特殊的字段需要導入指定的包才能使用
  4. 定義引用字段的各個服務接口
  5. 內部實現邏輯,及打印展示相應的字段結果
// 1.提供公共的實體proto文件
// 2.服務引用對應的proto文件// 通用消息文件datamessages.proto
syntax = "proto3";option csharp_namespace = "GrpcProject";package grpc.serviceing;// 基礎類型實體
message BaseConfig{string name = 1;double position = 2;float distance= 3 ;int32 age = 4;int64 timeSpanId = 5;uint32 uAge = 6;uint64 uTimeSpanId = 7;sint32 sAge = 8;sint64 sTimeSpanId = 9;bool flag = 10;
}// 日期類型實體 需要導入 日期namespace
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";message DateConfig{int64 id = 1;google.protobuf.Timestamp dateTimestamp = 2;google.protobuf.Duration dateDuration = 3;
}// 字節類型
message ByteConfig{int64 id = 1;bytes positionBytes = 2;
}// 可為null類型 需要導入 null的namespace
import "google/protobuf/wrappers.proto";message NullConfig{int64 id = 1;google.protobuf.BoolValue nullBool = 2;google.protobuf.DoubleValue nullDoubule = 3;google.protobuf.FloatValue nullFloat = 4;google.protobuf.Int32Value nullInt = 5;google.protobuf.Int64Value nullLong = 6;google.protobuf.UInt32Value nullUInt = 7;google.protobuf.StringValue nullString = 8;google.protobuf.BytesValue nullBytes = 9;
}//  集合類型
message ListConfig{int64 id = 1;// 數組repeated string names = 2;repeated ListDetailConfig details = 3;// 字典map<int32,string> attributes = 4;map<int32,ListDetailConfig> dicDetail = 5;
}message ListDetailConfig{string name = 1;int32 height = 2;
}// 任意類型 需要導入對應的包
import "google/protobuf/any.proto";
message AnyConfig{int32 id = 1;google.protobuf.Any anyObject = 2;
}// Oneof類型  編譯器在生成消息類時處理 oneof 關鍵字。 使用 oneof 指定可能返回 A 或 B 或 C 的響應消息
message OneofConfig{oneof result{A oA = 1;B oB = 2;C oC = 3;}
}message A{int32 id = 1;
}message B{int32 id = 1;
}message C{int32 id =1;
}
// 接口服務定義protofield.proto文件syntax = "proto3";import "google/protobuf/empty.proto";
import "Protos/datamessages.proto";option csharp_namespace = "GrpcProject";package grpc.serviceing;service FieldRpc{// 基礎字段處理rpc BaseConfigService(BaseConfig) returns (google.protobuf.Empty);// 日期字段處理rpc DateConfigService(DateConfig) returns (google.protobuf.Empty);// 字節處理rpc ByteConfigService(ByteConfig) returns (google.protobuf.Empty);// null字段處理rpc NullConfigService(NullConfig) returns (google.protobuf.Empty);// 集合類型字段處理rpc ListConfigService(ListConfig) returns (google.protobuf.Empty);// 任意類型字段處理rpc AnyConfigService(AnyConfig) returns (google.protobuf.Empty);// Oneof類型字段處理rpc OneofConfigService(OneofConfig) returns (google.protobuf.Empty);
}
// 服務實現類/// <summary>/// 字段處理服務/// </summary>public class ProtoFieldService : FieldRpc.FieldRpcBase{// 基礎配置public override async Task<Empty> BaseConfigService(BaseConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------基礎配置--------------------------\r\n");// 打印字段信息var properties = request.GetType().GetProperties();foreach (var property in properties){var value = property.GetValue(request);await Console.Out.WriteLineAsync($"{property.Name}:{value}");}return new Empty();}// 日期配置public override async Task<Empty> DateConfigService(DateConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------日期配置--------------------------\r\n");// timspanvar duration = request.DateDuration.ToTimeSpan();await Console.Out.WriteLineAsync($"{nameof(duration)}:{duration.TotalSeconds}");// datetimevar time = request.DateTimestamp.ToDateTime();await Console.Out.WriteLineAsync($"{nameof(time)}:{time:yyyy-MM-dd HH:mm:ss}");return new Empty();}// 字節public override async Task<Empty> ByteConfigService(ByteConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------字節配置--------------------------\r\n");var bytes = request.PositionBytes.ToByteArray();var message = Encoding.UTF8.GetString(bytes, 0, bytes.Length);await Console.Out.WriteLineAsync($"{nameof(message)}:{message}");return new Empty();}// null配置public override async Task<Empty> NullConfigService(NullConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------null配置--------------------------\r\n");// 打印字段信息var properties = request.GetType().GetProperties();foreach (var property in properties){var value = property.GetValue(request);var printValue = value == null ? "返回null值" : value;await Console.Out.WriteLineAsync($"{property.Name}:{printValue}");}return new Empty();}// 集合public override async Task<Empty> ListConfigService(ListConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------集合配置--------------------------\r\n");var id = request.Id;await Console.Out.WriteLineAsync($"主鍵標識:{id}\r\n");// 轉換數組arrayawait Console.Out.WriteLineAsync($"打印names信息:");var names = request.Names.ToArray();foreach (var name in names){await Console.Out.WriteLineAsync(name);}// 轉換listawait Console.Out.WriteLineAsync($"\r\n打印detailList信息:");var detailList = request.Details.ToList();foreach (var item in detailList){await Console.Out.WriteLineAsync($"ListDetailConfig:{nameof(item.Name)}  {item.Name};{nameof(item.Height)}  {item.Height}。");}// 字典await Console.Out.WriteLineAsync($"\r\n打印一般字典信息:");var dicAttributes = request.Attributes.ToDictionary(t => t.Key, t => t.Value);foreach (var attr in dicAttributes){await Console.Out.WriteLineAsync($"key:{attr.Key};value:{attr.Value}。");}await Console.Out.WriteLineAsync($"\r\n打印對象字典信息:");foreach (var item in request.DicDetail){await Console.Out.WriteLineAsync($"key:{item.Key};value:{item.Value.Name} | {item.Value.Height}。");}return new Empty();}// Anypublic override async Task<Empty> AnyConfigService(AnyConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------Any配置--------------------------\r\n");var anyObject = request.AnyObject;// 檢查是否是A對象if (anyObject.Is(A.Descriptor)){var a = anyObject.Unpack<A>();if (a is not null){await Console.Out.WriteLineAsync($"A對象:{a.Id}");}}else if (anyObject.Is(B.Descriptor)){var b = anyObject.Unpack<B>();if (b is not null){await Console.Out.WriteLineAsync($"B對象:{b.Id}");}}else if (anyObject.Is(C.Descriptor)){var c = anyObject.Unpack<C>();if (c is not null){await Console.Out.WriteLineAsync($"C對象:{c.Id}");}}else{await Console.Out.WriteLineAsync("Any未解析到任何對象");}return new Empty();}// oneofpublic override async Task<Empty> OneofConfigService(OneofConfig request, ServerCallContext context){await Console.Out.WriteLineAsync("\r\n--------------------------Oneof配置--------------------------\r\n");// 檢測對應的對象是否有值switch (request.ResultCase){case OneofConfig.ResultOneofCase.None:await Console.Out.WriteLineAsync("未檢測到任何對象");break;case OneofConfig.ResultOneofCase.OA:await Console.Out.WriteLineAsync($"對象OA存在值:{request.OA.Id}");break;case OneofConfig.ResultOneofCase.OB:await Console.Out.WriteLineAsync($"對象OB存在值:{request.OB.Id}");break;case OneofConfig.ResultOneofCase.OC:await Console.Out.WriteLineAsync($"對象OC存在值:{request.OC.Id}");break;default:break;}return new Empty();}}

三、客戶端定義

  1. 引用proto文件,配置為客戶端類型
  2. 根據編譯生成的函數進行傳參調用
  3. 創建WPF測試客戶端
  4. 各個服務接口創建對應的按鈕進行調用
  5. 執行過程中,服務端控制臺會打印對應的消息

        // 基礎private async void BtnBaseconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(1);MessageBox();}// 日期private async void BtnDateconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(2);MessageBox();}// 字節private async void BtnByteconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(3);MessageBox();}// nullprivate async void BtnNullconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(4);MessageBox();}// listprivate async void BtnListconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(5);MessageBox();}// anyprivate async void BtnAnyconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(6);MessageBox();}// Oneofprivate async void BtnOneofconfig_Click(object sender, RoutedEventArgs e){await WpfFieldClient.Show(7);MessageBox();}

調用的類庫:

    public class WpfFieldClient{/// <summary>/// 根據參數選擇不同的方法執行/// </summary>/// <param name="k"></param>public static async Task Show(int k){var channel = GrpcChannel.ForAddress("https://localhost:7188");var client = new GrpcProject.FieldRpc.FieldRpcClient(channel);// 基礎BaseConfig config = new BaseConfig();config.Name = "張三";config.Position = 2.33D;config.Distance = 5.48F;config.Age = 10;config.TimeSpanId = 6538590027736100;config.SAge = 1921;config.STimeSpanId = 6538590027736130;config.Flag = true;// 日期DateConfig dateConfig = new DateConfig();dateConfig.Id = 179;dateConfig.DateDuration = Duration.FromTimeSpan(TimeSpan.FromSeconds(5));// 注意這里的時間是utc時間dateConfig.DateTimestamp = Timestamp.FromDateTime(DateTime.UtcNow);// 字節ByteConfig byteConfig = new ByteConfig();byteConfig.Id = 9854564654654;byteConfig.PositionBytes = ByteString.CopyFrom(Encoding.UTF8.GetBytes("莊這人的南的很"));// nullNullConfig nullConfig = new NullConfig();nullConfig.Id = 1854564654654;nullConfig.NullBool = true;nullConfig.NullFloat = null;nullConfig.NullUInt = null;nullConfig.NullInt = 15;nullConfig.NullLong = 112345451234787;// ListConfigListConfig listConfig = new ListConfig();var attributes = new Dictionary<int, string>{[1] = "one",[2] = "two",[3] = "three",[4] = "four",[5] = "five"};listConfig.Id = 123456456;listConfig.Attributes.Add(attributes);var dicDetail = new Dictionary<int, ListDetailConfig>{[1] = new ListDetailConfig { Height = 1, Name = "one" },[2] = new ListDetailConfig { Height = 2, Name = "two" },[3] = new ListDetailConfig { Height = 3, Name = "three" },[4] = new ListDetailConfig { Height = 4, Name = "four" },[5] = new ListDetailConfig { Height = 5, Name = "five" }};listConfig.DicDetail.Add(dicDetail);listConfig.Details.Add(new ListDetailConfig { Height = 8, Name = "Eight" });var detailConfigs = new List<ListDetailConfig>{new ListDetailConfig { Height=9,Name="nine"},new ListDetailConfig{ Height=10,Name="ten"}};listConfig.Details.Add(detailConfigs);// AnyAnyConfig anyConfig = new AnyConfig();anyConfig.Id = 42564134;anyConfig.AnyObject = Any.Pack(new B { Id = 15 });// OneofOneofConfig oneofConfig = new OneofConfig();oneofConfig.OA = new A { Id = 1 };//oneofConfig.OC = new C { Id = 2 };var emptyResult = k switch{1 => await client.BaseConfigServiceAsync(config),2 => await client.DateConfigServiceAsync(dateConfig),3 => await client.ByteConfigServiceAsync(byteConfig),4 => await client.NullConfigServiceAsync(nullConfig),5 => await client.ListConfigServiceAsync(listConfig),6 => await client.AnyConfigServiceAsync(anyConfig),7 => await client.OneofConfigServiceAsync(oneofConfig),_ => new Empty()};}}

五、執行結果

服務端:

?客戶端:

?六、源碼地址

鏈接:https://pan.baidu.com/s/150TKY2Kgln3l_uKAsztyzw?
提取碼:hkb9

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41775.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41775.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41775.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端筆試+面試分享

以下是個人線下面試遇到的真實的題&#xff0c;僅供參考和學習 1. css 選擇符有哪些&#xff1f;哪些屬性可以繼承&#xff1f;優先級算法加何計算&#xff1f; CSS選擇符有很多種&#xff0c;例如類型選擇器、類選擇器、ID選擇器、屬性選擇器、偽類選擇器、偽元素選擇器等。 …

【1day】復現海康威視綜合安防管理平臺artemis接口Spring boot heapdump內存泄露漏洞

目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現 一、漏洞描述 HIKVISION iSecure Center綜合安防管理平臺是一套“集成化”、“智能化”的平臺,通過接入視頻監控、一卡通

Algorithem Review 5.2 圖論

網絡流 設源點為 s s s&#xff0c;匯點為 t t t&#xff0c;每條邊 e e e 的流量上限為 c ( e ) c(e) c(e)&#xff0c;流量為 f ( e ) f(e) f(e)。割 指對于某一頂點集合 P ? V P \subset V P?V&#xff0c;從 P P P 出發指向 P P P 外部的那些原圖中的邊的集合&a…

回歸預測 | MATLAB實現基于SSA-KELM-Adaboost麻雀算法優化核極限學習機結合AdaBoost多輸入單輸出回歸預測

回歸預測 | MATLAB實現基于SSA-KELM-Adaboost麻雀算法優化核極限學習機結合AdaBoost多輸入單輸出回歸預測 目錄 回歸預測 | MATLAB實現基于SSA-KELM-Adaboost麻雀算法優化核極限學習機結合AdaBoost多輸入單輸出回歸預測預測效果基本介紹模型描述程序設計參考資料 預測效果 基本…

SSH遠程連接MacOS catalina并進行終端顏色配置

一、開關SSH服務 在虛擬機上安裝了MacOS catalina&#xff0c;想要使用SSH遠程進行連接&#xff0c;但是使用“系統偏好設置”/“共享”/“遠程登錄”開關進行打開&#xff0c;卻一直是正在啟動“遠程登錄”&#xff1a; 難道是catalina有BUG&#xff1f;不過還是有方法的&…

第07天 Static關鍵字作用及用法

?作者簡介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;熱愛Java后端開發者&#xff0c;一個想要與大家共同進步的男人&#x1f609;&#x1f609; &#x1f34e;個人主頁&#xff1a;Leo的博客 &#x1f49e;當前專欄&#xff1a;每天一個知識點 ?特色專欄&#xff1a…

【前端|Javascript第5篇】全網最詳細的JS的內置對象文章!

前言 在當今數字時代&#xff0c;前端技術正日益成為塑造用戶體驗的關鍵。我們在開發中需要用到很多js的內置對象的一些屬性來幫助我們更快速的進行開發。或許你是剛踏入前端領域的小白&#xff0c;或者是希望深入了解內置對象的開發者&#xff0c;不論你的經驗如何&#xff0c…

使用Dockerfile制作RocketMq的Docker鏡像(任意版本)

使用dockerfile制作任意版本的docker鏡像 1、Dockerfile 創建文件rocketmq #FROM openjdk:8 FROM java8:1.0 #上面的基礎鏡像可以自己 docker pull LABEL "作者"=aaaaaENV ROCKETMQ_VERSION 5.1.3 # ENV LANG en_US.UTF-8ENV ROCKETMQ_HOME="/home/rocketm…

MATLAB中的代數環概念

在 Simulink 模型中&#xff0c;當存在信號環并且信號環中只存在直接饋通模塊時&#xff0c;將出現代數環。直接饋通表示 Simulink 需要模塊輸入信號的值來計算當前時間步的輸出。這種信號循環會在同一時間步中產生模塊輸出和輸入的循環依存關系。這會導致一個需要在每個時間步…

【【verilog典型電路設計之流水線結構】】

verilog典型電路設計之流水線結構 下圖是一個4位的乘法器結構&#xff0c;用verilog HDL 設計一個兩級流水線加法器樹4位乘法器 對于流水線結構 其實需要做的是在每級之間增加一個暫存的數據用來存儲 我們得到的東西 我們一般來說會通過在每一級之間插入D觸發器來保證數據的聯…

Oracle 數據庫備份

1、使用管理員賬號創建對應的directory目錄 登錄數據庫 sqlplus / as sysdba 創建directory create or replace directory dumpdir as F:\container; 2、給用戶賦予使用該目錄的權限 grant read,write on directory dumpdir to Scott; 查看創建的目錄位置 select * fro…

OpenCV-Python中的圖像處理-圖像特征

OpenCV-Python中的圖像處理-圖像特征 圖像特征Harris角點檢測亞像素級精度的角點檢測Shi-Tomasi角點檢測SIFT(Scale-Invariant Feature Transfrom)SURF(Speeded-Up Robust Features)FAST算法BRIEF(Binary Robust Independent Elementary Features)算法ORB (Oriented FAST and R…

JavaScript判空設默認值的幾種寫法

前端面試題庫 &#xff08;面試必備&#xff09; 推薦&#xff1a;★★★★★ 地址&#xff1a;前端面試題庫 實踐中需要給某個變量賦值時&#xff0c;若數據來源不可控&#xff0c;通常會給它設置一個默認值&#xff08;就像空對象模式一樣&#xff09;。JavaScri…

python編程中有哪些方便的調試方法

大家好&#xff0c;給大家分享一下一個有趣的事情&#xff0c;很多人還不知道這一點。下面詳細解釋一下。現在讓我們來看看&#xff01; 對于每個程序開發者來說&#xff0c;調試幾乎是必備技能。常用Pycharm編輯器里的方法有Print大法、log大法&#xff0c;但缺少類似Matlab的…

敏感掛載binfmt_misc容器逃逸復現和分析

前言 對于/proc下有很多掛載會導致容器逃逸&#xff0c;其中binfmt_misc就是一種可以利用的逃逸掛載 binfmt_mics 實驗 touch test_fmt_intp echo aaa > test_fmt echo #!/bin/sh > test_fmt_intp echo >> test_fmt_intp chmod x test_fmt_intp echo :test_fmt…

怎么開通Tik Tok海外娛樂公會呢?

TikTok作為全球知名的社交媒體平臺&#xff0c;吸引了數億用戶的關注和參與。許多公司和個人渴望通過開通TikTok直播公會進入這一領域&#xff0c;以展示自己的創造力和吸引更多粉絲。然而&#xff0c;成為TikTok直播公會并非易事&#xff0c;需要滿足一定的門檻和申請找cmxyci…

【日常積累】Linux之init系統學習

init系統簡介: Linux 操作系統的啟動首先從 BIOS 開始&#xff0c;接下來進入 boot loader&#xff0c;由 bootloader 載入內核&#xff0c;進行內核初始化。內核初始化的最后一步就是啟動 pid 為 1 的 init 進程&#xff0c;這個進程是系統的第一個進程&#xff0c;它負責產生…

銀河麒麟服務器v10 sp1 .Net6.0 上傳文件錯誤

上一篇&#xff1a;銀河麒麟服務器v10 sp1 部署.Net6.0 http https_csdn_aspnet的博客-CSDN博客 .NET 6之前&#xff0c;在Linux服務器上安裝 libgdiplus 即可解決&#xff0c;libgdiplus是System.Drawing.Common原生端跨平臺實現的主要提供者&#xff0c;是開源mono項目。地址…

封裝form表單

目錄 1. 源碼 2. 其他頁面引用 ps&#xff1a;請看完看明白再復用 1. 源碼 <template><div style"width: 100%; height: 100%" class"form-condition"><!-- 普通表單 --><el-card shadow"hover" class"cardheigh…

AQS的原理及應用

文章目錄 AQS引言AQS 的原理AQS 應用舉例1:Semaphore舉例2:ReentrantLockAQS 的案例分析問題背景解決方案AQS 引言 在我們的日常生活和工作中,往往需要協調各個線程之間的執行順序和資源使用,而AQS(AbstractQueuedSynchronizer)即為 Java 并發包中提供的一種解決辦法。…