You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在ASP.NET Core的Kestrel上为MVC与gRPC配置独立端点?

解决ASP.NET Core中MVC与gRPC绑定独立套接字的问题

嘿,这个问题我之前也踩过坑!默认情况下Kestrel会把所有端点映射应用到所有配置的套接字上,所以咱们得做些条件筛选,让MVC和gRPC分别绑定到指定端口,同时满足各自的HTTP协议要求。下面是具体的实现步骤:

1. 先配置Kestrel的两个独立端点

首先要在项目的配置阶段(比如.NET 6+的Program.cs,或者旧版本Startup.csConfigureServices方法里)指定两个端口,分别对应MVC和gRPC,并设置对应的HTTP协议:

// .NET 6+ 风格的 Program.cs
var builder = WebApplication.CreateBuilder(args);

// 配置Kestrel的两个端点
builder.WebHost.ConfigureKestrel(options =>
{
    // MVC专属端点:localhost:8888,仅支持HTTP/1
    options.ListenLocalhost(8888, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1;
    });

    // gRPC专属端点:localhost:8889,仅支持HTTP/2(gRPC必须依赖HTTP/2)
    options.ListenLocalhost(8889, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http2;
    });
});

// 注册必要服务
builder.Services.AddControllers();
builder.Services.AddGrpc();

var app = builder.Build();

2. 在UseEndpoints中添加条件映射

接下来修改你的端点配置逻辑,使用MapWhen方法根据请求的端口来区分映射MVC和gRPC服务,确保每个服务只会绑定到指定端口:

// 在Configure方法(或Program.cs的app配置段)
app.UseRouting();

app.UseEndpoints(endpoints =>
{
    // 仅当请求来自8889端口时,映射gRPC服务
    endpoints.MapWhen(context => context.Request.Host.Port == 8889, grpcEndpoints =>
    {
        grpcEndpoints.MapGrpcService<ComunicacaoService>();
    });

    // 仅当请求来自8888端口时,映射MVC默认路由
    endpoints.MapWhen(context => context.Request.Host.Port == 8888, mvcEndpoints =>
    {
        mvcEndpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller}/{action=Index}/{id?}");
    });
});

app.Run();

原理说明

  • MapWhen方法会根据传入的条件判断,将请求路由到对应的端点集合中,实现了不同端口对应不同服务的隔离。
  • Kestrel的端点配置中明确指定了各自的HTTP协议,既满足gRPC对HTTP/2的强制要求,也符合MVC使用HTTP/1的需求。

这样配置完成后,localhost:8888只会响应MVC控制器的请求,localhost:8889只会处理gRPC调用,再也不会出现两个服务同时绑定到两个端口的情况啦!

内容的提问来源于stack exchange,提问作者Douglas Ramos

火山引擎 最新活动