架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 24236|回复: 8

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

[复制链接]
发表于 2019-11-11 10:55:26 | 显示全部楼层 |阅读模式
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 server.jpg

创建完成后,如下图:

QQ截图20191111093138.jpg


创建 gRPC 客户端

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


添加所需的包

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

QQ截图20191111094252.jpg


添加 greet.proto

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

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



QQ截图20191111095213.jpg

创建 Greeter 客户端

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





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


QQ截图20191111095542.jpg

创建自己的 .proto 文件通信

在 serve 的 Protos 文件夹下面新建一个 userinfo.proto 文件,定义如下:


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 文件,代码如下:

在 Startup.cs 注册 UserInfoService 服务,代码如下:

客户端就不说了,当然,需要复制 userinfo.proto 文件过去,代码如下:

返回值:

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
请按任意键继续. . .
QQ截图20191111103314.jpg

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


Fiddler 抓包

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

服务端报错:

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
请按任意键继续. . .
QQ截图20191111104916.jpg

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
下一篇:无损煲机音乐100首
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2019-11-11 17:46:30 | 显示全部楼层
ASP.NET Core 中使用 gRPC 通信
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2019-11-28 15:14:53 | 显示全部楼层
ASP.NET Core 中使用 gRPC 通信
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2019-11-28 15:15:25 | 显示全部楼层
ASP.NET Core 中使用 gRPC 通信
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2020-12-2 15:52:18 | 显示全部楼层
请问最后这个错误 你是怎么解决的啊
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2020-12-7 20:37:56 | 显示全部楼层
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GrpcService1
{
    public class UserInfoService : UserInfo.UserInfoBase
    {
        private readonly ILogger<UserInfoService> _logger;
        private static List<UserInfoReply> userInfoReplies = new List<UserInfoReply>();
        static UserInfoService()
        {
            userInfoReplies.Add(new UserInfoReply()
            {
                Id = 1,
                Name = "架构师",
                Age = 5,
                IsVip = true
            });
            userInfoReplies.Add(new UserInfoReply()
            {
                Id = 2,
                Name = "itsvse.com",
                Age = 5,
                IsVip = false
            });
            userInfoReplies.Add(new UserInfoReply()
            {
                Id = 3,
                Name = "小渣渣",
                Age = 1,
                IsVip = false
            });
        }
        public UserInfoService(ILogger<UserInfoService> logger)
        {
            _logger = logger;
        }

        public override Task<UserInfoReply> GetUserInfo(GetUserInfoRequest request, ServerCallContext context)
        {
            return Task.Run(() =>
            {
                return userInfoReplies.SingleOrDefault(x => x.Id == request.Id);
            });
        }
    }
}
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2020-12-7 21:06:17 | 显示全部楼层
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   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)
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2021-5-25 11:37:34 | 显示全部楼层
写的真好,赞赞赞
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2021-6-5 11:45:21 | 显示全部楼层
ASP.NET Core 中使用 gRPC 通信
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

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

Mail To:help@itsvse.com

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

GMT+8, 2024-3-29 16:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表