tnblog
首页
视频
资源
登录

.NetCore 3.x 与 grpc

7071人阅读 2020/3/28 17:31 总访问:3470564 评论:0 收藏:0 手机
分类: grpc

  目录


 本篇文章主要讲解如下内容

   一。grpc在 .Net Core 3.x 中的应用

   二。grpc如何分段上传图片

   代码与实现过程比较简单,大家可以无限延伸对 grpc 的使用



环境部署

Server


(一) 创建服务器端 GrpcServer.Web



(二) 项目结构如下



(三) Startup.cs 内容如下


  1. public class Startup
  2. {
  3.     public void ConfigureServices(IServiceCollection services)
  4.     {
  5.         services.AddGrpc();
  6.     }
  7.     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  8.     {
  9.         if (env.IsDevelopment())
  10.         {
  11.             app.UseDeveloperExceptionPage();
  12.         }
  13.         app.UseRouting();
  14.         app.UseStaticFiles();
  15.         app.UseHttpsRedirection();
  16.         app.UseEndpoints(endpoints =>
  17.         {
  18.             endpoints.MapGrpcService<MyEmployeeService>();
  19.         });
  20.     }
  21. }


(四) 安装 Grpc.AspNetCore      



launchSettings.json

  1. {
  2.   "profiles": {
  3.     "GrpcServer.Web": {
  4.       "commandName""Project",
  5.       "launchBrowser"true,
  6.       "applicationUrl""https://localhost:5001",
  7.       "environmentVariables": {
  8.         "ASPNETCORE_ENVIRONMENT""Development"
  9.       }
  10.     }
  11.   }
  12. }



Client


(一) 创建 GrpcClient 控制台应用程序  



(二) 安装相关 Grpc 客户端的包        




Grpc 建立普通通信方式

Server


Proto 文件夹下添加 Message.proto 文件




添加内容


  1. syntax = "proto3";
  2. option csharp_namespace = "GrpcServer.Web.Protos";
  3. message Employee {
  4. int32 id = 1;
  5. int32 no = 2;
  6. string firstName = 3;
  7. string lasterName = 4;
  8. float salary = 5;
  9. }
  10. message GetByNoRequest{
  11. int32 no = 1;
  12. }
  13. message EmployeeResponse{
  14. Employee employee =1;
  15. }
  16. message GetAllRequest {}
  17. message AddPhotoRequest{
  18. bytes data = 1;
  19. }
  20. message AddPhotoResponse{
  21. bool isOk = 1;
  22. }
  23. message EmployeeRequest{
  24. Employee employee = 1;
  25. }
  26. service EmployeeService{
  27. rpc GetByNo(GetByNoRequest) returns (EmployeeResponse);
  28. rpc GetAll(GetAllRequest) returns (stream EmployeeResponse);
  29. rpc AddPhoto(stream AddPhotoRequest) returns (AddPhotoResponse);
  30. rpc Save(EmployeeRequest) returns (EmployeeResponse);
  31. rpc SaveAll(stream EmployeeRequest) returns (stream EmployeeResponse);
  32. }


并选中 Message.proto 修改为如下属性



在 Data 文件夹下添加 InMemoryData.cs


  1. public class InMemoryData
  2. {
  3.     public static List<Employee> Employees = new List<Employee>() {
  4.         new Employee{
  5.             Id = 1,
  6.             No = 1994,
  7.             FirstName = "Chandler",
  8.             LasterName = "Bing",
  9.             Salary = 2200
  10.         },
  11.         new Employee{
  12.             Id = 2,
  13.             No = 1999,
  14.             FirstName = "Rachl",
  15.             LasterName = "Green",
  16.             Salary = 2400
  17.         },
  18.         new Employee{
  19.             Id = 3,
  20.             No = 2452,
  21.             FirstName = "MI",
  22.             LasterName = "UIMI",
  23.             Salary = 2600
  24.         }
  25.     };
  26. }


在 Servcies 文件夹下添加 MyEmployeeService.cs


  1. public class MyEmployeeService: EmployeeService.EmployeeServiceBase
  2. {
  3.     private readonly ILogger<MyEmployeeService> _logger;
  4.     private readonly IHostingEnvironment _hostingEnvironment;
  5.     public MyEmployeeService(ILogger<MyEmployeeService> logger, IHostingEnvironment hostingEnvironment) 
  6.     {
  7.         _logger = logger;
  8.         _hostingEnvironment = hostingEnvironment;
  9.     }
  10.     public async override Task<EmployeeResponse> GetByNo(GetByNoRequest request, ServerCallContext context)
  11.     {
  12.         //获取 Metadata = context.RequestHeaders
  13.         var md = context.RequestHeaders;
  14.         foreach (var item in md)
  15.         {
  16.             _logger.LogInformation($"{ item.Key } : { item.Value }");
  17.         }
  18.         var employee = InMemoryData.Employees
  19.             .SingleOrDefault(x => x.No == request.No);
  20.         if (employee!=null)
  21.         {
  22.             var response = new EmployeeResponse { 
  23.                 Employee = employee
  24.             };
  25.             return await Task.FromResult(response);
  26.         }
  27.         throw new System.Exception($"Employee not found with no: {request.No}");
  28.     }
  29.     public override async Task GetAll(GetAllRequest request, IServerStreamWriter<EmployeeResponse> responseStream, ServerCallContext context)
  30.     {
  31.         foreach (var employee in InMemoryData.Employees)
  32.         {
  33.             await responseStream.WriteAsync(new EmployeeResponse { 
  34.                 Employee = employee
  35.             });
  36.         }
  37.     }
  38. }


Client


将服务器上的 Message.proto 文件复制到 Protos 文件夹下面

并修改其属性如下



修改 Program.cs 


  1. static async Task Main(string[] args)
  2. {
  3.     //
  4.     using var channel = GrpcChannel.ForAddress("https://localhost:5001");
  5.     //var client = new 
  6.     var client = new EmployeeService.EmployeeServiceClient(channel);
  7.     //await GetPhotoAsync(client);
  8.     var option = int.Parse(args[0]);
  9.     switch (option)
  10.     {
  11.         case 1:
  12.             await GetByNoAsync(client);
  13.             break;
  14.         case 2:
  15.             await GetAllAsync(client);
  16.             break;
  17.         default:
  18.             break;
  19.     }
  20.     Console.ReadKey();
  21. }
  22. private static async Task GetAllAsync(EmployeeService.EmployeeServiceClient client)
  23. {
  24.     using var call = client.GetAll(new GetAllRequest());
  25.     var responseStream = call.ResponseStream;
  26.     while (await responseStream.MoveNext())
  27.     {
  28.         Console.WriteLine(responseStream.Current.Employee);
  29.     }
  30. }
  31. private static async Task GetByNoAsync( EmployeeService.EmployeeServiceClient client)
  32. {
  33.     //定义元数据
  34.     var md = new Metadata {
  35.         { "username","administrator" },
  36.         { "role","administrator" }
  37.     };
  38.     var response = await client.GetByNoAsync(new GetByNoRequest
  39.     {
  40.         No = 1994
  41.     }, md);
  42.     Console.WriteLine($"Response messages:{response}");
  43.     Console.WriteLine("Press any key to exit.");
  44. }


 《 Test 》


先启动服务器端,然后再在控制台中启动客户端




通过客户端分段上传图片到服务器端

Server


实现 AddPhoto 方法


  1.         public async override Task<AddPhotoResponse> AddPhoto(IAsyncStreamReader<AddPhotoRequest> requestStream, ServerCallContext context)
  2.         {
  3.             //获取 Metadata
  4.             Metadata md = context.RequestHeaders;
  5.             string FileName = "";
  6.             foreach (var item in md)
  7.             {
  8.                 Console.WriteLine($"{item.Key}{item.Value}");
  9.                 if (item.Key== "filename")
  10.                 {
  11.                     FileName = item.Value;
  12.                 }
  13.             }
  14.             //获取
  15.             var data = new List<byte>();
  16.             //获取流
  17.             while (await requestStream.MoveNext())
  18.             {
  19.                 Console.WriteLine($"Received:{requestStream.Current.Data.Length} bytes ");
  20.                 data.AddRange(requestStream.Current.Data);
  21.             }
  22.             string fullnamepath = _hostingEnvironment.WebRootPath +"\\"+ DateTime.Now.ToString("yyyyMMddhhmmss") + FileName;
  23.             using var file = new MemoryStream(data.ToArray());
  24.             using (FileStream filestream = new FileStream(fullnamepath, FileMode.Create))
  25.             {
  26.                 await file.CopyToAsync(filestream);
  27.                 filestream.Flush();
  28.             }
  29.             Console.WriteLine($"Received file with {data.Count} bytes");
  30.             
  31.             //返回流结果
  32.             return new AddPhotoResponse { 
  33.                 IsOk = true
  34.             };
  35.         }


Client


修改 Program.cs 


  1.          。。。
  2.                 case 3:
  3.                     await GetPhotoAsync(client);
  4.                     break;
  5.          。。。
  6.          
  7. private static async Task GetPhotoAsync(EmployeeService.EmployeeServiceClient client)
  8. {
  9.     FileStream fs = File.OpenRead("logo.png");
  10.     //定义元数据
  11.     var md = new Metadata {
  12.         { "username","administrator" },
  13.         { "role","administrator" },
  14.         { "filename", fs.Name.Substring(fs.Name.LastIndexOf('\\')+1) }
  15.     };
  16.     using var call = client.AddPhoto(md);
  17.     //向 server 端发起请求
  18.     var stream = call.RequestStream;
  19.     //然后进行分段上传图片
  20.     while (true)
  21.     {
  22.         byte[] buffer = new byte[1024];
  23.         int numRead = await fs.ReadAsync(buffer, offset: 0, count: buffer.Length);
  24.         //读取读满了退出
  25.         if (numRead == 0)
  26.         {
  27.             break;
  28.         }
  29.         //读取长度不一致将变为一致
  30.         if (numRead < buffer.Length)
  31.         {
  32.             Array.Resize(ref buffer, numRead);
  33.         }
  34.         //向服务端写数据
  35.         await stream.WriteAsync(new AddPhotoRequest() { 
  36.             Data = ByteString.CopyFrom(buffer) 
  37.         });
  38.     }
  39.     //告诉 server 我的数据都传完了
  40.     await stream.CompleteAsync();
  41.     //获取上传结果
  42.     var res = await call.ResponseAsync;
  43.     Console.WriteLine(res.IsOk);
  44. }


 《 Test 》




扩展资料

如果你想进一步了解 gRPC,请查阅 ASP.NET Core gRPC 文档。请向我们提出你对 gRPC-Web 的意见和经验反馈,因为这将帮助我们选择如何以及是否在未来的 ASP.NET Core 版本中使 gRPC-Web 成 一个标准特性。你可以在这里发布评论,或者在 GitHub 上发布标题中带有“反馈”的 issue。

翻译自原文:https://blog.stevensanderson.com/2020/01/15/2020-01-15-grpc-web-in-blazor-webassembly

相关文章:

近期,观测分析平台 SkyWalking 的 .NET 自动探针 (SkyAPM-dotnet) 也已经支持了 grpc-dotnet 远程调用的链路跟踪采集,欢迎大家使用!如果喜欢,也请大家给点个星星!

项目地址:https://github.com/SkyAPM/SkyAPM-dotnet



欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

分布式服务架构微服务架构概念的区别联系

分布式:分散压力。微服务:分散能力。当下理解分布式:不同模块部署在不同服务器上作用:分布式解决网站高并发带来问题集...

jsController中分割字符串的方法

js: varstr=OpenRule; varstrs=newArray(); strs=str.split(&quot;,&quot;); for(vari=0;i&lt;strs.length;i++){ $(&q...

Service-stack.redis配置连接池读写分离(处理并发相关等)

配置连接池与读写分类 //写节点(主节点) List&lt;string&gt;writes=newList&lt;string&gt;(); writes.Add(&quot;123456a...

CSS相对定位绝对定位

一般相对定位和绝对定位可以配合起来使用 例如实现如下的效果 只需要在外层div设置为相对定位,在内部设置为绝对定位就...

C委托事件

1.什么是委托?  委托在C#里的意义和在现实里差不多,从字面意思理解即可。举个例子:领导委托小张去传递个文件,这就是...

asp.net core2.0 依赖注入 AddTransientAddScoped的区别

asp.net core主要提供了三种依赖注入的方式其中AddTransient与AddSingleton比较好区别AddTransient瞬时模式:每次都获取一...

Vue.js+Layer实现表格数据绑定更新

一:使用Vue.js绑定好数据与更新事件 使用v-on绑定好事件,在事件里边直接把该行数据传递进去,在更新方法里边就可以直接...

下划线、换行、回车、空格ASCII码值对照表

下划线,ASCII码95换行 , ASCII码10回车 , ASCII码13空格 , ASCII码32ASCII码表:Bin(二进制)Oct(八进制)Dec(十进制)Hex(...

数据读取器指定的"xx"不兼容。某个类型为"xx"的成员在同名的数据读取器中没有对应的列

报错的地方var result= _db.Database.SqlQuery&lt;SMachine&gt;(sql).FirstOrDefault();经过分析,是因为SqlQuery方法查询...

git 下载提交命令

一.先使用git clone下载一个项目 git clone &#39;项目地址&#39; 这里要注意: clone的项目里边会自带git的一些信息,...

微信开发四 接受用户普通消息回复消息

微信接收用户普通消息的文章可以在官方中直接看微信普通消息分类:接受用户文本消息 与 回复文本信息 注意在接收用户普通...

记忆糖的关系【阅读听力】

Link Between Memory and SugarSugar On The BrainIt’s long been understood that there is a connection between memory...

婚姻心脏健康的关系【阅读听力】

Marriage and Heart HealthPlenty of studies have found that being married is generally good for health. One study ze...

iframe自适应高度配合net core使用

去掉iframe边框frameborder=&quot;0&quot;去掉滚动条scrolling=&quot;no&quot;iframe 自适应高度如果内容是固定的,那么就...

net core中使用url编码解码操作

net core中暂时还没有以前asp.net与mvc中的server对象。获取url的编码与解码操作不能使用以前的server对象来获取。使用的是...

Sqlerver添加用户授权

添加用户安全性--&gt;登录名,然后右键新建登录名就可以了然后填写好相关信息就可以了右键属性,用户映射可以选择该用户可...
这一世以无限游戏为使命!
排名
2
文章
635
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术