Install-Package Google.Protobuf Install-Package Grpc.AspNetCore Install-Package Grpc.Net.Client Install-Package Grpc.Tools
//Add new file book.proto syntax="proto3";option csharp_namespace="GrpcBookServer";package book;message BookProto{int64 id=1;string name=2;string isbn=3;string abstract=4;string author=5;string comment=6;string content=7;string summary=8;string title=9;string topic=10; }message GetBooksListRequest{int32 cnt=1; }message GetBooksListResponse{repeated BookProto books=1; }service BookService {rpc GetBooksList(GetBooksListRequest) returns (GetBooksListResponse); }
Add new file book.proto and set properties of book.proto Build action as Protobuf compiler both in producer and consumer app.

//Producer //D:\C\ConsoleApp19\ConsoleApp19\Program.cs using Google.Protobuf; using Google.Protobuf.Collections; using Grpc.Core; using GrpcBookServer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.DependencyInjection; using System.Runtime.Serialization; using System.Threading.Tasks.Dataflow;namespace ConsoleApp19 {internal class Program{static void Main(string[] args){GrpcDemo();Console.ReadLine();}static async Task GrpcDemo(){var builder = WebApplication.CreateBuilder();builder.WebHost.ConfigureKestrel(serviceOptions =>{serviceOptions.ListenLocalhost(8888, x => x.Protocols = HttpProtocols.Http2);});builder.Services.AddGrpc(options =>{options.MaxSendMessageSize = null;options.MaxSendMessageSize = null;}); var app = builder.Build();app.MapGrpcService<BookServiceImpl>();Console.WriteLine($"{DateTime.Now},the grpc service started at http://localhost:8888");await app.RunAsync("http://localhost:8888");}}public class BookServiceImpl:BookService.BookServiceBase{private static long id = 0;private static long GetIncrementId(){return Interlocked.Increment(ref id);}public List<Book> GetBooksList(int cnt=1000000){var bksList = new List<Book>();for(int i=0;i<cnt;i++){var a = GetIncrementId();bksList.Add(new Book(){Id=a,Name=$"Name_{a}",ISBN=$"ISBN_{a}_{Guid.NewGuid():N}",Abstract=$"Abstract_{a}",Author=$"Author_{a}",Comment=$"Comment_{a}",Content=$"Content_{a}",Summary=$"Summary_{a}",Title=$"Title_{a}",Topic=$"Topic_{a}"});}return bksList;}public override Task<GetBooksListResponse> GetBooksList(GetBooksListRequest request, ServerCallContext context){var count = request.Cnt is 0 ? 1000000 : request.Cnt;var bksList = GetBooksList(count);var response=new GetBooksListResponse();response.Books.AddRange(bksList.ToProtoList());return Task.FromResult(response);}}public static class BookMapper{public static BookProto ToProtoBook(this Book bk){return new BookProto{Id = bk.Id,Name = bk.Name ?? "",Isbn = bk.ISBN ?? "",Author=bk.Author??"",Abstract = bk.Abstract ?? "",Comment = bk.Comment ?? "",Content = bk.Content ?? "",Summary = bk.Summary ?? "",Title = bk.Title ?? "",Topic = bk.Topic ?? ""};}public static Book ToModel(this BookProto pt){return new Book{Id = pt.Id,Name = pt.Name,ISBN = pt.Isbn,Abstract = pt.Abstract,Author = pt.Author,Comment=pt.Comment,Content=pt.Content,Summary=pt.Summary,Title=pt.Title,Topic=pt.Topic};}public static List<Book> ToModelList(this RepeatedField<BookProto> list){return list.Select(ToModel).ToList();}public static List<BookProto> ToProtoList(this List<Book> list){return list.Select(ToProtoBook).ToList();}}public class Book{public long Id { get; set; }public string Name { get; set; }public string ISBN { get; set; }public string Abstract { get; set; }public string Author { get; set; }public string Comment { get; set; }public string Content { get; set; }public string Summary { get; set; }public string Title { get; set; }public string Topic { get; set; }}}
//Consumer
//D:\C\ConsoleApp20\ConsoleApp20\Program.cs using Grpc.Net.Client; using GrpcBookServer;namespace ConsoleApp20 {internal class Program{private static string requestUrl = "http://localhost:8888";static GrpcChannel channel;static BookService.BookServiceClient client;static System.Timers.Timer tmr;static void Main(string[] args){channel = GrpcChannel.ForAddress(requestUrl, new GrpcChannelOptions{MaxSendMessageSize =null,MaxReceiveMessageSize=null});client = new BookService.BookServiceClient(channel);Task.Run(async () =>{await ConsumeGrpcServiceAsync();});tmr = new System.Timers.Timer();tmr.Interval = 3000;tmr.Elapsed += async (s, e) =>{await ConsumeGrpcServiceAsync();};tmr.Start();Console.ReadLine();}static async Task ConsumeGrpcServiceAsync(int cnt= 1000000){var resp = await client.GetBooksListAsync(new GetBooksListRequest { Cnt = cnt });var books = resp.Books;Console.WriteLine($"{DateTime.Now},receive from server books count:{books.Count},First Id:{books.FirstOrDefault()?.Id},Last Id:{books.LastOrDefault()?.Id}");}} }

