Asp.net Core 3.0 使用GRPC

asp.net core 3.0使用grpc

首先新建一个webapi项目,引入nuget包,这个包含所需要的包以及grpc工具包

grpc-1.png

新建存放proto文件的Grpc文件夹,将proto文件放到该目录下

grpc-2.png
然后在项目的csproj文件中引入该文件夹
grpc-3.png
最后在start.up中进行依赖注入

services.AddGrpcClient<ProjectAreaer.ProjectAreaerClient>(o =>
            {
                o.Address = new Uri("");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
                return handler;
            });

最后在聚合层(控制层)引入使用

private readonly ProjectAreaer.ProjectAreaerClient ProjectAreaClient;
        public WisdomToiletScreenController(ProjectAreaer.ProjectAreaerClient ProjectAreaClient)
        {
            this.ProjectAreaClient = ProjectAreaClient;
        }
public override async Task SayHellos(HelloRequest request,
        IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
    {
        // Forward the call on to the greeter service
        using (var call = _client.SayHellos(request))
        {
            await foreach (var response in call.ResponseStream.ReadAllAsync())
            {
                await responseStream.WriteAsync(response);
            }
        }
    }

关于一些使用gRPC的测试

var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = new Greeter.GreeterClient(channel);
//忽略ssl证书
var channel = GrpcChannel.ForAddress(HYD_GRPCSERVICES_CORE, new GrpcChannelOptions
            {
                HttpClient = new HttpClient(new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                })
            });
            var client = new CoreDataQueryer.CoreDataQueryerClient(channel);

创建一个客户端,客户端会绑定一个端口,当使用同一个客户端发送请求时,端口是一样的,并且不会有端口占用的问题。

gRPC Interceptor

public virtual TResponse BlockingUnaryCall<TRequest, TResponse>();
public virtual AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>();
public virtual AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>();
public virtual AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>();
public virtual AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>();
public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>();
public virtual Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>();
public virtual Task ServerStreamingServerHandler<TRequest, TResponse>();
public virtual Task DuplexStreamingServerHandler<TRequest, TResponse>();
方法名称作用
BlockingUnaryCall拦截阻塞调用
AsyncUnaryCall拦截异步调用
AsyncServerStreamingCall拦截异步服务端流调用
AsyncClientStreamingCall拦截异步客户端流调用
AsyncDuplexStreamingCall拦截异步双向流调用
UnaryServerHandler用于拦截和传入普通调用服务器端处理程序
ClientStreamingServerHandler用于拦截客户端流调用的服务器端处理程序
ServerStreamingServerHandler用于拦截服务端流调用的服务器端处理程序
DuplexStreamingServerHandler用于拦截双向流调用的服务器端处理程序

在客户端项目新建一个类,命名为 ClientLoggerInterceptor,继承拦截器基类 Interceptor

我们在前面使用的Demo,定义了撸猫服务,其中 SuckingCatAsync方法为异步调用,所以我们重写拦截器的 AsyncUnaryCall方法

public class ClientLoggerInterceptor:Interceptor
{
  public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
    TRequest request,
    ClientInterceptorContext<TRequest, TResponse> context,
    AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
  {
    LogCall(context.Method);
    return continuation(request, context);
  }
  private void LogCall<TRequest, TResponse>(Method<TRequest, TResponse> method)
    where TRequest : class
    where TResponse : class
  {
    var initialColor = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
    Console.ForegroundColor = initialColor;
  }
}
var channel = GrpcChannel.ForAddress("https://localhost:5001");
//注册拦截器
var invoker = channel.Intercept(new ClientLoggerInterceptor());
var catClient = new LuCat.LuCatClient(invoker);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("调用撸猫服务:"+ catReply.Message);

在服务端项目新建一个类,命名为 ServerLoggerInterceptor,继承拦截器基类 Interceptor

我们在服务端需要实现的方法是 UnaryServerHandler

public class ServerLoggerInterceptor: Interceptor
{
  private readonly ILogger<ServerLoggerInterceptor> _logger;
  public ServerLoggerInterceptor(ILogger<ServerLoggerInterceptor> logger)
  {
    _logger = logger;
  }
  public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
    TRequest request,
    ServerCallContext context,
    UnaryServerMethod<TRequest, TResponse> continuation)
  {
    LogCall<TRequest, TResponse>(MethodType.Unary, context);
    return continuation(request, context);
  }
  private void LogCall<TRequest, TResponse>(MethodType methodType, ServerCallContext context)
    where TRequest : class
    where TResponse : class
  {
    _logger.LogWarning($"Starting call. Type: {methodType}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
  }
}

startup里面注册拦截器:

public void ConfigureServices(IServiceCollection services)
{
  services.AddGrpc(options =>
  {
    options.Interceptors.Add<ServerLoggerInterceptor>();
  });
}

远程连接proto文件

<ItemGroup>
    <Protobuf Include="..\..\StreamTest\StreamTest\Protos\LuCat.proto" GrpcServices="Client">
      <Link>Protos\LuCat.proto</Link>
    </Protobuf>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Client">
      <SourceUri>http://192.168.1.31:9999/files/protos/greet.proto</SourceUri>
    </Protobuf>
  </ItemGroup>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值