ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

gRPC之Server Streaming

2022-02-07 18:04:05  阅读:435  来源: 互联网

标签:gRPC server Streaming client new dotnet using Server


gRPC是什么?
简单来说,gRPC是google开发的一款开源RPC通讯框架,支持request/reponse模式、client stream模式、server stream模式和双向模式。
(双向(bi-directional)模式,感觉和传统的web socket很像)

现实场景中我们经常会遇到client端的一个请求,会在server端执行多个长耗时的任务,client端只能等待server全部完成。如果我们要在client实时端显示server端的进度,该如何实现呢? 本文将使用.net core+gRPC的server stream给出实现代码。

vscode安装语法扩展

1) .net core创建server端gRPC服务
dotnet new grpc -o server
cd server
dotnet new gitignore

添加gRPC定义文件:charging.proto

syntax = "proto3";

option csharp_namespace = "server";

package charging;

service Charging {
    rpc ReportProgress (ProgressRequest) returns (stream ProgressResponse);
}

message ProgressRequest {
    bool continue = 1;
}

message ProgressResponse {
    int32 percentage = 1;
}

打开server.csproj,加入以下配置

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

运行dotnet build,在obj文件夹下生成Charging代码

Services文件夹下添加一个新的服务:ChargingService.cs

using System;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;

namespace server
{
    public class ChargingService : Charging.ChargingBase
    {
        public override async Task ReportProgress(
              ProgressRequest request, 
              IServerStreamWriter<ProgressResponse> responseStream, 
              ServerCallContext context)
        {
            int percentage = 0;           
            try
            {                
                while (!context.CancellationToken.IsCancellationRequested)
                {
                    Thread.Sleep(5000);
                    percentage += 20;
                    await responseStream.WriteAsync(new ProgressResponse { 
                     Percentage = percentage
                    });
                }
            }
            catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
            {
                Console.WriteLine("Operation Cancelled.");
            }

            Console.WriteLine("Processing Complete.");
        }
    }
}

打开startup.cs,加入

endpoints.MapGrpcService<ChargingService>();

建立Client端
参考: https://docs.microsoft.com/en-us/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore-6.0&tabs=visual-studio-code

dotnet new console -o client
cd client

dotnet add client.csproj package Grpc.Net.Client
dotnet add client.csproj package Google.Protobuf
dotnet add client.csproj package Grpc.Tools

把server端的proto文件copy到client端,修改namespace

option csharp_namespace = "client";

csproj加入Protobuf定义

<ItemGroup>
    <Protobuf Include="Protos\charging.proto" GrpcServices="Client" />
  </ItemGroup>

dotnet build 生成ChargingClient对象
最后program.cs加入以下代码

using System;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using client;

namespace client
{
    class Program
    {
        static void Main(string[] args)
        {
            GetServerProgress();
        }

        static void GetServerProgress()
        {
            using var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = new client.Charging.ChargingClient(channel); //GrpcGreeterClient.Greeter.GreeterClient(channel);
            var request = new client.ProgressRequest { Continue = true };
            var cancellationToken = new CancellationTokenSource();

            try
            {
                AsyncServerStreamingCall<ProgressResponse> response = 
                    client.ReportProgress(request, 
                      cancellationToken: cancellationToken.Token);

                // loop through each object from the ResponseStream
                while (response.ResponseStream.MoveNext().Result)
                {
                    // fetch the object currently pointed
                    var current = response.ResponseStream.Current;
                    if(current.Percentage >= 100)
                    {
                        cancellationToken.Cancel();
                    }

                    // print it
                    Console.WriteLine($"{current.Percentage}%");
                }
            }
            catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
            {
                Console.WriteLine("Operation Cancelled.");
            }

            Console.ReadLine();
        }
    }
}

server端dotnet run,
Client端dotnet run

只是这种模式必须通过Client发送CalcellationToken来结束,而结束时会引发exception。 还没发现有更优雅的结束方式。

代码:
https://github.com/992990831/gRPC

参考:
https://docs.microsoft.com/en-us/aspnet/core/grpc/services?view=aspnetcore-6.0
https://referbruv.com/blog/posts/implementing-stream-based-communication-with-grpc-and-aspnet-core

标签:gRPC,server,Streaming,client,new,dotnet,using,Server
来源: https://www.cnblogs.com/Andy1982/p/15865945.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有