万州房产网站建设/seo优化教程培训
一、.proto文件字段概述
- grpc的接口传输参数都是根据.proto文件约定的字段格式进行传输的
- grpc提供了多种类型字段;主要包括标量值类型(基础类型)、日期时间、可为null类型、字节、列表、字典、Any类型(任意类型)、Oneof等
- 字段严格规范,是一种强类型文件协议
二、案例介绍
- 标量值类型
- 日期时间
- 可为null类型
- 字节
- 列表
- 字典
- Any类型
- Oneof:一种语言特性,可以通过该特性进行对象切换处理;使用
oneof
指定可能返回 A对象或B对象 的响应消息
三、服务端定义
- 定义通用消息实体
- 根据不同的类型创建对应的案例实体
- 特殊的字段需要导入指定的包才能使用
- 定义引用字段的各个服务接口
- 内部实现逻辑,及打印展示相应的字段结果
// 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();}}
三、客户端定义
- 引用proto文件,配置为客户端类型
- 根据编译生成的函数进行传参调用
- 创建WPF测试客户端
- 各个服务接口创建对应的按钮进行调用
- 执行过程中,服务端控制台会打印对应的消息
// 基础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
下一篇https://blog.csdn.net/qq_31975127/article/details/132345428
相关文章:

.netcore grpc的proto文件字段详解
一、.proto文件字段概述 grpc的接口传输参数都是根据.proto文件约定的字段格式进行传输的grpc提供了多种类型字段;主要包括标量值类型(基础类型)、日期时间、可为null类型、字节、列表、字典、Any类型(任意类型)、One…...

带你了解建堆的时间复杂度
目录 用向上调整建堆的时间复杂度 1.向上调整建堆的时间复杂度O(N*logN) 2.数学论证 3.相关代码 用向下调整建堆的时间复杂度 1.建堆的时间复杂度为O(N) 2.数学论证 3.相关代码 完结撒花✿✿ヽ(▽)ノ✿✿ 博主建议:面试的时候可能会被面试官问到建堆时间复杂度的证明过…...
人工智能原理(6)
目录 一、机器学习概述 1、学习和机器学习 2、学习系统 3、机器学习发展简史 4、机器学习分类 二、归纳学习 1、归纳学习的基本概念 2、变型空间学习 3、归纳偏置 三、决策树 1、决策树组成 2、决策树的构造算法CLS 3、ID3 4、决策树的偏置 四、基于实例的学习…...

单片机模块化编程文件创建流程
一、在工程文件夹下创建一个新的文件夹,命名为“ModulesCodesFiles”,译为“模块化代码文件”,用于存放所有模块化代码文件。 二、在“ModulesCodesFiles”文件夹下为每个模块创建一个新的文件夹,命名为模块的名称,例…...

docker image
docker image 1. 由来 docker image是Docker容器管理工具中的一个命令,用于管理和操作Docker镜像。 2. 常见五种示例命令和说明 以下是docker image的常见示例命令及其说明: 示例一:列出所有镜像 docker image ls描述:使用d…...

力扣75——单调栈
总结leetcode75中的单调栈算法题解题思路。 上一篇:力扣75——区间集合 力扣75——单调栈 1 每日温度2 股票价格跨度1 - 2 解题总结 1 每日温度 题目: 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer &…...

Webpack和Parcel详解
构建工具和打包器是在开发过程中帮助组织、优化和打包项目的工具。它们可以处理依赖管理、资源优化、代码转换等任务,从而使开发流程更高效。以下是关于构建工具和打包器的一些指导: **Webpack:** Webpack 是一个功能强大的模块打包器&#…...

linux系统服务学习(六)FTP服务学习
文章目录 FTP、NFS、SAMBA系统服务一、FTP服务概述1、FTP服务介绍2、FTP服务的客户端工具3、FTP的两种运行模式(了解)☆ 主动模式☆ 被动模式 4、搭建FTP服务(重要)5、FTP的配置文件详解(重要) 二、FTP任务…...

7.原 型
7.1原型 【例如】 另外- this指向: 构造函数和原型对象中的this都指向实例化的对象 7.2 constructor属性 每个原型对象里面都有个constructor属性( constructor构造函数) 作用:该属性指向该原型对象的构造函数 使用场景: 如果有多个对象的方法&#…...

【图像分类】理论篇(2)经典卷积神经网络 Lenet~Resenet
目录 1、卷积运算 2、经典卷积神经网络 2.1 Lenet 网络构架 代码实现 2.2 Alexnet 网络构架 代码实现 2.3 VGG VGG16网络构架 代码实现 2.4 ResNet ResNet50网络构架 代码实现 1、卷积运算 在二维卷积运算中,卷积窗口从输入张量的左上角开始ÿ…...

C++系列-内存模型
内存模型 内存模型四个区代码区全局区栈区堆区内存开辟和释放在堆区开辟数组 内存模型四个区 不同区域存放的数据生命周期是不同的,更为灵活。 代码区:存放函数体的二进制代码,操作系统管理。全局区:存放全局变量,常…...

[管理与领导-30]:IT基层管理者 - 人的管理 - 向上管理,管理好你的上司,职业发展事半功倍。什么样的上司不值得跟随?
目录 前言: 一、什么是向上管理 二、为什么要向上管理 三、如何进行向上管理 四、向上管理的注意事项 五、向上管理的忌讳 六、向上管理常犯的错 七、如何帮助上司解决他关心的问题 7.1 如何帮助上司解决他关心的问题 7.2 如何帮助上司降低压力 八、什么…...

Java进阶篇--迭代器模式
目录 同步迭代器(Synchronous Iterator): Iterator 接口 常用方法: 注意: 扩展小知识: 异步迭代器(Asynchronous Iterator): 常用的方法 注意: 总结:…...

【CAM】CAM(Class Activation Mapping)——可视化CNN的特征定位
文章目录 一、CAM(Class Activation Mapping)二、CAM技术实现2.1 网络修改2.2 微调2.2 特征提取 三、总结Reference 完整代码见Github :https://github.com/capsule2077/CAM-Visualization ,如果有用可以点个Star,谢谢! 一、CAM(C…...

Maven教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 Maven 是一款基于 Java 平台的项目管理和整合工具,它将项目的开发和管理过程抽象成一个项目对象模型(POM)。开发人员只需要做一些简单的配置,Maven 就可以自动完成项目的编译、测试、打包、发布以及部署等工作。Maven 是…...

Gof23设计模式之模板方法模式
1.定义 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 2.结构 模板方法(Template Method)模式包含以下主要角色: 抽象类࿰…...

springBoot 配置文件 spring.resources.add-mappings 参数的作用
在Spring Boot应用中,spring.resources.add-mappings参数用于控制是否将特定路径的资源文件添加到URL路径映射中。 默认情况下,该参数的值为true,即会自动将静态资源(例如CSS、JavaScript、图片等)的URL路径添加到Spr…...

《Java极简设计模式》第03章:工厂方法模式(FactoryMethod)
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 源码地址:https://github.com/binghe001/java-simple-design-patterns/tree/master/j…...

C++11并发与多线程笔记(11) std::atomic续谈、std::async深入谈
C11并发与多线程笔记(11) std::atomic续谈、std::async深入谈 1、std::atomic续谈2、std::async深入理解2.1 std::async参数详述2.2 std::async和std::thread()区别:2.3 async不确定性问题的解决 1、std::atomic续谈 #include <iostream&…...

React快速入门
最近需要学到react,这里进行一个快速的入门,参考react官网 1.创建和嵌套组件 react的组件封装是个思想,我这里快速演示代码,自己本身也不太熟悉。 代码的路径是src底下的App.js function MyButton() {return (<button>I…...

windows权限维持—SSPHOOKDSRMSIDhistorySkeletonKey
windows权限维持—SSP&HOOK&DSRM&SIDhistory&SkeletonKey 1. 权限维持介绍1.1. 其他 2. 基于验证DLL加载—SPP2.1. 操作演示—临时生效2.1.1. 执行命令2.1.2. 切换用户 2.2. 操作演示—永久生效2.2.1. 上传文件2.2.2. 执行命令2.2.3. 重启生效 2.3. 总结 3. 基…...

CSS 两栏布局和三栏布局的实现
文章目录 一、两栏布局的实现1. floatmargin2. flaotBFC3. 定位margin4. flex 布局5. grid布局 二、三栏布局的实现1. float margin2. float BFC3. 定位 margin(或者定位BFC)4. flex布局5. 圣杯布局6. 双飞翼布局 一、两栏布局的实现 两栏布局其实就是左侧定宽,…...

消息中间件相关面试题
👏作者简介:大家好,我是爱发博客的嗯哼,爱好Java的小菜鸟 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝社区论坛:希望大家能加入社区共同进步…...

成集云 | 电子签署集成腾讯云企业网盘 | 解决方案
源系统成集云目标系统 方案介绍 电子签署是通过电子方式完成合同、文件或其他文件的签署过程。相较于传统的纸质签署,电子签署具有更高效、更便捷、更安全的优势。 在电子签署过程中,使用电子签名技术来验证签署者的身份并确保签署文件的完整性。电子…...

提升大数据技能,不再颓废!这6家学习网站是你的利器!
随着国家数字化转型,大数据领域对人才的需求越来越多。大数据主要研究计算机科学和大数据处理技术等相关的知识和技能,从大数据应用的三个主要层面(即数据管理、系统开发、海量数据分析与挖掘)出发,对实际问题进行分析…...

uniapp开发小程序-有分类和列表时,进入页面默认选中第一个分类
一、效果: 如下图所示,进入该页面后,默认选中第一个分类,以及第一个分类下的列表数据。 二、代码实现: 关键代码: 进入页面时,默认调用分类的接口,在分类接口里做判断ÿ…...

小程序-uni-app:hbuildx uni-app 安装 uni-icons 及使用
一、官方文档找到uni-icons uni-app官网 二、下载插件 三、点击“打开HBuildX” 四、选择要安装的项目 五、勾选要安装的插件 六、安装后,项目插件目录 根目录uni_modules目录下增加uni-icons、uni-scss 七、引入组件,使用组件 <uni-icons type&qu…...

PHP中in_array()函数用法详解
in_array() 函数是PHP中常用的数组函数之一,用于搜索数组中是否存在指定的值。 语法 bool in_array ( mixed $needle , array $haystack [, bool $strict FALSE ] ) 参数描述needle必需。规定要在数组搜索的值。haystack必需。规定要搜索的数组。strict可选。如…...

热电联产在综合能源系统中的选址定容研究(matlab代码)
目录 1 主要内容 目标函数 程序模型 2 部分代码 3 程序结果 1 主要内容 该程序参考《热电联产在区域综合能源系统中的定容选址研究》,主要针对电热综合能源系统进行优化,确定热电联产机组的位置和容量,程序以33节点电网和17节点热网为例…...

校园网安全风险分析
⒈物理层的安全风险分析 网络的物理安全风险主要指网络周边环境和物理特性引起的网络设备和线路的不可用 , 而 造成网络系统的不可用。我们在考虑校园网络安全时,首先要考虑物理安全风险,它是整个 网络系统安全的前提。物理安全风险有:设备…...