标签:优点 remove namespace use result pac option 允许 http请求
gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架。
gRPC 的主要优点是:
这些优点使 gRPC 适用于:
以上来自微软的文档:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/index?view=aspnetcore-3.0
个人理解:
补充:
Restful是一种架构风格,关注的是资源。
通过每次http请求把资源拿过来,但资源怎么用是客户端的事情。
gRpc是rpc的一个实现框架,因此关注其中的rpc远程过程调用。
意思是在客户端调用服务器方法就像调用本地方法一样。如果这样做,那么服务器就必须要有相应的处理的方法(参数和返回值)。
grpc在proto文件中定义了方法名和返回值,在各种语言中,我们只需要在服务器和客户端实现相应的方法即可。
以下Demo主要体现了服务端与客户端以流式RPC的方式,并对比webapi的方式。
*必须使用http/2,因此需要在服务器上监听端口设置。
//支持无tls的http/2。 webBuilder.ConfigureKestrel(options => { options.ListenLocalhost(5000, o => o.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2); });
*客户端需要设置
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
C#自动生成代码,客户端需要从nuget安装:
Google.Protobuf
Grpc.Core
Grpc.Net.ClientFactory
Grpc.Tools
项目文件:
<ItemGroup>
<Protobuf Include="Protos\Duplicate.proto" GrpcServices="Client">
</Protobuf>
</ItemGroup>
服务的需要
Grpc.Tools
Grpc.AspNetCore.Server
Grpc.AspNetCore
项目文件:
<ItemGroup>
<Protobuf Include="Protos/Duplicate.proto" GrpcServices="Server" />
</ItemGroup>
该Demo模拟了一个判重的服务器和客户端。
public interface IDuplicate { /// <summary> /// 将标签进入判重。 /// </summary> /// <param name="tag">标签。</param> /// <returns>保存成功后将返回一个值。</returns> bool EntryDuplicate(string tag); /// <summary> /// 判断标签是否已经存在。 /// </summary> /// <param name="tag">标签。</param> /// <returns>如果标签存在则返回true。</returns> bool DuplicateCheck(string tag); /// <summary> /// 删除一条标签。 /// </summary> /// <param name="tag">标签。</param> /// <returns>返回结果。</returns> bool RemoveItem(string tag); }
Proto配置:
syntax = "proto3"; // 命名空间。 option csharp_namespace = "GrpcServer.Protos"; package Duplicate; service Duplicater{ // 进队列接口。 rpc EntryDuplicate(stream EntryRequset) returns (stream EntryResponse); // 判重接口。 rpc DuplicateCheck(stream DuplicateCheckRequset) returns (stream DuplicateCheckResponse); } // 进队列请求。 message EntryRequset{ // tag=1,表示在传输过程中,此数据的名字就是1。 string tag=1; } // 进队后响应。 message EntryResponse{ bool result=1; string msg=2; } // 判重请求。 message DuplicateCheckRequset{ string tag=1; } // 判重后响应。 message DuplicateCheckResponse{ bool result=1; }
Demo中主要实现了入判重的方法。
/// <summary> /// 入判重。 /// </summary> /// <param name="requestStream">请求流。</param> /// <param name="responseStream">响应流。</param> /// <param name="context">上下文。</param> /// <returns></returns> public override async Task EntryDuplicate(IAsyncStreamReader<EntryRequset> requestStream, IServerStreamWriter<EntryResponse> responseStream, ServerCallContext context) { while (await requestStream.MoveNext()) { var result = _memoryDuplicate.EntryDuplicate(requestStream.Current.Tag); var msg = string.Empty; if (result) msg = $"{requestStream.Current.Tag} 入判重成功。"; else msg = $"{requestStream.Current.Tag} 入判重失败,已有重复的数据"; _logger.LogInformation(msg); await responseStream.WriteAsync(new EntryResponse { Result = result, Msg = msg }); } _logger.LogInformation("本次请求已完成"); }
由客户端告知流传输结束,然后释放连接:
var token = new CancellationToken(); var response = Task.Run(async () => { while (await entry.ResponseStream.MoveNext(token)) { if (entry.ResponseStream.Current.Result) Console.WriteLine($"{entry.ResponseStream.Current.Msg}"); else Console.WriteLine($"{entry.ResponseStream.Current.Msg}入判重失败。"); } }); for (int i = 0; i < length; i++) { SpinWait.SpinUntil(() => false, 200); var msg = random.Next(0, 2000).ToString(); await entry.RequestStream.WriteAsync(new EntryRequset { Tag = msg }); } Console.WriteLine("等待释放链接。"); await entry.RequestStream.CompleteAsync(); entry.Dispose(); Console.WriteLine("完成");
Grpc:
WebApi:
github地址:https://github.com/yeqifeng2288/GrpcDemo
标签:优点 remove namespace use result pac option 允许 http请求
原文地址:https://www.cnblogs.com/yeqifeng2288/p/11762579.html