|
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"。
添加 greet.proto
在 gRPC 客户端项目中创建 Protos 文件夹 。
从 gRPC Greeter 服务将 Protos\greet.proto 文件复制到 gRPC 客户端项目 。
编辑 gRPC-Client.csproj 项目文件,添加具有引用 greet.proto 文件的 <Protobuf> 元素的项组:
创建 Greeter 客户端
使用以下代码更新 gRPC 客户端的 Program.cs 文件 :
实例化 GrpcChannel,使其包含用于创建到 gRPC 服务的连接的信息。
使用 GrpcChannel 构造 Greeter 客户端。
Greeter 客户端会调用 SayHello 方法。 随即显示 SayHello 调用的结果。
创建自己的 .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
请按任意键继续. . .
当返回值为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
请按任意键继续. . .
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首
|