.NET Framework下RecaptchaEnterpriseServiceClient创建Assessment失败
我有一个基于.NET Framework 4.8搭建的控制台测试应用,通过Google.Cloud.RecaptchaEnterprise.V1 NuGet包接入Google reCAPTCHA Enterprise服务,代码逻辑和官方示例基本一致,身份认证配置已经验证通过,客户端初始化流程可以正常走完,但执行创建评估操作时抛出如下错误:
Status(StatusCode="Unavailable", Detail="failed to connect to all addresses",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{"created":"@1657548977.660000000","description":"Failed to pick subchannel","file":"......\src\core\ext\filters\client_channel\client_channel.cc","file_line":3218,"referenced_errors":[{"created":"@1657548977.660000000","description":"failed to connect to all addresses","file":"......\src\core\lib\transport\error_utils.cc","file_line":165,"grpc_status":14}]}")
测试用代码如下:
static void Main(string[] args) { RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.Create(); var projectName = new ProjectName("[insert project name]"); CreateAssessmentRequest createAssessmentRequest = new CreateAssessmentRequest() { Assessment = new Assessment() { Event = new Event() { SiteKey = "[insert site key]", Token = "[insert token]", ExpectedAction = "login", } }, ParentAsProjectName = projectName }; Assessment assessmentResponse = client.CreateAssessment(createAssessmentRequest); Console.WriteLine(assessmentResponse.Name); }
这个是.NET Framework环境下使用Google Cloud客户端库的典型问题,按以下顺序排查即可:
- 先验证网络连通性:reCAPTCHA Enterprise默认gRPC服务端点为
recaptchaenterprise.googleapis.com:443,先确认当前运行环境可以正常访问该地址的443端口,没有被防火墙、服务器安全组、本地网络策略拦截;如果是在国内网络环境下测试,先确认网络可以正常访问Google服务,基础连通性有问题必然报这个错。 - 补全gRPC原生依赖:.NET Framework本身不原生支持gRPC协议,只安装
Google.Cloud.RecaptchaEnterprise.V1包大概率缺少Grpc.Core的原生二进制文件,手动给项目安装Grpc.CoreNuGet包,安装后检查项目输出目录是否存在grpc_csharp_ext.x64.dll、grpc_csharp_ext.x86.dll两个原生库,很多场景下客户端初始化不报错,但实际发请求失败就是因为缺这两个文件。 - 排查代理兼容性问题:如果本地开启了系统代理,绝大多数普通HTTP代理不支持gRPC要求的HTTP/2多路复用特性,会直接中断连接,测试时可以先关闭代理,或者给gRPC请求配置直连规则,也可以更换支持HTTP/2的代理。
- 不想折腾gRPC配置可以直接切换为REST传输模式:Google的客户端库原生支持REST传输适配,不需要修改后续业务逻辑,只要调整客户端初始化代码即可,REST模式对.NET Framework的兼容性远好于gRPC,绝大多数遇到该报错的场景切换后即可恢复正常:
// 替换原代码里的 RecaptchaEnterpriseServiceClient.Create() RecaptchaEnterpriseServiceClient client = new RecaptchaEnterpriseServiceClientBuilder { GrpcAdapter = RestGrpcAdapter.Default }.Build();
内容的提问来源于stack exchange,提问作者Scott

