You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Kestrel多动态端口监听器如何匹配端口与对应服务

问题场景

我有一个.NET6应用,需要实现以下端口监听需求:

  • 在系统随机分配的可用端口开放标准HTTP服务
  • 在另一个系统随机分配的可用端口,开放基于自定义协议的TCP服务,该自定义协议通过ConnectionHandler实现

目前已经实现两个服务的动态端口绑定,也能获取到所有包含端口号的绑定地址,但无法确定哪个地址/端口对应哪一项服务。

现有实现与卡点

目前已参考公开的实现方案完成基础功能开发:

  • 动态端口绑定方案:将监听端口设为0,由操作系统自动分配可用端口,服务启动后通过IServerAddressesFeature获取实际生效的绑定URL,从中提取端口号
  • 多协议Kestrel方案:通过UseConnectionHandler()扩展方法,在Kestrel服务上同时挂载HTTP服务与自定义TCP处理器

当前的卡点是:没有可靠的端口-服务匹配方式,仅能假设IServerAddressesFeature.Addresses集合的元素顺序,和代码中so.Listen()的调用顺序一一对应,这种判断依赖未文档化的实现细节,存在不确定性。需要找到不依赖顺序假设、不依赖未文档化行为的确定性匹配方案。

最小可复现代码如下:

// Kestrel同时绑定动态端口HTTP服务、动态端口自定义ConnectionHandler服务的最小示例
// 可通过 `curl -i %URL%` 测试HTTP服务连通性
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using System.Net;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(so =>
{
  so.Listen(new IPEndPoint(IPAddress.Loopback, 0));
  so.Listen(new IPEndPoint(IPAddress.Loopback, 0),
    epo => epo.UseConnectionHandler<HttpEchoHandler>());
});

var app = builder.Build();
app.MapGet("/", () =>
{
  return "Hello, world";
});
app.Lifetime.ApplicationStarted.Register(() =>
{
  // 提取服务实际绑定的地址集合
  var server = app.Services.GetRequiredService<IServer>();
  var addresses = server.Features.Get<IServerAddressesFeature>().Addresses;
  Console.WriteLine(String.Join(Environment.NewLine, addresses));
  // ******** 无法判断哪个地址对应HTTP服务,哪个对应Echo自定义服务 ********
});
app.Run();

// 自定义Echo连接处理器
class HttpEchoHandler : ConnectionHandler
{
  public override async Task OnConnectedAsync(ConnectionContext connection)
  {
    Console.WriteLine($"C{connection.ConnectionId} connected");
    var header = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n";
    var headerBytes = Encoding.ASCII.GetBytes(header);
    await connection.Transport.Output.WriteAsync(headerBytes);
    await connection.Transport.Input.CopyToAsync(connection.Transport.Output);
    Console.WriteLine($"C{connection.ConnectionId} disconnected");
  }
}

内容的提问来源于stack exchange,提问作者Trevor Davel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:57:24