架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 76|回复: 1

[.NET Core] 【实战】ASP.NET Core 中使用 gRPC 通信

[复制链接]
跳转到指定楼层
楼主
发表于 6 天前
zu
grpc(https://grpc.io/)是google发布的一个开源、高性能、通用RPC(Remote Procedure Call)框架,使用HTTP/2协议,支持多路复用,并用ProtoBuf作为序列化工具,提供跨语言、跨平台支持。
gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架。

gRPC 的主要优点是:

  • 现代高性能轻量级 RPC 框架。
  • 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
  • 可用于多种语言的工具,以生成强类型服务器和客户端。
  • 支持客户端、服务器和双向流式处理调用。
  • 使用 Protobuf 二进制序列化减少对网络的使用。


本文以.Net Core 使用 gRPC 协议进行客户端和服务端进行通信。

创建 gRPC 服务端

启动 Visual Studio 并选择“创建新项目” 。 或者,从 Visual Studio“文件”菜单中选择“新建” > “项目” 。

在“创建新项目”对话框中,选择“gRPC 服务”,然后选择“下一步” :




创建完成后,如下图:




创建 gRPC 客户端

打开 Visual Studio 的第二个实例并选择“创建新项目” 。
在“创建新项目”对话框中,选择“控制台应用(.NET Core)”,然后选择“下一步” 。
在“名称”文本框中,输入“gRPC-Client”,然后选择“创建” 。


添加所需的包

gRPC 客户端项目需要以下包:
Grpc.Net.Client,其中包含 .NET Core 客户端。
Google.Protobuf 包含适用于 C# 的 Protobuf 消息。
Grpc.Tools 包含适用于 Protobuf 文件的 C# 工具支持。 运行时不需要工具包,因此依赖项标记为 PrivateAssets="All"。

  1. Install-Package Grpc.Net.Client -Version 2.25.0
  2. Install-Package Google.Protobuf -Version 3.10.1
  3. Install-Package Grpc.Tools -Version 2.25.0
复制代码



添加 greet.proto

在 gRPC 客户端项目中创建 Protos 文件夹 。
从 gRPC Greeter 服务将 Protos\greet.proto 文件复制到 gRPC 客户端项目 。

编辑 gRPC-Client.csproj 项目文件,添加具有引用 greet.proto 文件的 <Protobuf> 元素的项组:

  1. <ItemGroup>
  2.   <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
  3. </ItemGroup>
复制代码




创建 Greeter 客户端

使用以下代码更新 gRPC 客户端的 Program.cs 文件 :


  1. using Grpc.Net.Client;
  2. using GrpcService1;
  3. using System;

  4. namespace gRPC_Client
  5. {
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             Console.WriteLine("Hello World!");
  11.             var channel = GrpcChannel.ForAddress("https://localhost:5001");
  12.             var client = new Greeter.GreeterClient(channel);
  13.             var reply = client.SayHello(
  14.                               new HelloRequest { Name = "itsvse.com" });
  15.             Console.WriteLine("响应: " + reply.Message);
  16.             Console.ReadKey();
  17.         }
  18.     }
  19. }
复制代码



实例化 GrpcChannel,使其包含用于创建到 gRPC 服务的连接的信息。
使用 GrpcChannel 构造 Greeter 客户端。
Greeter 客户端会调用 SayHello 方法。 随即显示 SayHello 调用的结果。




创建自己的 .proto 文件通信

在 serve 的 Protos 文件夹下面新建一个 userinfo.proto 文件,定义如下:
  1. syntax = "proto3";
  2. //服务
  3. service UserInfo {
  4.   rpc GetUserInfo (GetUserInfoRequest) returns (UserInfoReply);
  5. }
  6. //请求
  7. message GetUserInfoRequest {
  8.   sint64 id = 1;
  9. }
  10. //响应
  11. message UserInfoReply {
  12.   string name = 1;
  13.   int32 age = 2;
  14.   bool isVip = 3;
  15. }
复制代码


gRPC 使用协定优先方法进行 API 开发。 在 *.proto 文件中定义服务和消息。

编辑 GrpcService1.csproj 项目文件,添加具有引用 userinfo.proto 文件的 <Protobuf> 元素的项组:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
    <Protobuf Include="Protos\userinfo.proto" GrpcServices="Server" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.23.1" />
  </ItemGroup>

</Project>


在 Services 文件夹下面新建 UserInfoService.cs 文件,代码如下:

  1. using Grpc.Core;
  2. using Microsoft.Extensions.Logging;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading.Tasks;

  7. namespace GrpcService1
  8. {
  9.     public class UserInfoService : UserInfo.UserInfoBase
  10.     {
  11.         private readonly ILogger<UserInfoService> _logger;
  12.         private static List<UserInfoReply> userInfoReplies = new List<UserInfoReply>();
  13.         static UserInfoService()
  14.         {
  15.             userInfoReplies.Add(new UserInfoReply()
  16.             {
  17.                 Id = 1,
  18.                 Name = "架构师",
  19.                 Age = 5,
  20.                 IsVip = true
  21.             });
  22.             userInfoReplies.Add(new UserInfoReply()
  23.             {
  24.                 Id = 2,
  25.                 Name = "itsvse.com",
  26.                 Age = 5,
  27.                 IsVip = false
  28.             });
  29.             userInfoReplies.Add(new UserInfoReply()
  30.             {
  31.                 Id = 3,
  32.                 Name = "小渣渣",
  33.                 Age = 1,
  34.                 IsVip = false
  35.             });
  36.         }
  37.         public UserInfoService(ILogger<UserInfoService> logger)
  38.         {
  39.             _logger = logger;
  40.         }

  41.         public override Task<UserInfoReply> GetUserInfo(GetUserInfoRequest request, ServerCallContext context)
  42.         {
  43.             return Task.Run(() =>
  44.             {
  45.                 return userInfoReplies.SingleOrDefault(x => x.Id == request.Id);
  46.             });
  47.         }
  48.     }
  49. }
复制代码
在 Startup.cs 注册 UserInfoService 服务,代码如下:

  1. endpoints.MapGrpcService<GreeterService>();
  2.                 endpoints.MapGrpcService<UserInfoService>();
复制代码
客户端就不说了,当然,需要复制 userinfo.proto 文件过去,代码如下:

  1. using Grpc.Net.Client;
  2. using GrpcService1;
  3. using System;

  4. namespace gRPC_Client
  5. {
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             Console.WriteLine("Hello World!");
  11.             var channel = GrpcChannel.ForAddress("https://localhost:5001");
  12.             var client = new Greeter.GreeterClient(channel);
  13.             var userClient = new UserInfo.UserInfoClient(channel);
  14.             var reply = client.SayHello(
  15.                               new HelloRequest { Name = "itsvse.com" });
  16.             Console.WriteLine("响应: " + reply.Message);
  17.             Console.WriteLine(userClient.GetUserInfo(new GetUserInfoRequest { Id = 1 }));
  18.             Console.WriteLine(userClient.GetUserInfo(new GetUserInfoRequest { Id = 2 }));
  19.             Console.WriteLine(userClient.GetUserInfo(new GetUserInfoRequest { Id = 123 }));
  20.             Console.ReadKey();
  21.         }
  22.     }
  23. }
复制代码
返回值:

Hello World!
响应: Hello itsvse.com
{ "id": "1", "name": "架构师", "age": 5, "isVip": true }
{ "id": "2", "name": "itsvse.com", "age": 5 }
Unhandled exception. Grpc.Core.RpcException: Status(StatusCode=Cancelled, Detail="No message returned from method.")
   at Grpc.Net.Client.Internal.HttpClientCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext`2 ctx)
   at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at UserInfo.UserInfoClient.GetUserInfo(GetUserInfoRequest request, CallOptions options) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\obj\Debug\netcoreapp3.0\UserinfoGrpc.cs:line 62
   at UserInfo.UserInfoClient.GetUserInfo(GetUserInfoRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\obj\Debug\netcoreapp3.0\UserinfoGrpc.cs:line 58
   at gRPC_Client.Program.Main(String[] args) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\Program.cs:line 20
请按任意键继续. . .


当返回值为null的时候,客户端会抛出异常。


Fiddler 抓包

尝试使用Fiddler抓包,首先客户端设置代理如下(其实不设置也可以,直接打开fiddler即可):

  1. HttpClient.DefaultProxy = new System.Net.WebProxy("127.0.0.1:8888",false);
复制代码
服务端报错:

fail: Microsoft.AspNetCore.Server.Kestrel[0]
      HTTP/2 over TLS was not negotiated on an HTTP/2-only endpoint.
客户端报错:

Unhandled exception. Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Bad gRPC response. Response protocol downgraded to HTTP/1.1.")
   at Grpc.Net.Client.Internal.HttpClientCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext`2 ctx)
   at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at UserInfo.UserInfoClient.GetUserInfo(GetUserInfoRequest request, CallOptions options) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\obj\Debug\netcoreapp3.0\UserinfoGrpc.cs:line 62
   at UserInfo.UserInfoClient.GetUserInfo(GetUserInfoRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\obj\Debug\netcoreapp3.0\UserinfoGrpc.cs:line 58
   at gRPC_Client.Program.Main(String[] args) in C:\Users\DELL\source\repos\GrpcService1\gRPC-Client\Program.cs:line 23
请按任意键继续. . .


POST 地址: https://localhost:5001/UserInfo/GetUserInfo

内容:

Host: localhost:5001
User-Agent: grpc-dotnet/2.25.0.0
TE: trailers
grpc-accept-encoding: identity,gzip
Content-Type: application/grpc
Content-Length: 7
Fiddler-Encoding: base64


最后,附上源代码:

游客,如果您要查看本帖隐藏内容请回复


(完)




上一篇:程序员炼成记:从小白到工程师 完整pdf
下一篇:达芬奇全套教程,从入门到放弃你值得拥有
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
沙发
发表于 6 天前
ASP.NET Core 中使用 gRPC 通信
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-11-17 07:56

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表
即时比分新浪