入门干货之Grpc的.Net 封装-MagicOnion

0x01、Grpc

 

  1、介绍

 Google主导开发的RPC框架,使用HTTP/2协议并用ProtoBuf作为序列化工具,支持多种语言。在.NET Core “大更新” 之前,也就是目前来说还算是个很不错的选择。

  

  2、吐槽

      a、有很多性能比较的文章拿Grpc开涮.

      b、搭建困难,恶心,复杂,反胃,有点吃不消,吃吗丁啉不一定好使,砸键盘也解决不了问题。

  

  3、搭建流程

      a、引用

        

        

        都能搜索到,搜索不到就打全。

 

      b、编写跨语言服务文件(.proto),内容如下

syntax = "proto3";

package gRPCDemo;

service gRPC {

  rpc SayHello (HelloRequest) returns (HelloReply) {}

}


message HelloRequest {

  string name = 1;

}


message HelloReply {

  string message = 1;

}

      c、这时开始用到了tools, 敲命令:

        首先你的路径能识别下面两个exe,如果不能,就搜索这两个exe,我当时就没找到,用everthing搜索,然后复制粘贴。

        命令:protoc.exe -I GrpcConsole --csharp_out GrpcConsole GrpcConsole\helloworld.proto --grpc_out GrpcConsole --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe

        对,你找文章都这一长串,demo也是,运行时候各种报错,神特么烦,也不跟你细说选项作用,注意事项。

        这里就详细说一下:

          ①、 -I 指定一个或者多个目录,用来搜索.proto文件的。所以上面那行的GrpcConsole\helloworld.proto 已经可以换成helloworld.proto了,因为-I已经指定了。注意:如果不指定,那就是当前目录,没毛病。

          ②、--csharp_out 生成C#代码,当然了还能cpp_out、java_out、javanano_out、js_out、objc_out、php_out、python_out、ruby_out 这时候你就应该知道,这玩意就是支持多语言的,才用的,生成一些文件,然后给各个语言平台调用。参数1是输出路径,参数2是proto的文件名或者路径。 

          ③、--grpc_out 到这里可能有人会懵逼,咋回事?C#不是有一个自己的输出目录么?怎么又一个输出?  

            csharp_out是输出类似于咱们平时写的实体类,接口,定义之类的。生成的文件叫,额,就叫xxx.cs吧.

            grpc_out是跟服务相关,创建,调用,绑定,实现相关。生成的玩意叫xxxGrpc.cs。 对比上个选项生成的文件名,大概能了解个十之八九吧。

          ④、--plugin=protoc-gen-grpc=grpc_csharp_plugin.exe 这个就是csharp的插件,python有python的,java有java的。你不指定它,你毛都生成不了。

 

      d、开发

          请允许我做被悲伤、绝望地砸键盘动作,你忙活了那么久,现在刚刚进入开发阶段,具体的,自己个去看官方demo.  毕竟本文重点并不是这货。

 

0x02、MagicOnion

  1、介绍

      首先这里声明一点,技术无国界。

      MagicOnion 是一位来自日本的 CTO (目前就职于Grani游戏公司), UniRx、MsgPack序列化CSharp实现的作者,连续...反正好多年的MVP(从2011年开始),叫Yoshifumi Kawai ?(咋这么像‘卡哇伊’??)。作品集:https://github.com/neuecc。

      MagicOnion是对Grpc的封装,并且采用了MessagePack序列化技术,提高性能,随后支持了SwaggerUI。

      MessagePack (msgPack)是很早之前的一个序列化技术,各文章媒体介绍说比json快10倍,之前关注过,json这两年的势头太猛了。 MessagePack-CSharp 去年(2017年)开始浮出水面的,实测比json.net序列化快很多很多,不是一个数量级,这里我就不谈protobuf和mesasgepack的差别了,因为我可能写了假代码(他的readme说MessagePack比protobuf效率要高,我测protobuf序列化性能比他要高)。

      Swagger, 必应一大把。

      MIT协议,写着放心,用着舒心。

 

  2、吐槽

      两个月没更新了,Github上有灰。

 

  3、普通C/S框架搭建流程

       a、Nuget上搜MagicOnion,下载安装。

      b、非常非常重要的接口,你不得不写的接口,这个接口服务端和客户端都要定义。

      

 1   //不管你在哪里写,反正服务端和客户端都要写,对!要么引用,要么写一模一样的。 2   //你能看懂的那都是你写的。 3   //你看不懂的都是它库里自带的,比如IService,UnaryResult<>。 4   public interface IHello : IService<IHello> 5   { 6     UnaryResult<string> Hello(string name); 7   } 8   public interface IWorld : IService<IWorld> 9   {10     UnaryResult<string> World(string name);11   }12 15 16    //不管你在哪写,反正服务端需要实现,客户端远程调用接口的时候走的就是这方法17     public class HelloServices : ServiceBase<IHello>, IHello18     {19         public UnaryResult<string> Hello(string name)20         {21             return new UnaryResult<string>($"hello {name}");22         }23     }24     public class WorldServices : ServiceBase<IWorld>, IWorld25     {26         public UnaryResult<string> World(string name)27         {28             return new UnaryResult<string>($"This is {name}'s world!");29         }30     }  

      c、编写客户端和服务端,简单到我不好意思贴代码,贴图吧

      

      

      各位老铁,这代码能看懂吧?没毛病。流传输去官网下看Readme的例子,也挺容易。

 

  4、集成在Web中,做成接口。

      a、引用

        MagicOnion.HttpGateway (其中包含了MagicOnion、Asp.net core 中间件扩展、Json.net、MagicOnion.HttpGetway)

        Swashbuckle.AspNetCore

       b、有了第3个C/S的基础,那么你就可以继续干了。写你的接口,并且配上注释,因为Swagger要用!

        ReturnResult是我自己定义的返回值,跟这些库无关,你随便写。

        

      c、写你的代码,实体类,要支持MessagePack序列化,打个标签。

        

      d、其他的工作(都随你便)

        

      

    public class Test :ServiceBase<ITest>, ITest{        public UnaryResult<ReturnResult> GetStudent(int sid){            //GetStudentBySidFromDatabase(sid)            //GetModelStudent student;student.Name = "Test_小明";student.Sid = sid;            //FillResultReturnResult result = new ReturnResult() {Data = student,Status = 0};            //Returnreturn UnaryResult(result);}}

        这是是实现你定义的接口,你想返回啥都行,读数据库,读缓存都随便你,我就是简单写个例子。

      e、然后就是添加服务,你这个rpc是作为服务集成在web中的。

      

        public void ConfigureServices(IServiceCollection services){            //这代码跟咱们之前定义服务的那个代码一个样子var service = MagicOnionEngine.BuildServerServiceDefinition(new MagicOnionOptions(true){MagicOnionLogger = new MagicOnionLogToGrpcLogger()});            var server = new Server{Services = { service },Ports = { new ServerPort("localhost", 8800, ServerCredentials.Insecure) }};            //这里开始不同,你要把注释生成到xml里给swagger,这里是swagger的用法,看不懂去学swaggerservices.AddSwaggerGen(c =>{                var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "Swagger.xml");c.IncludeXmlComments(filePath);});server.Start();            //这里添加服务services.Add(new ServiceDescriptor(typeof(MagicOnionServiceDefinition), service));services.AddMvc();}

      f、配置,各种配置。

     public void Configure(IApplicationBuilder app, IHostingEnvironment env){            //获取添加了的服务var magicOnion = app.ApplicationServices.GetService<MagicOnionServiceDefinition>();            //使用MagicOnion的Swagger扩展,就是让你的rpc接口也能在swagger页面上显示            //下面这些东西你可能乍一看就懵逼,但你看到页面的时候就会发现,一个萝卜一个坑。            //注意:swagger原生用法属性都是大写的,这里是小写。app.UseMagicOnionSwagger(magicOnion.MethodHandlers, new SwaggerOptions("MagicOnion.Server", "Swagger Integration Test", "/"){Info = new Info(){title = "MGrpc",version = "v1",description = "This is the API-Interface for MGrpc",termsOfService = "By NMS",contact = new Contact{name = "LanX",email = "2765968624@qq.com"}},                //使用Swagger生成的xml,就是你接口的注释XmlDocumentPath = PlatformServices.Default.Application.ApplicationBasePath + "Swagger.xml"});            //要想让rpc成为该web服务的接口,流量和协议被统一到你写的这个web项目中来,那么就要用个方法链接你和rpc            //这个web项目承接你的请求,然后web去调用rpc获取结果,再返回给你。            //因此需要下面这句话app.UseMagicOnionHttpGateway(magicOnion.MethodHandlers, new Channel("localhost:8800", ChannelCredentials.Insecure));            
  
       if (env.IsDevelopment()){app.UseDeveloperExceptionPage();} //以下是swagger的用法,不赘述app.UseSwagger(c =>{c.RouteTemplate = "swagger/{documentName}/swagger.json";});app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/swagger/v1/swagger.json", "API-v1");c.ShowJsonEditor();c.ShowRequestHeaders();});app.UseSwagger();app.UseMvc();}

   5、成果:


      

 

0x03、窥视你的通信过程

    1、抓包查看它们的通信过程,装Wireshark, 但是它不抓本地包,只抓网卡的,本地环回地址实际上是走的是操作系统内部,跟网卡无关,因此需要借助一个工具,Npcap,下载页面https://nmap.org/npcap/#download,文章中间有下载的地方。某些人会留意到神器Nmap,吊得一比。装完之后你的Wireshark会多一个接口,本地接口,然后你就侦听吧,过滤语句:http || tcp.port == 8800,复制粘贴就是干。

  效果:

     
      
      
      交互过程以及三次握爪
      
      发送数据,可靠传输
      

0x04、广告时间
    

0x05、结束
     
     

    
感谢各位老铁能坚持看完,没有彩蛋,拜拜~

原文地址:https://www.cnblogs.com/nmslanx/articles/8242105.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11-分步查询懒加载

分步查询——懒加载模式 目录 懒加载模式示例不使用懒加载使用懒加载aggressiveLazyLoadinglazyLoadTriggerMethods所谓懒加载&#xff0c;也称延时加载&#xff0c;是指不一下子加载完全部资源。需要用到哪些资源才去加载这些资源&#xff0c;用不到的资源&#xff0c;就不去…

利用Service Fabric承载eShop On Containers

从模块化到微服务化从Pet Shop 到eShop on Container都是Microsoft在技术演进的路径上给开发者展示.Net的开发能力和架构能力的Sample工程&#xff0c;Petshop的时候更多的是展现应用的分层架构&#xff0c;设计的抽象与模块间的通讯。到了eShop on Container更多的关注在架构设…

12-多对一添加操作(添加新客户及对应的新订单)

多对一添加操作 场景&#xff1a;现在想要添加一个新客户对应一个新订单&#xff0c;那么要怎么来添加呢&#xff1f; 分析&#xff1a;由于添加订单时&#xff0c;客户对订单是一对多的关系&#xff0c;所以添加订单的时候必须要指明一位客户。 要同时添加新客户以及一个新订…

.NET Core+MySql+Nginx 容器化部署

1. 引言上两节我们通过简单的demo学习了docker的基本操作。这一节我们来一个进阶学习&#xff0c;完成ASP.NET Core MySql Nginx的容器化部署。本文是基于CentOS 7.4环境进行演示&#xff0c;示例项目可以访问Docker.NetCore.MySql进行下载。2. Hello MySQL同样我们还是以循序…

HiveSQL常用优化方法全面总结

转载自 HiveSQL常用优化方法全面总结 Hive作为大数据领域常用的数据仓库组件&#xff0c;在平时设计和查询时要特别注意效率。影响Hive效率的几乎从不是数据量过大&#xff0c;而是数据倾斜、数据冗余、job或I/O过多、MapReduce分配不合理等等。对Hive的调优既包含对HiveQL语…

P3597-[POI2015]WYC【矩阵乘法,倍增】

前言 正题 题目链接:https://www.luogu.org/problemnew/show/P3597 题目大意 问第kkk长的路径长度(非简单路径) 解题思路 先考虑kkk比较小时的情况&#xff0c;我们可以求出长度为111的路径&#xff0c;长度为222的路径&#xff0c;然后以此类推找到第一个与前面的和到kkk就…

13-一对多左连接查询分步查询(查询所有客户及客户对应的订单)

查询所有客户以及对应的订单 目录 左连接查询&#xff08;不支持懒加载&#xff09;分步查询&#xff08;支持懒加载&#xff09;左连接查询&#xff08;不支持懒加载&#xff09; 场景&#xff1a;我们想要查询出所有的客户&#xff0c;并且把每个客户对应的订单也查出来。…

实战 | 利用Delta Lake使Spark SQL支持跨表CRUD操作

转载自 实战 | 利用Delta Lake使Spark SQL支持跨表CRUD操作 供稿 | eBay ADI-Carmel Team 作者 | 金澜涛 编辑 | 顾欣怡 本文7309字&#xff0c;预计阅读时间22分钟 导读 本文介绍eBay Carmel团队利用Delta Lake&#xff0c;使Spark SQL支持Teradata的Update/Delete语法。…

14-多对多关系建表

多对多关系建表 目录 多对多关系多对多关系建表原则domain多对多关系 一个老师可以教多个学生&#xff0c;一个学生可以被多个老师教。一个学生可以选择多门课程&#xff0c;一门课程可以被多个学生选择。一个用户可以选择多个角色&#xff0c;一个角色可以被多个用户选择。…

DevOps文档中心的技术实践演进

这应该算是《Git企业开发者教程》的篇外篇&#xff0c;介绍一下这个教程是怎样写出来的。相信每个技术人都有类似下面的文件夹&#xff0c;保存着你辛苦工作的成果。实际的感觉&#xff1a;看着闹心&#xff0c;弃之不舍。一份文档久经修改&#xff0c;不能定稿&#xff0c;循环…

MySQL UPDATE 语句一个“经典”的坑

转载自 MySQL UPDATE 语句一个“经典”的坑 来源&#xff1a;ju.outofmemory.cn/entry/336774 有问题的SQL语句 why? 倒回去再重试验一把 最近好几次有开发同学在钉钉上问我&#xff0c;比如下图&#xff1a; 问题归纳起来就是&#xff1a;在MySQL里面update一条记录&…

jzoj4803-[NOIP2016提高A组模拟9.28]求导【模拟】

正题 题目大意 求一个标准多项式的求导 解题思路 暴力模拟即可&#xff0c;注意细节即可 一下是贴心的坑爹细节样例 (233x)−>(1)而不是(1)(233x)->(1)而不是(1)(233x)−>(1)而不是(1) (1)−>(0)而不是()(1)->(0)而不是()(1)−>(0)而不是() codecodecode …

g4e基础篇#1 为什么要使用版本控制系统

本篇是Git企业开发者教程基础篇的第一篇1. 基础篇&#xff1a;为什么要使用版本控制系统Git 分布式版本控制系统的优势Git 安装和设置初始化Git存储库(Repo)起步 1 – 创建分支和保存代码起步 2 – 了解Git历史记录起步 3 – 拉取请求 Pull Request 工作机制Git是一种版本控制系…

15-多对多做左连接查询(查询老师,并且把关联的学生也查出来)

多对多左连接查询 目录 左连接查询老师对学生是多对多的关系&#xff0c;把中心放在老师上&#xff0c;一个老师可以教多个学生&#xff0c;实际上老师对学生也可以理解为一对多的关系。 左连接查询 场景&#xff1a;查询老师&#xff0c;并且把关联的学生也查出来。 Teac…

.Net 如何模拟会话级别的信号量,对http接口调用频率进行限制(有demo)

现在&#xff0c;因为种种因素&#xff0c;你必须对一个请求或者方法进行频率上的访问限制。 比如&#xff0c; 你对外提供了一个API接口&#xff0c;注册用户每秒钟最多可以调用100次&#xff0c;非注册用户每秒钟最多可以调用10次。比如&#xff0c; 有一个非常吃服务器资源的…

1.数据湖deltalake初识

转载自 1.数据湖deltalake初识 1.delta特性简介 Delta Lake是Spark计算框架和存储系统之间带有Schema信息数据的存储中间层。它给Spark带来了三个最主要的功能&#xff1a; 第一&#xff0c;Delta Lake使得Spark能支持数据更新和删除功能&#xff1b; 第二&#xff0c;Del…

Quartz.NET 3.0 正式发布

Quartz.NET是一个强大、开源、轻量的作业调度框架&#xff0c;你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征&#xff0c;如&#xff1a;数据库支持&#xff0c;集群&#xff0c;插件&#xff0c;支持cron-like表达式等等。在2017年的最后一天Quartz.…

(九)IDEA便捷配置MyBatis.xml文件

在使用IDEA新建mybatis.xml经常需要手动复制粘贴之前的xml配置。这样也比较麻烦。我们可以IDEA进行关于xml的配置 1.创建MyBatis Config的模版 1.打开新增2.查看编辑页面查看编辑页面 我们看到Name&#xff1a;为我们新增模版的文件名称。Extension&#xff1a;为我们新增文件…

用 Identity Server 4 (JWKS 端点和 RS256 算法) 来保护 Python web api

目前正在使用asp.net core 2.0 (主要是web api)做一个项目, 其中一部分功能需要使用js客户端调用python的pandas, 所以需要建立一个python 的 rest api, 我暂时选用了hug, 官网在这: http://www.hug.rest/.目前项目使用的是identity server 4, 还有一些web api和js client.项目…

MySQL死锁如何处理

转载自 MySQL死锁如何处理 前提 笔者负责的一个系统最近有新功能上线后突然在预警模块不定时报出MySQL死锁导致事务回滚。幸亏&#xff0c;上游系统采用了异步推送和同步查询结合的方式&#xff0c;感知到推送失败及时进行了补偿。于是&#xff0c;笔者争取了一点时间详细分析…