首页 > 解决方案 > 如何检测 Kestrel 中的连接关闭

问题描述

再一次,微软的文档让我想要。我正在尝试找到正确的 API,我可以在其中配置回调以在客户端关闭其连接时进行捕获。

当我启动 gRPC 服务器时,在控制台中我会看到所有 Kestrel 配置和启动日志消息。当我启动 gRPC 客户端时,我可以在服务器的控制台日志中看到表明已建立连接的消息,如下所示:

dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]
      Connection id "0HMCEE5LHGSKR" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]
      Connection id "0HMCEE5LHGSKR" started.

当我通过单击关闭窗口按钮 (X) 关闭客户端时,我看到以下内容:

dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[19]
      Connection id "0HMCEE5LHGSKR" reset.
dbug: Microsoft.AspNetCore.Server.Kestrel.Http2[48]
      Connection id "0HMCEE5LHGSKR" is closed. The last processed stream ID was 1.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
      Connection id "0HMCEE5LHGSKR" sending FIN because: "The client closed the connection."
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]
      Connection id "0HMCEE5LHGSKR" stopped.

使用 ListenOptions.UseConnectionLogging(ListenOptions) 扩展方法的选项没有提供我可以找到的回调选项。显然,在默认中间件中,事件被捕获,但我找不到该选项的路径。对 Microsoft.AspNetCore.Server.Kestrel 命名空间的检查显示(我找不到)如何获取 Microsoft.AspNetCore.Server.Kestrel.Connections 或 Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets 数据。

我正在使用 Visual Studio 2022、.NET 6、C# 10 和 gRPC。这是我当前的 Kestrel 配置:

// Configure Kestrel, the .NET Core web server.
var hostBuilder = webHostBuilder.ConfigureKestrel (kestrelServerOptions => {

    kestrelServerOptions.ConfigureHttpsDefaults (httpsConnectionAdapterOptions => httpsConnectionAdapterOptions.SslProtocols = SslProtocols.Tls12);

    // Read in the X.509 certificate file.
    var certPath = Path.Combine (builder.Environment.ContentRootPath, "Certs", $"{environment}.pfx");

    kestrelServerOptions.ConfigureEndpointDefaults (listenOptions => {

        _ = listenOptions.UseHttps (certPath, password);

        logger.Debug ($"Using {certPath} as the cert file.");
        logger.Debug ("Configuring host to use HTTP/2 protocol.");

        listenOptions.Protocols = HttpProtocols.Http2;
    });

    logger.Debug ("Reading config values for the server name and port.");

    // Get the host name and port number to bind the service to.
    var port = builder.Configuration.GetValue<int> ("AppSettings:OperationsServerPort");
    var address = IPAddress.Parse ("0.0.0.0");

    if (address != null) {
        logger.Debug ($"Host will listen at https://{address}:{port}");

        kestrelServerOptions.Listen (address, port);
    } else {
        logger.Error ("DNS address for service host cannot be determined!  Exiting...");

        Environment.Exit (-1);
    }
});

任何线索,指导,例子将不胜感激!

标签: c#asp.net-coregrpckestrel

解决方案


好吧,我可能在理解所有这些 ASP.NET Core 配置方面迟到了,但是捕获来来往往的连接太简单了......只需将中间件委托添加到侦听器......

var ipEndpoint = new IPEndPoint (address, port);

kestrelServerOptions.Listen (ipEndpoint, action => action.Use (async (context, next) => {

    Console.WriteLine ($"INTERNAL ---------------- New Connection: {context.ConnectionId}");

    await next.Invoke ();

    Console.WriteLine ($"INTERNAL ---------------- Connection terminated: {context.ConnectionId}");
}));

这个片段通过添加中间件委托修改了我上面的原始帖子。可以在这里找到使我摆脱僵局的必读内容:https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0

我希望这对某人有帮助!


推荐阅读