azure - 将服务器托管在 Azure 上后,gRPC 客户端无法与 gRPC 服务器通信

标签 azure grpc asp.net-core-3.1 grpc-web

以下代码片段展示了如何在 gRPC AspNet 核心应用程序中启用 gRPC Web:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseDefaultFiles();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseGrpcWeb();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<SubmissionService>().EnableGrpcWeb();
        });
    }
}

客户端应用程序的代码如下所示:

public static async Task SendSomethingAsync(string payload, ILoggerFactory loggerFactory)
        {
            const string url = "https://MASKED.azurewebsites.net/";
            //const string url = "https://localhost:44308";
            AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
            var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
            using var channel = GrpcChannel.ForAddress(url, new GrpcChannelOptions
            {
                HttpClient = new HttpClient(handler),
                LoggerFactory = loggerFactory
            });

            var client = new TestgRPC.gRPC.PayloadSubmission.PayloadSubmissionClient(channel);
            var submitted = await client.SubmitAsync(new SubmissionRequest
            {
                ClientKey = "678",
                ConnectionId = "abcdef",
                UserId = "3",
                MyObjectPayload= payload,
            });

            Console.WriteLine($"Submitted: {submitted}");
        }

当客户端代码(上面)托管在本地主机(开发计算机)上时,它会接收来自 gRPC 服务器的回复。相同的客户端代码无法与 Azure 上托管的服务器实例通信,并记录以下失败消息:

dbug: Grpc.Net.Client.Internal.GrpcCall[18] Sending message. fail: Grpc.Net.Client.Internal.GrpcCall[20] Error sending message. System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Net.Http.TaskCompletionSourceWithCancellation1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.Http2Connection.Http2Stream.SendDataAsync(ReadOnlyMemory1 buffer, CancellationToken cancellationToken) at Grpc.Net.Client.Web.Internal.Base64RequestStream.WriteAsync(ReadOnlyMemory1 data, CancellationToken cancellationToken) at Grpc.Net.Client.StreamExtensions.WriteMessageAsync[TMessage](Stream stream, ILogger logger, TMessage message, Action2 serializer, String grpcEncoding, Nullable1 maximumMessageSize, Dictionary2 compressionProviders, CallOptions callOptions) fail: Grpc.Net.Client.Internal.GrpcCall[6] Error starting gRPC call. System.Threading.Tasks.TaskCanceledException: The operation was canceled. at System.Net.Http.CancellationHelper.ThrowOperationCanceledException(Exception innerException, CancellationToken cancellationToken) at System.Net.Http.CancellationHelper.ThrowIfCancellationRequested(CancellationToken cancellationToken) at System.Net.Http.Http2Connection.Http2Stream.GetCancelableWaiterTask(CancellationToken cancellationToken) at System.Net.Http.Http2Connection.Http2Stream.ReadResponseHeadersAsync(CancellationToken cancellationToken) at System.Net.Http.Http2Connection.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at Grpc.Net.Client.Web.GrpcWebHandler.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Grpc.Net.Client.Internal.GrpcCall2.RunCall(HttpRequestMessage request, Nullable`1 timeout) info: Grpc.Net.Client.Internal.GrpcCall[3] Call failed with gRPC error status. Status code: 'Cancelled', Message: ''. dbug: Grpc.Net.Client.Internal.GrpcCall[4] Finished gRPC call.

我无法找出是什么阻碍了这种沟通的发生以及要实现什么解决方案。有什么想法吗?

顺便说一句,我用尽了 this github ticket 中的所有内容。但一点运气都没有。

最佳答案

问题是我们需要将应用程序部署为独立的应用程序。显然,Azure 应用服务上安装的默认 .net core 3.1 无法容纳 gRPC-web 应用。

关于azure - 将服务器托管在 Azure 上后,gRPC 客户端无法与 gRPC 服务器通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63020334/

相关文章:

c# - 在 EF Core 3.1 中加入群组

azure-active-directory - Ocelot 与 Azure Active Directory 身份验证 .Net Core 3.1 集成

Azure Functions 内存不足异常

Azure Kusto 使用 KQL 创建数据库

javascript - 在本地主机上使用 TLS 的 Web gRPC

c++ - grpc c++ 异步服务器示例,处理状态下是否需要互斥锁?

c# - Microsoft.AspNetCore.Routing.Matching.AmbigouslyMatchException : The request matched multiple endpoints

Azure Blob 存储 - 创建只能使用一次的 SAS token

bash - 在 databricks 上重新启动集群

go - 如何正确运行 evans(gRPC 客户端)?