GRPC与.net core

系列章节

GRPC与.net core

GRPC截止时间与元数据

GRPC与netcore Identity

GRPC与netcore IdentityServer4

概述

GRPC的数据交互模式有:

1.单项RPC,最简单的数据交换方式,客户端发出单个请求,收到单个响应

2.服务端流式RPC,是在服务端收到客户端的请求之后,返回一个应答流,客户端收到流之后处理。

3.客户端流式RPC,与单项类似,但客户端发送的是流式RPC

4.双向流式RPC,调用由客户端调用方法来初始化,而服务端则接收到客户端的元数据,方法名和截止时间。服务端可以选择发送回它的初始元数据或等待客户端发送请求。下一步怎样发展取决于应用,因为客户端和服务端能在任意顺序上读写 - 这些流的操作是完全独立的。例如服务端可以一直等直到它接收到所有客户端的消息才写应答,或者服务端和客户端可以像"乒乓球"一样:服务端后得到一个请求就回送一个应答,接着客户端根据应答来发送另一个请求,以此类推。

单项RPC较简单不做示例了。

首先在vs2019中net core3.0中新建GRPC项目。然后定义响应的proto文件,根据proto文件生成响应的服务端与客户端代码。

1.服务端流式RPC

1.定义 protofile

syntax = "proto3";

option csharp_namespace = "GrpcGreeter";

package Greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc GetStreamContent (StreamRequest) returns (stream StreamContent) {}
}

// The request message containing the user‘s name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}
message StreamRequest {
  string fileName = 1;
}
message StreamContent {
  bytes content = 1;
}

2.实现服务端Service

重新生成项目,然后实现GetStreamContent,简单的读取文件内容,并将内容返回给Client

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Google.Protobuf;
using Grpc.Core;

namespace GrpcGreeter
{
    public class GreeterService : Greeter.GreeterBase
    {
        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }

        public override Task GetStreamContent(StreamRequest request, IServerStreamWriter<StreamContent> responseStream, ServerCallContext context)
        {
            return Task.Run(async () =>
             {
                 using (var fs = File.Open(request.FileName, FileMode.Open)) // 从 request 中读取文件名并打开文件流
                 {
                     var remainingLength = fs.Length; // 剩余长度
                     var buff = new byte[1048576]; // 缓冲区,这里我们设置为 1 Mb
                     while (remainingLength > 0) // 若未读完则继续读取
                     {
                         var len = await fs.ReadAsync(buff); // 异步从文件中读取数据到缓冲区中
                         remainingLength -= len; // 剩余长度减去刚才实际读取的长度

                         // 向流中写入我们刚刚读取的数据
                         await responseStream.WriteAsync(new StreamContent
                         {
                             Content = ByteString.CopyFrom(buff, 0, len)
                         });
                     }
                 }
             });
        }
    }
}

3.实现Client

新建一个netcore 3.0的Console项目,并引入Nuget包

Install-Package Grpc.Net.Client -Version 0.1.22-pre1
Install-Package Google.Protobuf -Version 3.8.0
Install-Package Grpc.Tools -Version 1.22.0

编辑项目文件,修改如下节点

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

重新生成项目,Client端主要实现发送请求,请求是一个服务器端的文件路径。然后实现接收服务端的流,并保存到Client本地。

using Grpc.Net.Client;
using GrpcGreeter;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;

namespace GrpcGreeterClient
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            AppContext.SetSwitch(
                "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport",
                true);
            var httpClient = new HttpClient();
            // The port number(50051) must match the port of the gRPC server.
            httpClient.BaseAddress = new Uri("http://localhost:50051");
            var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
            //
            var reply = await client.SayHelloAsync(
                              new HelloRequest { Name = "GreeterClient" });
            Console.WriteLine("Greeting: " + reply.Message);
            Console.ReadKey();

            //
            var result = client.GetStreamContent(new StreamRequest { FileName = @"D:\Docs.zip" });  //发送请求
            var iter = result.ResponseStream;
            using (var fs = new FileStream(@"D:\Docs2.zip", FileMode.Create)) // 新建一个文件流用于存放我们获取到数据
            {
                while (await iter.MoveNext()) // 迭代
                {
                    iter.Current.Content.WriteTo(fs); // 将数据写入到文件流中
                }
            }

            Console.ReadKey();
        }
    }
}

文件生成成功

2.客户端流式RPC

1.定义 protofile

syntax = "proto3";

option csharp_namespace = "GRPC.TEST";

package Greet;

// The greeting service definition.
service Greeter {
  rpc getResult (stream Value) returns (Result) {}
}

//定义Value消息类型,用于客户端消息
message Value {
    int32 value = 1;
}
//定义Result消息类型,包含总和,数字数量和平均值,用于服务端消息返回
message Result {
    int32 sum = 1;
    int32 cnt = 2;
    double avg = 3;
}

2.实现服务端Service

重新生成项目,并实现如下

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Google.Protobuf;
using Grpc.Core;

namespace GRPC.TEST
{
    public class GreeterService : Greeter.GreeterBase
    {
        public override async Task<Result> getResult(IAsyncStreamReader<Value> requestStream, ServerCallContext context)
        {
            while (await requestStream.MoveNext())
            {
                var point = requestStream.Current;
            }
            return new Result { Sum = 1 };
        }
    }
}

3.实现Client

新建一个netcore 3.0的Console项目,并引入Nuget包,安装nuget包与其他操作同上一个例子,实现代码如下

using Grpc.Net.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;

namespace GRPC.TEST.CLIENT
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            AppContext.SetSwitch(
                 "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport",
                 true);
            var httpClient = new HttpClient();
            // The port number(50051) must match the port of the gRPC server.
            httpClient.BaseAddress = new Uri("http://localhost:50051");
            var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
            using (var call = client.getResult())
            {
                await call.RequestStream.WriteAsync(new Value { Value_ = 1 });
                await call.RequestStream.CompleteAsync();
                var response = await call.ResponseAsync;
            }

            Console.ReadKey();
        }
    }
}

3.双向流式RPC

1.定义proto

syntax = "proto3";

option csharp_namespace = "GRPC.TEST";

package Greet;

// The greeting service definition.
service Greeter {
  rpc getResult (stream Value) returns (stream Result) {}
}

//定义Value消息类型,用于客户端消息
message Value {
    int32 value = 1;
}
//定义Result消息类型,包含总和,数字数量和平均值,用于服务端消息返回
message Result {
    int32 sum = 1;
    int32 cnt = 2;
    double avg = 3;
}

2.服务端实现

重新生成项目,并实现如下

public override async Task getResult(IAsyncStreamReader<Value> requestStream, IServerStreamWriter<Result> responseStream, ServerCallContext context)
        {
            while (await requestStream.MoveNext())
            {
                var note = requestStream.Current;

                await responseStream.WriteAsync(new Result { Sum = 100 });
            }
        }

3.客户端代码

新建一个netcore 3.0的Console项目,并引入Nuget包,安装nuget包与其他操作同上一个例子,实现代码如下

using Grpc.Net.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

namespace GRPC.TEST.CLIENT
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            AppContext.SetSwitch(
       "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport",
       true);
            var httpClient = new HttpClient();
            // The port number(50051) must match the port of the gRPC server.
            httpClient.BaseAddress = new Uri("http://localhost:50051");
            var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
            using (var call = client.getResult())
            {
                var responseReaderTask = Task.Run(async () =>
                {
                    while (await call.ResponseStream.MoveNext())
                    {
                        var note = call.ResponseStream.Current;
                        Console.WriteLine("Received " + note);
                    }
                });

                await call.RequestStream.WriteAsync(new Value { Value_ = 12 });
                await call.RequestStream.CompleteAsync();
                await responseReaderTask;
            }

            Console.ReadKey();
        }
    }
}

至此,GRPC的几种数据交互分享完毕

原文地址:https://www.cnblogs.com/chenyishi/p/11143375.html

时间: 2024-08-06 14:06:35

GRPC与.net core的相关文章

grpc asp.net core 集成时一些配置的说明

一  什么是grpc google出了一款分布式通讯框架:grpc.我想这也不是新的东西了,在13年的一个项目中,用在了数据层和业务端之间的通讯上,当时并没有觉得怎么样,因为wcf很轻松的也可以可以实现哪些功能.但是想在想一想,确实在某些场合,grpc比wcf要更好一点.第一就是比wcf要轻量级的多,第二,跨平台,他出了一款协议Protocol Buffers,来定义接口,然后使用工具去生成不同 的语言代码.而wcf我们也知道,跨平台使用soap协议,基于http,坏处就是慢.而基于tcp或者命

gRPC:在ASP.NET Core上的简单实现

gRPC是Google基于HTTP/2和protobuf推出的一款也是当下热门的开源RPC(Remote Procedure Call)框架.可在程序或者服务之间进行高性能低带宽的通信,并且支持身份认证.日志系统等等需要用到的功能.在微服务作为主流的时代,各个服务之间的通信也是一个亟需解决的问题.在ASP.NET Core 3.x下,gRPC也是微软传统RPC框架WCF的有效替代. 使用gRPC,可以让客户端像调用本地方法一样地去调用服务端中的方法.gRPC是一种合约优先的API开发模式,就是我

【译】gRPC vs HTTP APIs

本文翻译自 ASP.NET Blog | gRPC vs HTTP APIs,作者 James,译者 Edison Zhou. 写在开头 现在,ASP.NET Core使开发人员可以构建gRPC服务.gRPC是一个远程过程调用框架,专注于高性能和开发人员的生产力.ASP.NET Core 3.0中集成了gRPC,因此您可以结合使用现有的ASP.NET Core日志系统,配置系统,身份验证模式来构建新的gRPC服务. 这篇文章将gRPC与基于JSON的HTTP API进行了比较,讨论了gRPC的优

Dapr Pub/Sub 集成 RabbitMQ 、Golang、Java、DotNet Core

前置条件: <Dapr运用> <Dapr 运用之 Java gRPC 调用篇> <Dapr 运用之集成 Asp.Net Core Grpc 调用篇> 搭建 RabbitMQ Docker 搭建 RabbitMQ 服务 docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management 创建 rabbiqmq.yaml apiVers

.net core 用grpc实现微服务

GRPC?是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用GRPC框架. ? ? 软件版本 .net core :1.0.1 GRPC:1.0.1-pre1 ? ? ? ? 1.定义服务 使用proto3语法定义一个服务,主要测试package.import.常用类型的测试, proto3语法: https://developers.google.com/p

gRpc NET Core

NET Core下使用gRpc公开服务(SSL/TLS) 一.前言 前一阵子关于.NET的各大公众号都发表了关于gRpc的消息,而随之而来的就是一波关于.NET Core下如何使用的教程,但是在这众多的教程中基本都是泛泛而谈,难以实际在实际环境中使用,而该篇教程以gRpc为主,但是使用了其SSL/TLS,这样更加符合实际的生产使用,期间也会配套的讲解Docker.openssl等. 二.服务端 a.准备工作 笔者的项目分为三个部分分别如下所示: Sino.GrpcService.Host(控制台

.NET Core下使用gRpc公开服务(SSL/TLS)

一.前言 前一阵子关于.NET的各大公众号都发表了关于gRpc的消息,而随之而来的就是一波关于.NET Core下如何使用的教程,但是在这众多的教程中基本都是泛泛而谈,难以实际在实际环境中使用,而该篇教程以gRpc为主,但是使用了其SSL/TLS,这样更加符合实际的生产使用,期间也会配套的讲解Docker.openssl等. 二.服务端 a.准备工作 笔者的项目分为三个部分分别如下所示: Sino.GrpcService.Host(控制台):宿主程序 Sino.GrpcService.Impl(

.net core grpc 实现通信

现在系统都服务化,.net core 实现服务化的方式有很多,我们通过grpc实现客户端.服务端通信. grpc是google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架,使用HTTP/2协议并用ProtoBuf作为序列化工具,提供跨语言.跨平台支持.下面以.net core演示如何使用grpc框架实现通信. 软件版本 .net core:2.0 grpc:1.11.0 项目结构 InstallGrpc .net framework类库 只为得到生成协议代

.net core 3.0中可以使用gRPC了

今天发现.net core下有gRPC模板了,这个可是补全了.net core下高性能RPC框架缺失这一大短板了. 使用模板创建了工程后,发现连客户端的示例也创建了. 更加给力的是,IDE是能直接识别proto文件的,后台后自动将其编译为相应的c#代码,这可是解决了手动编译idl的一大痛点了.除了gRPC基础外,框架本身的使用也是比较简单的,另外,由于目前还是一个预览版,这里我不做更多的介绍了.相信这些对于有高性能RPC需求的场景来说,系统集成gRPC无疑是方便不少的. 原文地址:https:/