用 dotnet new grpc
创建基础服务项目
这是最直接的起点,命令会生成包含
GreeterService示例的完整可运行 gRPC 服务(基于 ASP.NET Core)。
执行后你会得到一个带
Program.cs、
Protos/greet.proto和
Services/GreeterService.cs的项目。关键点在于:它默认启用 HTTPS 和 HTTP/2,且
app.MapGrpcService<greeterservice>()</greeterservice>是注册服务的必需调用。 若在非开发环境部署,需确保服务器支持 HTTP/2(如 Kestrel 默认支持,IIS 需 Windows Server 2016+ + TLS 1.2+)
.proto文件必须放在
Protos/目录并设为
Protobuf生成操作,否则
dotnet build不会生成 C# 绑定类 不要手动修改生成的
*.Grpc.cs文件——它们每次构建都会被覆盖
定义接口时注意 service
和 rpc
的写法
gRPC 的契约由
.proto文件驱动,C# 类型和行为完全由此决定。错误的 proto 定义会导致客户端和服务端无法通信,甚至编译不报错但运行时报
StatusCode=Unimplemented。
常见问题包括:
遗漏option csharp_namespace = "MyApp.Protos";—— 导致生成的 C# 类不在预期命名空间,引用失败
rpc SayHello(HelloRequest) returns (HelloReply);中的
HelloRequest和
HelloReply必须已用
message正确定义,且字段名首字母小写(如
string name = 1;→ C# 属性为
Name) 流式方法要显式标注:比如
rpc StreamingCall(stream ClientMessage) returns (stream ServerMessage);,否则生成器不会产生
IAsyncStreamReader或
IServerStreamWriter
客户端调用必须用 Channel
+ 生成的 *Client
类
不能像调用普通类一样 new 一个服务类;必须通过
GrpcChannel.ForAddress("https://localhost:5001") 创建通道,再传给生成的客户端构造函数。
典型调用模式:
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "Alice" });
HTTP/2 要求地址协议明确:用 https://(开发时可配
http://,但需在
channel构造时加
new GrpcChannelOptions { HttpHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true } })
若服务启用了 TLS 但客户端证书验证失败,会抛 System.Net.Http.HttpRequestException,提示 “The SSL connection could not be established” —— 此时需配置
GrpcChannelOptions.Credentials或临时禁用验证(仅限开发) 短生命周期调用建议复用
GrpcChannel实例(它是线程安全的),不要为每次请求新建 channel
调试时先确认 StatusCode=Internal
还是 StatusCode=Unavailable
这两个错误看起来像网络问题,但根源完全不同:
StatusCode=Unavailable:通常是连接失败(地址错、端口未监听、防火墙拦截、TLS 协商失败),检查
dotnet run是否真在监听,用
curl -v https://localhost:5001看是否返回 HTTP/2 404(说明服务起来了)
StatusCode=Internal:大概率是服务端代码异常未捕获,比如
SayHello方法里 throw 了未处理的
Exception—— gRPC 会将其转为
Internal并丢掉原始堆栈;应在服务端添加全局异常过滤器或日志中间件捕获 客户端收到异常时,
exception.Status.Detail可能含服务端返回的错误信息(前提是服务端用了
Status(StatusCode.Internal, "xxx")显式设置)
proto 文件改了之后,务必重新生成客户端和服务端代码;Visual Studio 不总会自动触发,可手动运行
dotnet build或右键 .proto 文件选 “重新生成”。
