.NET 中的 gRPC 用戶端處理站整合
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
gRPC 與 HttpClientFactory
的整合提供建立 gRPC 用戶端的集中式方式。 其可作為設定獨立 gRPC 用戶端執行個體的替代方案。 Grpc.Net.ClientFactory NuGet 套件中提供了處理站整合。
處理站提供下列優點:
- 提供用於設定邏輯 gRPC 用戶端執行個體的中央位置。
- 管理基礎
HttpClientMessageHandler
的存留期。 - 在 ASP.NET Core gRPC 服務中自動傳播期限和取消。
註冊 gRPC 用戶端
若要註冊 gRPC 用戶端,可以在 Program.cs
中應用程式進入點的 WebApplicationBuilder 執行個體內使用泛型 AddGrpcClient
擴充方法,並指定 gRPC 型別用戶端類別和服務位址:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
gRPC 用戶端類型會透過相依性插入 (DI) 註冊為暫時性。 您現在可以直接在 DI 所建立的類型中插入及取用用戶端。 ASP.NET Core MVC 控制器、SignalR 中樞及 gRPC 服務是可以自動插入 gRPC 用戶端的位置:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
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);
}
}
}
}
設定 HttpHandler
HttpClientFactory
會建立 gRPC 用戶端所使用的 HttpMessageHandler
。 標準 HttpClientFactory
方法可用來新增傳出要求中介軟體,或設定 HttpClient
的基礎 HttpClientHandler
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
如需詳細資訊,請參閱使用 IHttpClientFactory 發出 HTTP 要求。
設定攔截器
可以使用 AddInterceptor
方法將 gRPC 攔截器新增至用戶端。
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
上述 程式碼:
- 註冊
GreeterClient
類型。 - 為此用戶端設定
LoggingInterceptor
。LoggingInterceptor
建立一次,並在GreeterClient
執行個體之間共用。
根據預設,攔截器會建立一次,並在用戶端之間共用。 透過在註冊攔截器時指定範圍,即可覆寫此行為。 您可以藉由指定 InterceptorScope.Client
,將用戶端處理站設定為針對每個用戶端建立新的攔截器。
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
當攔截器需要來自 DI 的範圍服務或暫時性範圍服務時,建立用戶端範圍攔截器非常有用。
gRPC 攔截器或通道認證可用來隨每個要求傳送 Authorization
中繼資料。 如需設定驗證的詳細資訊,請參閱使用 gRPC 用戶端處理站傳送持有人權杖。
設定通道
您可以使用 ConfigureChannel
方法,將其他組態套用至通道:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
會傳遞 GrpcChannelOptions
執行個體。 如需詳細資訊,請參閱設定用戶端選項。
注意
在執行 ConfigureChannel
回呼之前,先在 GrpcChannelOptions
上設定一些屬性:
HttpHandler
設定為 ConfigurePrimaryHttpMessageHandler 的結果。LoggerFactory
設定為從 DI 解析的 ILoggerFactory。
這些值可透過 ConfigureChannel
覆寫。
呼叫認證
您可以使用 AddCallCredentials
方法將驗證標頭新增至 gRPC 呼叫:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
如需設定呼叫認證的詳細資訊,請參閱 使用 gRPC 用戶端處理站的持有人權杖。
期限和取消傳播
可使用 EnableCallContextPropagation()
設定 gRPC 服務中處理站所建立的 gRPC 用戶端,以自動將期限和取消權杖傳播至子呼叫。 Grpc.AspNetCore.Server.ClientFactory NuGet 套件中提供了 EnableCallContextPropagation()
擴充方法。
呼叫內容傳播的運作方式是:從目前的 gRPC 要求內容讀取期限和取消權杖,並自動將其傳播至 gRPC 用戶端所發出的傳出呼叫。 呼叫內容傳播是確保複雜的巢狀 gRPC 案例絕對會散佈期限和取消權杖的絕佳方式。
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
根據預設,如果在 gRPC 呼叫的內容之外使用用戶端,EnableCallContextPropagation
就會引發錯誤。 錯誤的設計目的是要提醒您沒有要傳播的呼叫內容。 如果您要在呼叫內容之外使用用戶端,請在使用 SuppressContextNotFoundErrors
設定用戶端時隱藏錯誤:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
如需期限和 RPC 取消的詳細資訊,請參閱具有期限和取消功能的可靠 gRPC 服務。
具名用戶端
一般而言,gRPC 用戶端類型會註冊一次,然後由 DI 直接插入到類型的建構函式。 不過,在某些情況下,為一個用戶端提供多個組態會很有用。 例如,在使用驗證和不使用驗證的情況下呼叫 gRPC 的用戶端。
透過為每個用戶端指定一個名稱,即可註冊具有相同類型的多個用戶端。 每個具名用戶端都可以有自己的組態。 泛型 AddGrpcClient
擴充方法具有包含名稱參數的多載:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
上述 程式碼:
- 註冊
GreeterClient
類型兩次,每次註冊皆指定唯一的名稱。 - 為每個具名用戶端設定不同的設定。
GreeterAuthenticated
註冊會將認證新增至通道,如此使用其進行的 gRPC 呼叫就會經過驗證。
具名 gRPC 用戶端會使用 GrpcClientFactory
在應用程式程式碼中建立。 所需用戶端的類型和名稱則使用泛型 GrpcClientFactory.CreateClient
方法指定:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
其他資源
gRPC 與 HttpClientFactory
的整合提供建立 gRPC 用戶端的集中式方式。 其可作為設定獨立 gRPC 用戶端執行個體的替代方案。 Grpc.Net.ClientFactory NuGet 套件中提供了處理站整合。
處理站提供下列優點:
- 提供用於設定邏輯 gRPC 用戶端執行個體的中央位置
- 管理基礎
HttpClientMessageHandler
的存留期 - 在 ASP.NET Core gRPC 服務中自動傳播期限和取消
註冊 gRPC 用戶端
若要註冊 gRPC 用戶端,可以在 Startup.ConfigureServices
內使用泛型 AddGrpcClient
擴充方法,並指定 gRPC 型別用戶端類別和服務位址:
services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
gRPC 用戶端類型會透過相依性插入 (DI) 註冊為暫時性。 您現在可以直接在 DI 所建立的類型中插入及取用用戶端。 ASP.NET Core MVC 控制器、SignalR 中樞及 gRPC 服務是可以自動插入 gRPC 用戶端的位置:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
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);
}
}
}
}
設定 HttpHandler
HttpClientFactory
會建立 gRPC 用戶端所使用的 HttpMessageHandler
。 標準 HttpClientFactory
方法可用來新增傳出要求中介軟體,或設定 HttpClient
的基礎 HttpClientHandler
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
如需詳細資訊,請參閱使用 IHttpClientFactory 發出 HTTP 要求。
設定攔截器
可以使用 AddInterceptor
方法將 gRPC 攔截器新增至用戶端。
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
上述 程式碼:
- 註冊
GreeterClient
類型。 - 為此用戶端設定
LoggingInterceptor
。LoggingInterceptor
建立一次,並在GreeterClient
執行個體之間共用。
根據預設,攔截器會建立一次,並在用戶端之間共用。 透過在註冊攔截器時指定範圍,即可覆寫此行為。 您可以藉由指定 InterceptorScope.Client
,將用戶端處理站設定為針對每個用戶端建立新的攔截器。
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
當攔截器需要來自 DI 的範圍服務或暫時性範圍服務時,建立用戶端範圍攔截器非常有用。
gRPC 攔截器或通道認證可用來隨每個要求傳送 Authorization
中繼資料。 如需設定驗證的詳細資訊,請參閱使用 gRPC 用戶端處理站傳送持有人權杖。
設定通道
您可以使用 ConfigureChannel
方法,將其他組態套用至通道:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
會傳遞 GrpcChannelOptions
執行個體。 如需詳細資訊,請參閱設定用戶端選項。
注意
在執行 ConfigureChannel
回呼之前,先在 GrpcChannelOptions
上設定一些屬性:
HttpHandler
設定為 ConfigurePrimaryHttpMessageHandler 的結果。LoggerFactory
設定為從 DI 解析的 ILoggerFactory。
這些值可透過 ConfigureChannel
覆寫。
期限和取消傳播
可使用 EnableCallContextPropagation()
設定 gRPC 服務中處理站所建立的 gRPC 用戶端,以自動將期限和取消權杖傳播至子呼叫。 Grpc.AspNetCore.Server.ClientFactory NuGet 套件中提供了 EnableCallContextPropagation()
擴充方法。
呼叫內容傳播的運作方式是:從目前的 gRPC 要求內容讀取期限和取消權杖,並自動將其傳播至 gRPC 用戶端所發出的傳出呼叫。 呼叫內容傳播是確保複雜的巢狀 gRPC 案例絕對會散佈期限和取消權杖的絕佳方式。
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
根據預設,如果在 gRPC 呼叫的內容之外使用用戶端,EnableCallContextPropagation
就會引發錯誤。 錯誤的設計目的是要提醒您沒有要傳播的呼叫內容。 如果您要在呼叫內容之外使用用戶端,請在使用 SuppressContextNotFoundErrors
設定用戶端時隱藏錯誤:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
如需期限和 RPC 取消的詳細資訊,請參閱具有期限和取消功能的可靠 gRPC 服務。
具名用戶端
一般而言,gRPC 用戶端類型會註冊一次,然後由 DI 直接插入到類型的建構函式。 不過,在某些情況下,為一個用戶端提供多個組態會很有用。 例如,在使用驗證和不使用驗證的情況下呼叫 gRPC 的用戶端。
透過為每個用戶端指定一個名稱,即可註冊具有相同類型的多個用戶端。 每個具名用戶端都可以有自己的組態。 泛型 AddGrpcClient
擴充方法具有包含名稱參數的多載:
services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
上述 程式碼:
- 註冊
GreeterClient
類型兩次,每次註冊皆指定唯一的名稱。 - 為每個具名用戶端設定不同的設定。
GreeterAuthenticated
註冊會將認證新增至通道,如此使用其進行的 gRPC 呼叫就會經過驗證。
具名 gRPC 用戶端會使用 GrpcClientFactory
在應用程式程式碼中建立。 所需用戶端的類型和名稱則使用泛型 GrpcClientFactory.CreateClient
方法指定:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}