Grpc (二)

三个项目 GrpcClient GrpcService  Proto

GrpcClient  客户端

GrpcService  Grpc 服务承载端

Proto Grpc 声明端

 

 

 Proto 项目新建 文本文件 user.proto 点击该文本文件属性设置  Nuget 引用 包 Grpc.AspNetCore

 

 

该文件内容为

syntax = "proto3";
option csharp_namespace = "UserGRPCService";
package UserGRPC;
import "google/protobuf/empty.proto";
service UserGRPC {
  //单向流 客户端 请求 服务端 返回流
  rpc GetUser (google.protobuf.Empty) returns (stream UserEntityReply);
  //单向流 客户端 请求 服务端 客户端传入流 
  rpc UpDateUser(stream UpdateUserRequst) returns (UpdateUserReplay);
  //双向流
  rpc InsertUser(stream UserInsertRequst) returns(stream UserInsertReply);
  //双向非流 请求传值 返回值
  rpc GetUserOne(QueryUserName) returns(QueryUserReplay);
  //单向非流 不传值 返回值
  rpc GetUserAll(google.protobuf.Empty) returns(QueryUerAllReplay);  
}
message QueryUserName
{
   string UserName =1;
}
message QueryUserReplay
{
  UserEntity UserEntity =1;
}
message QueryUerAllReplay
{
  repeated UserEntity UserEntities =1;  
}
message UpdateUserRequst
{
  UserEntity user =1;
}
message UpdateUserReplay{
  bool isUpdateResult =1;
}
message UserInsertRequst{
  string message =1;
  UserEntity user =2;
}
message UserInsertReply{
  bool isReuslt=1;
}
message UserEntityReply {    
  UserEntity user = 1;
  string message = 2;
}
message UserEntity{
  string name =1;
  int32 age =2;
}

  

GrpcService  Grpc 服务承载端 引用 Proto 项目 实现 Proto 

using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using UserGRPCService;

namespace GrpcApplication1.Services
{
    public class UserService : UserGRPC.UserGRPCBase
    {
        public override async Task GetUser(Empty request, IServerStreamWriter<UserEntityReply> responseStream, ServerCallContext context)
        {
            await responseStream.WriteAsync(new UserEntityReply { Message = "成功", User = new UserEntity { Age = 1, Name = "看放到" } });
        }
        public override Task<QueryUerAllReplay> GetUserAll(Empty request, ServerCallContext context)
        {
            var queryUerAllReplay = new QueryUerAllReplay();
            queryUerAllReplay.UserEntities.Add(new UserEntity
            {
                Age = 12,
                Name = "kk"
            });
            return Task.FromResult<QueryUerAllReplay>(queryUerAllReplay);
        }
        public override Task<QueryUserReplay> GetUserOne(QueryUserName request, ServerCallContext context)
        {
            string name = request.UserName;
            var queryUserReplay = new QueryUserReplay();
            queryUserReplay.UserEntity = new UserEntity { Age = 12, Name = name };
            return Task.FromResult<QueryUserReplay>(queryUserReplay);
        }
        public override async Task InsertUser(IAsyncStreamReader<UserInsertRequst> requestStream, IServerStreamWriter<UserInsertReply> responseStream, ServerCallContext context)
        {
            var userInsertRequst = requestStream.ReadAllAsync();
            await Task.Run(async () =>
            {
                await foreach (var item in userInsertRequst)
                {
                    var user = item.User;
                    await Console.Out.WriteLineAsync($" 添加 用户 {user.Age},{user.Name}");
                }
            });
            await responseStream.WriteAsync(new UserInsertReply { IsReuslt = true });
        }
        public override async Task<UpdateUserReplay> UpDateUser(IAsyncStreamReader<UpdateUserRequst> requestStream, ServerCallContext context)
        {
            UpdateUserRequst userRequst = null;
            await Task.Run(async () =>
            {
                await foreach (var item in requestStream.ReadAllAsync())
                {
                    userRequst = item;
                    Console.WriteLine(userRequst);
                }
            });
            return new UpdateUserReplay { IsUpdateResult = true };
        }
    }
}

  

服务设置Grpc承载 以及 Kestrel http2协议

using GrpcApplication1.Services;

namespace GrpcApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            // Add services to the container.
            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            builder.Services.AddGrpc();
            builder.WebHost.ConfigureKestrel(options =>
            {
                //配置kestrel 
                options.ConfigureEndpointDefaults(listen =>
                {
                    //由于grpc使用 http2协议所以需要配置
                    listen.Protocols = 
                    Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
                    
                });
            });
            var app = builder.Build();
            app.MapGrpcService<UserService>();
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.UseHttpsRedirection();
            app.UseAuthorization();
            app.MapControllers();
            app.Run();
        }
    }
}

  

  

客户端 调用Grpc服务端

客户端配置

using Microsoft.Extensions.DependencyInjection;

namespace GrpcClientApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            // Add services to the container.
            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            builder.WebHost.ConfigureKestrel(options =>
            {
                options.ConfigureEndpointDefaults(listen =>
                {
                    listen.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2AndHttp3;

                });
            });
            builder.Services.AddUserGrpc(builder.Configuration.GetSection("Grpc"));
            var app = builder.Build();
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.UseHttpsRedirection();
            app.UseAuthorization();
            app.MapControllers();
            app.Run();
        }
    }
}

  

ServiceExtends 扩展

using GrpcClientApplication.GrpcClientServices;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollection
    {
        public static IServiceCollection AddUserGrpc(this IServiceCollection services, IConfigurationSection grpcSection)
        {
            string host = grpcSection.GetValue<string>("host");
            services.AddScoped<UserGrpcService>(sp =>
            {
                return new UserGrpcService(host);
            });
            return services;
        }
    }
}

  

GrpcClientServices 封装

using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Grpc.Net.Client;
using UserGRPCService;

namespace GrpcClientApplication.GrpcClientServices
{
    public class UserGrpcService : IDisposable
    {
        private readonly string _host;
        private readonly GrpcChannel _grpcChannel;
        private readonly UserGRPC.UserGRPCClient _userClient;
        public UserGrpcService(string host)
        {
            _host = host;
            _grpcChannel = GrpcChannel.ForAddress(host);
            _userClient = new UserGRPC.UserGRPCClient(_grpcChannel);
        }
        public async Task<UserEntity> GetUserAsync()
        {
            UserEntity userEntity = null;
            var call = _userClient.GetUser(new Google.Protobuf.WellKnownTypes.Empty());
            var users = call.ResponseStream.ReadAllAsync();
            await foreach (var user in users)
            {
                userEntity = user.User;
            }
            return userEntity;
        }
        public List<UserEntity> GetUserAll()
        {
            List<UserEntity> list = new List<UserEntity>();
            var usersAll = _userClient.GetUserAll(new Empty());
            var users = usersAll.UserEntities;
            users.ToList().ForEach(item =>
            {
                list.Add(new UserEntity
                {
                    Age = item.Age,
                    Name = item.Name,
                });
            });
            return list;
        }
        public UserEntity GetUserOne(string name)
        {
            var userOneReplay = _userClient.GetUserOne(new QueryUserName { UserName = name });
            return userOneReplay.UserEntity;
        }
        public async Task<bool> Insert(UserEntity user)
        {
            var call = _userClient.InsertUser();
            await call.RequestStream.WriteAsync(new UserInsertRequst { Message = "插入user", User = user });
            await call.RequestStream.CompleteAsync();
            var replay = call.ResponseStream.ReadAllAsync();
            bool isReuslt = false;
            await foreach (var item in replay)
            {
                isReuslt = item.IsReuslt;
            }
            return isReuslt;
        }
        public async Task<bool> Update(UserEntity user)
        {
            var call = _userClient.UpDateUser();
            await call.RequestStream.WriteAsync(new UpdateUserRequst { User = user });
            await call.RequestStream.CompleteAsync();
            return call.ResponseAsync.Result.IsUpdateResult;
        }
        public void Dispose()
        {
            _grpcChannel?.Dispose();
        }
    }
}

  

 

using Grpc.Core;
using Grpc.Net.Client;
using GrpcClientApplication.GrpcClientServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using UserGRPCService;

namespace GrpcClientApplication.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly UserGrpcService _userGrpcService;
        public UserController(UserGrpcService testDan)
        {
            _userGrpcService = testDan;
        }
        [HttpGet]
        public async Task<ActionResult<UserEntity>> Get()
        {
            return await _userGrpcService.GetUserAsync();
        }
        [HttpGet("GetUserAll")]
        public ActionResult<List<UserEntity>> GetUserAll()
        {
            return _userGrpcService.GetUserAll();
        }
        [HttpPut]
        public async Task<ActionResult<bool>> Update(UserEntity user)
        {
            return await _userGrpcService.Update(user);
        }

        [HttpPost]
        public async Task<ActionResult<bool>> Add(UserEntity user)
        {
            return await _userGrpcService.Insert(user);
        }
    }
}

  

总结 

注意这里  

流操作这里别忘了

await call.RequestStream.CompleteAsync();

 

posted on 2024-09-03 21:51  是水饺不是水饺  阅读(13)  评论(0)    收藏  举报

导航