5.NET中GRPC服务端快速入门,服务端与客户端

gRPC是一个现代的开源高性能远程过程调用(RPC)框架,可以在任何环境中运行。它可以有效地连接数据中心内和跨数据中心的服务,支持负载均衡、跟踪、健康检查和身份验证。它也适用于分布式计算,将设备、移动应用程序和浏览器连接到后端服务

1.创建一个空项目GrpcServer

安装包:Grpc.AspNetCore

添加GRPC服务,Program.cs里面

builder.Services.AddGrpc();

设置GRPC为http2.0,Program.cs里面

builder.WebHost.UseKestrel(p =>
{
    p.ConfigureEndpointDefaults(opt =>
    {
        opt.Protocols = HttpProtocols.Http2;
    });
});

也可以在配置文件内去设置,appsettings文件里

 "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }

 

2.创建一个文件夹Apis里面存放服务

接口:IUserService

public interface IUserService
{
    List<UserInfo> GetUsers();
}

实现:UserServiceImpl

public class UserServiceImpl:IUserService
{
    public List<UserInfo> GetUsers()
    {
        return new()
        {
            new(){Id = 1,NickName = "张三"},
            new(){Id = 2,NickName = "李四"},
            new(){Id = 3,NickName = "王五"},
            new(){Id = 4,NickName = "赵交"}
        };
    }
}

 

3.创建Protos文件夹,里面中定义服务和消息

创建一个文件:user.proto

syntax="proto3"; //声明语法为proto3
option csharp_namespace = "GrpcServer";//声明命名空间,一般为项目的名称
package user;//定义包

//请求参数,1,2,....表示参数的下标。nick_name编译后NickName
message UserDtoGrpc{
  int32 id=1; // Id
  string nick_name=2; // NickName
}

// 入参对象,请求参数,没有可以不写,如果有参数和上面写法一样。
message UserReuqest{
  
}

// 出参对象,返回对象,为list集合,repeated表示一个集合。
message UserResponse{
  repeated UserDtoGrpc user_list=1;
}

//里面定义方法
service UserService{
  // 声明了需要暴露的Grpc方法
   rpc GetUsers(UserReuqest) returns (UserResponse);
}

 

编辑GrpcServer.csproj文件,将user.proto暴露出来生成C#的资产。

<ItemGroup>
      <PackageReference Include="Grpc.AspNetCore" Version="2.56.0" />
        <ProtoBuf Include="Protos/user.proto" GrpcService="Server" />
    </ItemGroup>

最后重新生成项目

4.创建一个文件夹Services,来存放GRPC的服务。

在Program.cs里面注册

builder.Services.AddTransient<IUserService, UserServiceImpl>();

 

添加一个类UserServiceGrpc继承的UserService其实就是user.proto文件里面的UserService。

重写的GetUsers方法其实就是UserServiceBase的GetUsers方法。

public class UserServiceGrpc:UserService.UserServiceBase
{
    private readonly IUserService _userService;

    public UserServiceGrpc(IUserService userService)
    {
        _userService = userService;
    }

    public override Task<UserResponse> GetUsers(UserReuqest request, ServerCallContext context)
    {
        UserResponse response = new();

        var userInfos = _userService.GetUsers();
        foreach (var userInfo in userInfos)
        {
            response.UserList.Add(new UserDtoGrpc()
            {
                Id = userInfo.Id,
                NickName = userInfo.NickName
            });
        }

        return Task.FromResult(response);
    }
}

添加到管道里面去

app.MapGrpcService<UserServiceGrpc>();

 

 

5.创建一个客户端空项目GrpcClient

安装包:

Swashbuckle.AspNetCore

Grpc.Net.Client

Grpc.Tools

Google.Protobuf

 

Program.cs里面配置

builder.Services.AddControllers();
builder.Services.AddSwaggerGen();

app.UseSwagger();
app.UseSwaggerUI();
app.UseRouting();

app.MapControllers();

launchSettings.json里面配置Swagger页面。

 "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "http://localhost:5290",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }

 

创建一个文件夹Protos,添加user.proto文件

syntax="proto3";
option csharp_namespace = "GrpcClient";
package user;


message UserDtoGrpc{
  int32 id=1; // Id
  string nick_name=2; // NickName
}

// 入参对象
message UserReuqest{
  
}

// 出参对象
message UserResponse{
  repeated UserDtoGrpc user_list=1;
}


service UserService{
  // 声明了需要暴露的Grpc方法
   rpc GetUsers(UserReuqest) returns (UserResponse);
}

 

生成后注意GrpcClient.csproj文件内是否有生成

 <Protobuf Include="Protos\user.proto">
      <GrpcServices>Client</GrpcServices>
      <Access>Public</Access>
      <ProtoCompile>True</ProtoCompile>
      <CompileOutputs>True</CompileOutputs>
      <OutputDir>obj\Debug\net7.0\</OutputDir>
      <Generator>MSBuild:Compile</Generator>
    </Protobuf>

 

添加控制器文件夹Controllers

[ApiController]
    [Route("[controller]/[action]")]
    public class UserController : ControllerBase
    {
        private readonly UserService.UserServiceClient _userServiceClient;

        public UserController(UserService.UserServiceClient userServiceClient)
        {
            _userServiceClient = userServiceClient;
        }

        [HttpGet]
        public IActionResult Get()
        {
             // 创建通信频道
             var channel = GrpcChannel.ForAddress("http://localhost:5023");
             // 创建客户端
             var userServiceClient = new UserService.UserServiceClient(channel);
            var userResponse = _userServiceClient.GetUsers(new UserReuqest());

            return Ok(userResponse.UserList);
        }
    }

 

posted @ 2024-02-18 10:11  野码  阅读(75)  评论(0编辑  收藏  举报