RPC:像调用本地函数一样远程调用,高效但耦合高,适合内部服务高频通信(如微服务集群内)。
RESTful API:基于 HTTP 资源操作,简单通用但性能略低,适合外部接口或跨系统通信(如开放平台、前后端交互)。
在 .NET Core 中实现 RPC 可以通过多种框架,常见的有 gRPC (谷歌开源,高性能)、SignalR (微软官方,实时通信)、DotNetty (基于 Netty 的 .NET 版本)等。其中,gRPC 是 .NET Core 官方推荐的 RPC 方案,因其跨语言、高性能、基于 HTTP/2 和 Protobuf 等特性被广泛使用。
以下以 gRPC 为例,详细说明在 .NET Core 中实现 RPC 的步骤:
一、环境准备
-
安装 .NET Core 3.0+(gRPC 在 .NET Core 3.0 及以上版本原生支持)。
-
安装 gRPC 工具(用于生成代码):
在 Visual Studio 中,通过 NuGet 安装Grpc.Tools;或在项目文件中添加依赖:xml<ItemGroup> <PackageReference Include="Grpc.Tools" Version="2.56.0" PrivateAssets="All" /> </ItemGroup>
二、创建 gRPC 服务端
1. 新建项目
-
在 Visual Studio 中选择"ASP.NET Core gRPC 服务"模板,或通过命令行创建:
bashdotnet new grpc -n GrpcServer
2. 定义服务契约(.proto 文件)
gRPC 使用 Protobuf(.proto)定义服务接口和数据结构,默认生成的 Protos/greet.proto 示例:
protobuf
syntax = "proto3";
option csharp_namespace = "GrpcServer";
package greet;
// 定义服务
service Greeter {
// 定义远程方法(类似函数)
rpc SayHello (HelloRequest) returns (HelloReply);
}
// 请求消息
message HelloRequest {
string name = 1; // 字段编号(Protobuf 要求)
}
// 响应消息
message HelloReply {
string message = 1;
}
3. 实现服务逻辑
在 Services/GreeterService.cs 中实现 .proto 定义的接口:
csharp
using Grpc.Core;
using greet;
namespace GrpcServer.Services;
public class GreeterService : Greeter.GreeterBase
{
// 重写远程方法
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
// 处理请求:拼接响应消息
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
4. 配置服务端
在 Program.cs 中,框架已默认配置 gRPC 服务,无需额外修改:
csharp
var builder = WebApplication.CreateBuilder(args);
// 添加 gRPC 服务
builder.Services.AddGrpc();
var app = builder.Build();
// 映射 gRPC 服务
app.MapGrpcService<GreeterService>();
// 提供 HTTP 页面(可选)
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client.");
app.Run();
三、创建 gRPC 客户端(.NET Core 控制台/API)
1. 新建客户端项目
bash
dotnet new console -n GrpcClient
2. 安装客户端依赖
bash
dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
3. 复制 .proto 文件
将服务端的 Protos/greet.proto 复制到客户端项目,并在客户端 .csproj 中配置(确保路径正确):
xml
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
GrpcServices="Client"表示生成客户端代码。
4. 编写客户端调用代码
在 Program.cs 中调用远程 gRPC 服务:
csharp
using Grpc.Net.Client;
using greet;
// 服务端地址(注意:.NET Core 客户端默认需要 HTTPS,开发环境可禁用)
var channel = GrpcChannel.ForAddress("https://localhost:5001");
// 创建客户端
var client = new Greeter.GreeterClient(channel);
// 调用远程方法 SayHello
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "World" });
Console.WriteLine("Greeting: " + reply.Message); // 输出:Greeting: Hello World
四、运行与测试
- 启动服务端项目(默认端口:HTTPS 5001,HTTP 5000)。
- 启动客户端项目,若正常调用,会输出
Greeting: Hello World。
五、其他 RPC 实现方式
- SignalR (适合实时通信场景,如聊天、通知):
- 服务端:
builder.Services.AddSignalR(); app.MapHub<ChatHub>("/chat"); - 客户端:
var hubConnection = new HubConnectionBuilder().WithUrl("https://localhost:5001/chat").Build(); await hubConnection.InvokeAsync("SendMessage", "Hello");
- 服务端:
- DotNetty (基于 TCP 自定义协议,适合高性能场景):
需手动处理编解码、消息格式,灵活性高但开发成本高。
总结
- gRPC 是 .NET Core 中最推荐的 RPC 方案,适合跨语言、高性能的服务间通信,通过 Protobuf 定义接口,自动生成代码,开发效率高。
- 核心步骤:定义
.proto契约 → 服务端实现接口 → 客户端调用生成的代理类。 - 如需实时双向通信,可考虑 SignalR;如需极致性能和自定义协议,可使用 DotNetty。
- RPC(远程过程调用)不是进程内的交互,而是跨进程、跨机器甚至跨网络的远程交互。它的核心目的是让一个进程(客户端)像调用本地函数一样,调用另一个进程(服务端)中的方法,无论这两个进程是否在同一台机器上。