Aspnetcore: 项目基岩

创建于 2017-08-04  ·  126评论  ·  资料来源: dotnet/aspnetcore

项目基岩

项目基石是关于进一步解耦 Kestrel 的组件,以便我们可以将其用作非 http 网络堆栈的基础。
我们希望建立在当今 ASP.NET Core 应用程序中存在的原语、模式和横切关注点的基础上。 目标是使更高级别的框架(如 SignalR 或 WCF 甚至 ASP.NET Core 本身)能够在不将它们绑定到特定连接实现(用于连接的 OWIN)的抽象之上构建。 例如,它允许 SignalR 在 TCP 或 Websockets 之上运行,而无需了解底层传输是什么。 我们还希望能够构建原始的低级协议服务器来处理物联网场景的 MQTT 之类的事情。

此服务器端编程模型中有 3 个主要参与者:

  • 应用程序/中间件/框架- 处理连接并实现协议解析逻辑或其他修改数据流的逻辑的应用程序代码(以http、TLS为例)
  • 传输- 传输提供了实现底层连接语义的IFeatureCollection实现。 简而言之,传输提供了流经调度程序到应用程序的ConnectionContext的具体实现。
  • 调度程序- 调度程序是将传输层和应用程序层结合在一起的组件。 它的工作是管理传输连接和运行在上面的应用程序的生命周期。 调度程序将为与传输相关的特定绑定公开IConnectionBuilder 。 例如,http 调度器将根据特定路由公开IConnectionBuilder ,而 TCP 调度器将根据 ip 地址和端口公开IConnectionBuilder

应用程序/中间件/框架

这项工作的核心是一组代表底层连接的新原语:

```C#
公共抽象类 ConnectionContext
{
公共抽象字符串 ConnectionId { get; 放; }

public abstract IFeatureCollection Features { get; }

public abstract IDuplexPipe Transport { get; set; }

public abstract IDictionary<object, object> Items { get; set; }

}

```C#
public interface IConnectionIdFeature
{
    string ConnectionId { get; set; }
}

```C#
公共接口 IConnectionTransportFeature
{
IDuplexPipe 传输 { 获取; 放; }
}

```C#
public interface IConnectionItemsFeature
{
    IDictionary<object, object> Items { get; set; }
}

ConnectionContext是连接宇宙的“HttpContext”。 它是一种抽象,表示某种形式的持久连接。 这可以
可以是 TCP 连接、websocket 连接或更混合的连接(例如通过非双工协议实现的连接,如服务器发送的事件 + http 帖子)。 特征集合
是否出于同样的原因它在HttpContext ,服务器或各种“中间件”可以添加、增加或删除功能
从连接可以丰富底层抽象。 2 个必需的功能是IConnectionTransportFeatureIConnectionIdFeature

接下来,我们介绍执行连接的抽象。

```C#
公共委托任务 ConnectionDelegate(ConnectionContext connection);

The `ConnectionDelegate` represents a function that executes some logic per connection. That `Task` return represents the
connection lifetime. When it completes, the application is finished with the connection and the server is free to close it.

In order to build up a pipeline, we need a builder abstraction and a pipeline. The `IConnectionBuilder` (similar to the `IApplicationBuilder`) represents
a sockets pipeline. The middleware signature is `Func<ConnectionDelegate, ConnectionDelegate>` so callers can decorate the next `ConnectionDelegate`
in the chain similar to http middleware in ASP.NET Core.

```C#
public interface IConnectionBuilder
{
    IServiceProvider ApplicationServices { get; }

    IConnectionBuilder Use(Func<ConnectionDelegate, ConnectionDelegate> middleware);

    ConnectionDelegate Build();
}

这些是构建面向连接的应用程序的基本构建块。 这将位于Microsoft.AspNetCore.Connections.Abstractions包中。

这种重构将实现以下几点:

  • Kestrel 的 ASP.NET Core 实现将重新部署在这个新基础架构之上,这意味着它将与 Kestrel 完全分离。
  • Kestrel 的连接适配器管道将改为使用IConnectionBuilder 。 这意味着像 TLS、windows auth 和连接日志这样的东西可以是单独的中间件组件。
  • SignalR 将建立在此之上,从而可以在任何基于连接的基础设施上运行 SignalR。

运输

传输负责为连接提供初始的IFeatureCollection实现并向应用程序提供字节流。

Libuv 和 System.Net.Sockets

今天,我们有 2 个位于 Kestrel 的传输实现,一个 System.Net.Sockets 和 libuv 实现。 我们计划保留这两个,因为它们都提供不同的功能集。 Libuv 可以监听文件句柄、命名管道、unix 域套接字和 tcp 套接字,而 System.Net.Sockets 只有一个 tcp 套接字实现(和 unix 域套接字)

网络套接字

我们希望使人们能够构建基于 websocket 的框架,而无需处理连接管理和缓冲等低级细节。 因此,我们将提供一个暴露这些连接原语的网络套接字传输。 它目前位于Microsoft.AspNetCore.Http.Connectons包中。

其他 HTTP 传输

SignalR 过去曾为不支持 websocket 的浏览器提供多种传输实现。 这些不是全双工传输,而是通过在 http 请求上往返传输连接 ID 来实现的。 我们还将为长轮询和服务器发送事件提供实现传输。 这些实现将需要一个能够理解底层非双工协议的特殊客户端库。 这些当前位于Microsoft.AspNetCore.Http.ConnectonsMicrosoft.AspNetCore.Http.Connectons.Client包中。

快讯

QUIC是一项快速兴起的标准,旨在提高当前使用 TCP 的面向连接的 Web 应用程序的感知性能。 当 QUIC 出现时,我们希望能够用相同的抽象来支持它。

调度员

ASP.NET 核心

ASP.NET Core 将作为我们的 HTTP 调度程序的基础。 将有一个RequestDelegate实现,用作构建在路由之上的调度程序。

```C#
使用 Microsoft.AspNetCore.Builder;
使用 Microsoft.AspNetCore.Hosting;
使用 Microsoft.Extensions.DependencyInjection;
使用 SocketsSample.EndPoints;
使用 SocketsSample.Hubs;

命名空间 SocketsSample
{
公开课启动
{
public void ConfigureServices(IServiceCollection 服务)
{
服务.AddConnections();
}

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseConnections(routes =>
        {
            // Handle mqtt connections over websockets on the /mqtt path
            routes.MapWebSocket("mqtt", connectionBuilder =>
            {
                connectionBuilder.UseMQTT<MQTTHandler>();
            });

            // Handle SignalR chat connections on the /chat path (multiple transports)
            routes.MapConnections("chat", connectionBuilder =>
            {
                connectionBuilder.UseSignalR<Chat>();
            });
        });
    }
}

}

### Kestrel

Kestrel was originally built as an http server for ASP.NET Core. Since then it's evolved to into a bunch of separate components but has still been hyper focused on http scenarios. As part of this work, there are further refactorings that will happen and kestrel will serve as the generic sockets server that will support multiple protocols.  We want to end up with layers that look something like this:

- **Microsoft.AspNetCore.Server.Kestrel.Core** - Dispatcher implementation
- **Microsoft.AspNetCore.Server.Kestrel.Https** - Deprecate this package in favor of (**Microsoft.AspNetCore.Protocols.Tls**)
- **Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions** - Abstractions for plugging different transports into kestrel
- **Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv** - Libuv transport (tcp, pipes, unix sockets)
- **Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets** - System.Net.Sockets transport
- **Microsoft.AspNetCore.Server.Kestrel** - Meta package for ASP.NET Core to avoid breaking changes

We should introduce the following packages:

- **Microsoft.AspNetCore.Protocols.Http** - Http `ConnectionDelegate` middleware
- **Microsoft.AspNetCore.Protocols.Http2** - Http2 `ConnectionDelegate` middleware (do we merge Http and Http2?)
- **Microsoft.AspNetCore.Protocols.Tls** - TLS `ConnectionDelegate` middleware

Here's what the Kestrel for TCP could look like wired up to the generic host:

```C#
var host = new HostBuilder()
            .ConfigureServer(options =>
            {
                // Listen on (*, 5001), then get access to the ISocketBuilder for this binding
                options.Listen(IPAddress.Any, 5001, connectionBuilder =>
                {
                   // This is the SignalR middleware running directly on top of TCP
                   connectionBuilder.UseHub<Chat>();
                });

                // Listen on (localhost, 8001), then get access to the ISocketBuilder for this binding
                options.Listen("localhost", 8001, connectionBuilder =>
                {
                   // Accept connections from an IOT device using the MQTT protocol
                   connectionBuilder.UseMQTT<MQTTHandler>();
                });

                options.Listen("localhost", 5000, connectionBuilder => 
                {
                    // TLS required for this end point (this piece of middleware isn't terminal)
                    connectionBuilder.UseTls("testCert.pfx", "testPassword");

                    // ASP.NET Core HTTP running inside of a Connections based server
                    connectionBuilder.UseHttpServer(async context =>
                    {
                        await context.Response.WriteAsync("Hello World");
                    });
                });
            })
            .Build();

host.Run();
area-servers servers-kestrel 🥌 Bedrock

最有用的评论

在客户端也有类似传输的东西真的很酷,这样你基本上可以有一个更抽象的 HttpClient 和可切换的底层传输机制

所有126条评论

在客户端也有类似传输的东西真的很酷,这样你基本上可以有一个更抽象的 HttpClient 和可切换的底层传输机制

@davidfowl在引入这种抽象之后,您如何看待性能

@davidfowl 干得好! 我只有一个顾虑...

由于抽象不会仅是 aspnet,您不认为我们可以只使用Microsoft.Sockets.Abstractions代替Microsoft.AspNetCore.Sockets.Abstractions Microsoft.Sockets.Abstractions用于核心抽象吗?

我同意 Kestrel 和 AspNet 抽象应该有各自的名称,但我认为这些抽象非常......抽象,就像你提到的那样,可以插入和管理非常低级的原语。

做得好! 期待吧! :)

同样,Microsoft.AspNetCore.Sockets.Tls => Microsoft.Sockets.Tls 也有道理,但我想要的不仅仅是一个名字。

@davidfowl如果我们需要从 USB 或串行端口而不是套接字读取数据,那会是我们必须创建特定传输的场景吗?

@dls314

但我想要的功能不仅仅是一个名字。

我也是。 但我想让包语义更_clear_。 最好在发布后立即提出建议:)

@shaggygi

如果我们需要从 USB 或串行端口而不是套接字读取数据,那会是我们必须创建特定传输的场景吗?

我想这就是运输的目的。

至少这是我从这部分理解的:

传输提供了实现底层连接语义的 IFeatureCollection 的

这是否意味着您可以将消息传输(msmq、rabbitMq、kafka)进一步推入堆栈? 我想这些传输将与 SignalR 处于同一抽象级别....

@aL3891

在客户端也有类似传输的东西真的很酷,这样你基本上可以有一个更抽象的 HttpClient 和可切换的底层传输机制

我一直在考虑一个与此相关的客户故事。 SignalR 有它的开端,但我将它排除在本规范之外。

@galvesribeiro

由于抽象不会仅限于 aspnet,您不认为我们可以只使用 Microsoft.Sockets.Abstractions 来代替使用 Microsoft.AspNetCore.Sockets.Abstractions 作为核心抽象吗?

这是我们过去一直在努力解决的问题,但 AspNetCore 不仅仅意味着我们现有的 HTTP 堆栈,它是一般的服务器堆栈。 我们不会在根命名空间(即 Microsoft.Sockets)中放置任何东西。 命名需要一些工作,但套接字不是很好。

@shaggygi

@davidfowl如果我们需要从 USB 或串行端口而不是套接字读取数据,那会是我们必须创建特定传输的场景吗?

是的,那将是一种交通工具。

@no1melman

这是否意味着您可以将消息传输(msmq、rabbitMq、kafka)进一步推入堆栈? 我想这些传输将与 SignalR 处于同一抽象级别....

我不完全理解这个问题。 传输可以是任何东西,但我不会开始通过消息总线实现 HTTP 😄。

我只是想你可以把消息队列作为传输,就像你用signalR一样,然后你就从机制中抽象出来了。

@davidfowl好吧,如果现在 AspNetCore 将成为 .Net 中所有服务器技术的参考,而不仅仅是 Web 堆栈,我完全支持! :)

我对本期完全没有提到 The Flintstones 感到非常沮丧。

如果现在 AspNetCore 将成为 .Net 中所有服务器技术的参考,而不仅仅是 Web 堆栈,我完全支持! :)

异步服务能力

@no1melman

我只是想你可以把消息队列作为传输,就像你用signalR一样,然后你就从机制中抽象出来了。

SignalR 没有将消息队列作为传输,它们是根本不同的抽象。

@davidfowl

命名需要一些工作,但套接字不是很好。

Microsoft.AspNetCore.Bungholes

对于 AspNetCore 的旧完整框架技术,我真的不介意更好的名称,更短且不会混淆。 特别是如果它通常是服务器堆栈的引用名称。

关于名称,我同意,考虑到此 API 的低级和普遍性,删除“AspNetCore”是个好主意。

我认为最适合描述它的关键词是“网络”。
那么,也许是 Microsoft.Network?
或者只是 Microsoft.Net(如 System.Net),但它听起来像“Microsoft .NET” :)

微软网络

嗯……严格来说,传输抽象是非常灵活的,这不是真的。 所以你可以写一个标准输入/输出或文件流传输和管道到程序或从文件流读取和写入 http。 或者之前的例子可能来自usb或串口......

交通就像司机

Microsoft.Bedrock? :)
这是一个很酷的名字imo

它也可以是 Microsoft.Transport,在概念上也非常适合

网络也是计算机科学之外的一个相当通用的术语。 其定义之一是:“相互关联的人或事物的群体或系统。”
因此,当您将某物与其他物连接时,您就创建了一个网络。

通过 T 而不是字符串来识别连接可能会很好。 也许 IConnectionIdFeature有适当的可比性 T?

我的猜测是 ConnectionId 是一个字符串以简化它的传递。
如果您将其设为 T,则需要提供一个比较器(如您所提到的)以及一个序列化器。 这很复杂。
您能否给出一个引人注目的场景,其中使用比字符串更好的其他东西会更好?

通过 T 而不是字符串来识别连接可能会很好。 也许 IConnectionIdFeature 带有适当的可比性 T?

有意义...将避免不必要的.ToString()调用的分配。

Socket通常有一个非常集中的用途; 它可以更通用吗Connection ? (也匹配ConnectionContext )其中Socket可以是许多连接类型。

例如

public delegate Task ConnectionDelegate(ConnectionContext connection);
public interface IConnectionBuilder
{
    IServiceProvider ApplicationServices { get; }
    IConnectionBuilder Use(Func<ConnectionDelegate, ConnectionDelegate> middleware);
    ConnectionDelegate Build();
}

我喜欢@benaadams Connection 的建议。 命名空间 System.IO.Connection 怎么样?

您能否给出一个引人注目的场景,其中使用比字符串更好的其他东西会更好?

我不确定我可以。 我的想法是连接 id 可能经常被用作散列键,并且使用一些 T 你可以在没有string.GetHashCode调用的情况下逃脱。

如果不是T怎么去int?

我喜欢@benaadams Connection 的建议。 命名空间 System.IO.Connection 怎么样?

使用 System.IO.Connections 避免同名命名空间的类歧义?

您能否给出一个引人注目的场景,其中使用比字符串更好的其他东西会更好?

我的想法是连接 id 可能经常被用作散列键,并且使用一些 T 你可以在没有 string.GetHashCode 调用的情况下逃脱

如果您打算使用具有此值的哈希函数并且您使用自己的T类型作为 Id,则您有责任像在其他任何地方一样覆盖GetHashCode()避免碰撞。 我不明白为什么我们需要强制执行stringint或任何类型。

为什么不让用户使用他们想要的任何类型?

还有, @benaadams 的建议看起来很棒。 通过使用Socket用户期望非常具体的语义,而Connection更抽象并且更适合这些抽象的上下文。

您能否给出一个引人注目的场景,其中使用比字符串更好的其他东西会更好?

有人可能会争辩说 byte[] 在某些情况下会更好,比如当你处理 ip 地址时,如果不是 T,也许这是一种选择

除了字符串之外的其他东西会很好的另一个原因是,如果您有多个连接组件(例如 ip 和端口),我的意思是您当然可以将其编码为字符串,但如果它位于何处,则必须对其进行解析可以将 T 作为“地址” 这将带来很大的灵活性

T ConnectionId让它有点一般讨厌

public abstract class ConnectionContext<T>
{
    public abstract T ConnectionId { get; set; }
    public abstract IFeatureCollection Features { get; }
    public abstract IPipe Transport { get; set; }
}

public interface IConnectionIdFeature<T>
{
    T ConnectionId { get; set; }
}

public interface IConnectionTransportFeature
{
    public abstract PipeFactory PipeFactory { get; set; }
    public abstract IPipe Transport { get; set; }
}

public delegate Task ConnectionDelegate<T>(ConnectionContext<T> connection);

public interface IConnectionBuilder<T>
{
    IServiceProvider ApplicationServices { get; }
    IConnectionBuilder Use(Func<ConnectionDelegate<T>, ConnectionDelegate<T>> middleware);
    ConnectionDelegate<T> Build();
}

也没有编译时强制执行使T中的IConnectionIdFeature与其他任何内容一致; 即使你现在到处都需要它?

还可以通过 IIPAddressFeature 等功能添加“t 的其他内容”

这将是一个字符串。 它更简单,我们已经将字符串用于请求 id 之类的内容。

如果IConnectionTransportFeatureIConnectionIdFeatureConnectionContext必需功能,为什么要复制ConnectionIdTransport属性?

参见HttpContext 。 提升到顶层的属性是最常用的属性,适用于大多数连接实现。 这是一种方便,仅此而已。 在幕后,这些属性的实现直接暴露了特征属性。

@尼诺弗洛里斯

对于 AspNetCore 的旧完整框架技术,我真的不介意更好的名称,更短且不会混淆。 特别是如果它通常是服务器堆栈的引用名称。

你的意思是 ASP.NET 不是,AspNetCore 对吗? 在某一点上,您最终会从纯连接抽象转向 ASP.NET Core 的 http 堆栈(请参阅“ASP.NET Core HTTP 在 ASP.NET Core 套接字内运行”示例)。 您如何称呼作为 HTTP“连接”中间件的桥接包。

也许一个品牌名称可以解决命名问题😄。

@贝纳亚当斯

Socket一般都有一个非常专注的用途; 它可以像连接一样更通用吗? (也匹配ConnectionContext)其中Socket 可以是多种Connection 类型。

我喜欢。 不过,我不确定我是否喜欢程序集名称。 Microsoft.AspNetCore.Connections ? 它会在我身上生长。

这将是一个字符串。 它更简单,我们已经将字符串用于请求 id 之类的内容。

还可以更轻松地使用 System.Diagnostics 的Activity ,例如HttpCorrelationProtocolbyte[]你会重新分配回string

我喜欢。 不过,我不确定我是否喜欢程序集名称。 Microsoft.AspNetCore.Connections? 它会在我身上生长。

它的解释层,也许:

Microsoft.AspNetCore.Protocols ?

Microsoft.AspNetCore.Protocols.Http1 - 特定的 Http1、Http1.1 协议
Microsoft.AspNetCore.Protocols.Http2 - 特定的 Http2 协议
Microsoft.AspNetCore.Protocols.Http - 合并的 Http1+2(协商)
Microsoft.AspNetCore.Protocols.Tls - TLS SocketDelegate 中间件

Microsoft.AspNetCore.Protocol.Abstractions
Microsoft.AspNetCore.Protocol.Http
Microsoft.AspNetCore.Protocol.Tls

@davidfowl我最喜欢这种布局,但为了一致性,我认为它应该是“协议”,就像大多数其他命名空间一样,例如

System.Collections
System.DirectoryServices.Protocols
System.Web.Services.Protocols

一些新库的末尾有 Protocol ,用于单一目的的协议空间,但如果我们在这里有很多:复数对我来说感觉更正确。 对比列表: https :

@davidfowl是的,我的意思是 ASP.NET 变得非常超载。 这些天它的实际 Web 框架部分是什么? The ASP.NET Core 2.0 Web Framework ?

不过,搜索 ASP.NET 2.0 是非常有趣的考古学:
https://www.google.com/search?q=asp.net+2.0

让我感到困扰的是,ASP.NET Core 的名称是由 2 部分平台标识符(.NET 和 Core)组成,而只有一部分是“产品名称”,它实际上并不是服务器堆栈的好名字,只是对来自九十年代,它又长又难打字,年龄正在显现。

现在我们都可以猜到,营销部门喜欢 ASP.NET 对旧卫士的品牌认知(意味着没有冒犯),我知道使用相同的名称可能会帮助那些人找到向 .NET Core 的过渡。 然而,越来越多的重载它没有为任何人提供服务。

我完全错过了几个品牌/代号,我可以参考直接对应于更大堆栈的特定部分的人。 并不总是必须参考附在所述堆栈的精确描述上的长时间超载的雨伞品牌名称。

Kestrel 就是一个非常成功的例子。

对不起,劫持了,有什么指定的地方可以把这个放在桌子上吗?

对不起,劫持了,有什么指定的地方可以把这个放在桌子上吗?

当然,在 aspnet/Home 上提出问题,但老实说,我不确定它会改变什么。 ASP.NET Core 甚至被称为 ASP.NET Core 的事实应该清楚地表明了这一点。 我们有可能在Microsoft.Extensions保护伞下移动一些东西,因为还有其他现有技术。

当然,在 aspnet/Home 上提出问题,但老实说,我不确定它会改变什么。

我不会有任何幻想;) 我知道更名永远不会发生,我所要求的只是在那张鼓起的伞下更加具体。

也许 ASP.NET (Core) 可以作为总称,但程序集可以不同地调用。 Kestrel 就是一个很好的例子。

很难找到这样的名称,因此您最终可能会默认使用 Microsoft.AspNetCore.XXX 作为一个安全的选择。

但我完全赞成这些独特的名字。 它们与众不同且易于研究/参考。

也许 ASP.NET (Core) 可以作为总称,但程序集可以不同地调用。 Kestrel 就是一个很好的例子。

那里没有分歧。

很难找到这样的名称,因此您最终可能会默认使用 Microsoft.AspNetCore.XXX 作为一个安全的选择。

可能,到目前为止,Protocols 的最新建议是我最喜欢的。

但我完全赞成这些独特的名字。 它们与众不同且易于研究/参考。

你的意思是像 kestrel 这样的名字,但代表这些较低的层。 基岩 😄 可能是这样,但这会导致过多的 Flintstones 参考。

我没有看到继续保留在 AspNetCore 命名法中的 kestrel 内容有任何问题,因为它非常属于 ASP.NET 团队及其平台的一部分。 这种变化可能会更多地分离 Kestrel 的组件以添加另一层抽象,但它仍然非常植根于同一个团队/平台。

我认为 Microsoft.Extensions 命名法涵盖了来自多个团队的框架的使用,无论是 Web、控制台、Windows 应用程序还是库。

我的建议是将任何与平台/框架无关的内容移动到 Microsoft.Extensions.* 命名法中,并在可能且有意义的地方。

附带说明一下,我实际上希望用于引导 Web 应用程序的主机提供商不在 AspNetCore 领域,因为有一个服务主机选项,在我看来这更像是一个特定于平台的实现,因为它只需要一个 Windows 系统来运行. 如果它是一个真正的抽象,那就太好了,因为它们下面可以有 systemd 和 upstartd 实现。 似乎那些与 .NET 生态系统更相关,而是成为 System.* 的一部分。 当 Windows 服务不是基于 Web 时,使用服务主机感觉很奇怪。

附带说明一下,我实际上希望用于引导 Web 应用程序的主机提供商不在 AspNetCore 领域,因为有一个服务主机选项,在我看来这更像是一个特定于平台的实现,因为它只需要一个 Windows 系统来运行. 如果它是一个真正的抽象,那就太好了,因为它们下面可以有 systemd 和 upstartd 实现。 似乎那些与 .NET 生态系统更相关,而是成为 System.* 的一部分。 当 Windows 服务不是基于 Web 时,使用服务主机感觉很奇怪。

Microsoft.Extensions.Hosting来。 但这是另一个规范和另一个代号(如果我能想到的话)。 将挑逗作为 2.0 版本的一部分https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.Extensions.Hosting.Abstractions

我已经用新名称更新了规范。

@davidfowl用于托管项目代号/规范,我喜欢 Project Hostess。 就像女主人纸杯蛋糕😄

我在哪里可以找到规范?

根据描述:“OWIN for Connections”,如何调用这个 OCIN?
“.NET 的开放连接/通信接口”?
命名空间:Microsoft.Ocin。

我几乎忽略了那部分,但认为这是一个很好的类比。 我宁愿不称它为 OWIN,因为 ASP.NET Core 具有不是 OWIN 的抽象,并且它也是如此。

但我建议使用“OCIN”,这是一个不同的名字:)

ONIN(用网络代替连接)听起来更好,但我仍然不喜欢它的内涵。

@davidfowl

命名需要一些工作,但套接字不是很好。

我们正在谈论不同类型的客户端 - 服务器通信,那么为什么不Microsoft.AspNetCore.Communication

嗨,您提到了 libuv/IOCP 和明显的旧套接字,您是否考虑使用 RIO?

谢谢。

@wholroyd你想要什么样的抽象来更好地支持 systemd/upstart?

我们有一个指南,演示如何使用 systemd 来保持您的 asp.net 核心应用程序运行和管理日志。 在 2.0.0 中,我们添加了KestrelServerOptions.UseSystemd()以支持 systemd 套接字激活。 至于正常关机,systemd 发送一个 SIGTERM AFAIK,由 Hosting 处理。

我并不是要声称我们不能做更多或提供更好的抽象。 我只是对你的想法感兴趣。

@halter73不知道KestrelServerOptions.UseSystemd() 。 我引用的部分是有一个服务主机(在 https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices/WebHostService.cs),但它是框架具体( IWebHost ),它使用ServiceBase (Windows)。

我喜欢库中使用的托管入口点概念,我只是希望它被抽象到足以与框架无关(更像是IHost - AspNetCore 可以将它进一步抽象为IWebHost )并成为平台不可知(非 Windows)。 我想这意味着要对 .NET 本身进行更改,以使 ServiceBase 可以在非 Windows 系统上使用 - 根据需要挂接到 Systemd/Upstartd/Windows。

有道理?

我认为这是有道理的。 实施类似的方法ServicBase.OnStopIHost.OnStop似乎比写的东西更容易了很多这样的自己。

我可以打开一个问题来请求它。 它应该转到 dotnet/netstandard 吗? @halter73

@whoroyd给它几天时间。 我将很快发布规范。

@davidfowl你认为 Kestrel GitHub 存储库会在新的抽象内容发布后重命名为 KestrelServer 吗?

@shaggygi确定

作为消费者,如果我拉入Microsoft.AspNetCore.Protocols.Http我个人希望 http 0.x 到 http2 及更高版本。 不介意它是一个允许更高级用例的元包(例如:我的服务只支持 http2)。 合并将为新手带来更好的体验(并且不会那么混乱),imo。

期待看到 AMQP 在未来如何适应这个(一般来说,不依赖于 RabbitMQ 等)

命名需要一些工作,但套接字不是很好。

如果是关于传输抽象,您应该将其命名为:

Microsoft.AspNetCore.Transport(s)

@aL3891我现在认为我们也需要支持客户。

我只是注意到这已移至 v2.2。
但这将如何与即将推出的 SignalR(使用 ASP.NET 2.1)兼容?

Bedrock 和 SignalR 之间有很多重叠,因此它们共享一些抽象层是理想的。

编辑:例如,他们都定义了一个ConnectionContext类,它的作用基本相同。

“SignalR”是指作为 SignalR 存储库一部分的较低级别的库,例如Microsoft.AspNetCore.Sockets.Abstractions

@MuleaneEve这是故意的。 计划是在 SignalR 中使用协议抽象并删除 sockets.abstractions。

我们今天做了一些决定:

  • 我们将在 2.1 中保留传输层公共性(就像在 2.0 中一样)。 我们认为有向现有抽象添加客户端的空间,因此我们还不想将 API 一成不变。 仍然可以编写传输,但 API 将在 2.2 中更改并公开。
  • 这将是一个多版本的努力。 在 2.1 中,我们将着眼于在 2.2(HttpParser,处理 Http 的基类)中公开更多的 kestrel 内容作为公共 API,以构建高效的专用服务器(参见 https://github.com/davidfowl/PlatformLevelTechempower/blob/ 944597f9ad196d3a333b837fb8c62a7304d5f9d2/ServerWithKestrel2.1/WebSocketConnection.cs)
  • 我们今天进行了 API 审查,并将重命名一些内容:

中间件

Microsoft.AspNetCore.Connections.Http - 有 HttpConnectionHandler (今天这是 Kestrel 的内部)
Microsoft.AspNetCore.Connections.Tls - TLS 连接中间件
Microsoft.AspNetCore.Connections.Logging - 记录连接中间件

协议抽象

Microsoft.AspNetCore.Protocol.Abstractions -> Microsoft.AspNetCore.Connections.Abstractions

将 EndPoint 移动到 Connections.Abstractions 并将其重命名为 ConnectionHandler。

C# public abstract ConnectionHandler { Task OnConnectionAsync(ConnectionContext connectionContext); }

考虑到我们离 2.1 版本有多近,这可能是最好的解决方案。

需要明确的是,这是否意味着这里的 Connections 层和 SignalR 中的 Sockets 层现在也将是内部的?

顺便说一下,我喜欢_Connections_这个名字。

需要明确的是,这是否意味着这里的 Connections 层和 SignalR 中的 Sockets 层现在也将是内部的?

不,它将是公开的。

好的。 您是否查看过我发布的点对点示例
我希望这些场景会得到支持。

@KPixel是的,我已经看过了,但 TBH 我不知道您打算如何使用连接抽象。

连接和套接字层(大部分)是最终的吗?

我将使用它们重写此示例和我的应用程序,以查看我遇到的问题。

连接和套接字层(大部分)是最终的吗?

现在都是连接,客户端 API 还不是最终版本。 我非常有信心 ConnectionContext API 不会产生太多变化。 不过,我们将向其中添加更多内容并重命名包和命名空间。

@KPixel我更深入地研究了一下,这看起来很有趣,有几个问题:

  • 我们目前没有任何用于 udp 或非流式传输的东西。 这在过去出现过,但尚未充实。
  • 当前的 API 模式意味着您会被回调,因此跨绑定将数据绑定在一起意味着您必须以某种方式传递状态。 您可以使用 DI 或任何其他状态共享机制来做到这一点。

@davidfowl感谢您的浏览。

我也在研究新的层……明天,我将创建一个新问题来继续这个讨论。

基岩更新(2018 年 3 月 28 日,星期三)

协议抽象(基本 API 在 2.1 中全部公开)

  • Microsoft.AspNetCore.Connections.Abstractions

```C#
公共抽象类 ConnectionContext
{
公共抽象字符串 ConnectionId { get; 放; }

public abstract IFeatureCollection Features { get; }

public abstract IDictionary<object, object> Items { get; set; }

public abstract IDuplexPipe Transport { get; set; }

}

公共接口 IConnectionBuilder
{
IServiceProvider ApplicationServices { 获取; }

IConnectionBuilder Use(Func<ConnectionDelegate, ConnectionDelegate> middleware);

ConnectionDelegate Build();

}

公共委托任务 ConnectionDelegate(ConnectionContext connection);

公共抽象ConnectionHandler
{
任务 OnConnectionAsync(ConnectionContext connectionContext);
}

### Remaining 2.1 work

- Figuring out how to merge use `ConnectionContext` as the client abstraction (SignalR needs this).
- Adding support for aborting the connection (a first class Abort method) semi related to the first bullet https://github.com/aspnet/KestrelHttpServer/issues/2054

### 2.2 and beyond

- Nothing specifically planned at this layer besides adding more feature interfaces

## Kestrel specific transport layer (pubternal in 2.1)

- **Microsoft.AspNetCore.Kestrel.Transport.Abstractions** - Required to implement a kestrel transport
- **Microsoft.AspNetCore.Kestrel.Transport.Libuv** - Libuv implementation
- **Microsoft.AspNetCore.Kestrel.Transport.Sockets** - Sockets implementation

3rd party implementations:

- **RedHatX.AspNetCore.Server.Kestrel.Transport.Linux** - https://github.com/tmds/kestrel-linux-transport - Native epoll transport for linux

The transport layer remains pubternal in 2.1 because we think there might be some bigger design
changes we want to make (see 2.2 and beyond for details).

## Remaining 2.1 work

We may add support for Abort on the `ConnectionContext` and will need to implement it at the transport layer.

## 2.2 and beyond

- Make the API public
- Support for clients (libuv client/sockets client)
- Potentially share abstractions for Kestrel's TCP transports and SignalR's HTTP based transports
- Design changes around who creates the Pipe (see https://github.com/aspnet/KestrelHttpServer/issues/2429)

## Kestrel Core (ASP.NET IServer implementation)

Even though the transport layer itself is pubternal in 2.1, consuming the IConnectionBuilder
from Kestrel is public. This is what our platform techempower benchmark is built on.

```C#
public class Program
{
    public static void Main(string[] args)
    {
        var host = WebHostBuilder.CreateDefaultBuilder(args)
            .UseKestrel(options =>
            {
                options.Listen(IPAddress.Loopback, 9001, builder =>
                {
                    // Log all of the bytes as they are sent and received
                    builder.UseConnectionLogging();

                    // Connection builder API is exposed here
                    builder.UseConnectionHandler<ChatHandler>();
                });

                options.Listen(IPAddress.Any, 8004, builder => 
                {
                    // Using hubs bound to TCP
                    builder.UseHub<Chat>();
                });
            })
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

2.2 及以后

  • 进行适当的更改,以便连接中间件在关闭时正常工作
    和连接管理。
  • 弃用连接适配器并将其替换为连接中间件。
  • 将 Kestrel 的 TCP 堆栈与 ASP.NET 的 IServer 实现分离,使其可以直接在 HostBuilder(而不是 WebHostBuilder)中使用。

连接中间件

  • Microsoft.AspNetCore.Connections.Http - 有 HttpConnectionHandler
  • Microsoft.AspNetCore.Connections.Tls - TLS 连接中间件
  • Microsoft.AspNetCore.Connections.Logging - 记录连接中间件

这些是今天存在于 kestrel 中的连接适配器,需要移植到中间件。

2.2 及以后

  • 实际实现连接中间件

信号R

  • Microsoft.AspNetCore.Http.Connections - 用于公开 IConnectionBuilder 的基于 ASP.NET Core HTTP 的传输和 API
  • Microsoft.AspNetCore.Http.Connections.Common - 服务器和客户端之间的共享代码
  • Microsoft.AspNetCore.Http.Connections.Client - 3 种传输(Websockets、LongPolling、ServerSentEvents)上的连接抽象

```C#
公开课启动
{
public void ConfigureServices(IServiceCollection 服务)
{
服务.AddConnections();
}

public void Configure(IApplicationBuilder app)
{
    app.UseConnections(routes =>
    {
        routes.MapConnections("/chat", builder => 
        {
            // Connection builder API is exposed here
            builder.UseConnectionHandler<ChatHandler>();
        });

        routes.MapConnections("/mqtt", builder => 
        {
            // Log all of the bytes as they are sent and received
            builder.UseConnectionLogging();

            builder.UseConnectionHandler<MQTTHandler>(options => 
            {
                // Restrict to websockets only
                options.Transports = TransportType.WebSockets;

                // Specify the subprotocol
                options.SubProtocol = "mqttv3.1";
            });
        });

        // Shortcut to directly map a single connection handler
        routes.MapConnectionHandler<NotificationHandler>("/notifictions");
    });
}

}

```C#
var connection = new HttpConnection(new Uri("http://localhost:8001"));
await connection.StartAsync();

var result = await connection.Transport.Input.ReadAsync();
await connection.Transport.Output.WriteAsync(result.Buffer.ToArray());

await connection.DisposeAsync();

剩下的工作

  • 包是否重命名(进行中)
  • 使用 ConnectionContext 作为客户端 API(统一客户端和服务器连接对象)

2.2 及以后

  • 一流的 TCP 支持

    • SignalR 将在 Kestrel 现有的 2.1 版本的服务器端使用纯 TCP

      连接构建器。

    • 我们需要一个一流的客户运输故事。 有关更多详细信息,请参阅 Kestrel.Core 传输抽象部分。

  • 可能是其他有意义的传输。

SignalR 2.2 -> 一流的 TCP 支持

我想早点使用它来启动 mqtt 传输,但看起来这必须等待更长的时间

我想早点使用它来启动 mqtt 传输,但看起来这必须等待更长的时间

运输究竟是为了什么? SignalR TCP 支持更多是官方声明,我们没有明确针对 2.1 进行处理,但它可以工作,并且不会有客户端支持(您可以从自定义 TCP 客户端发送有效负载)。 但是,我们正在提供实现任何服务器端协议(客户端在途中)所需的 API。

我想为信号器构建一个 mqtt 传输,以便我可以使用集线器编程模型作为我的 mqtt 代理

我想为信号器构建一个 mqtt 传输,以便我可以使用集线器编程模型作为我的 mqtt 代理

只是要清楚,websockets 或 tcp 是传输对吗? 您想使用 Mqtt 数据包描述集线器调用吗? 听起来你想写一个 IHubProtocol
在 SignalR 中,这是一个自定义集线器协议https://github.com/aspnet/SignalR/blob/2f9942e1f20ff6b76542900eadd5828a2b61957a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocolcs. 但如果你能进一步澄清那就太好了

@davidfowl我很高兴看到 2.2 路线图上的客户端(传出 TCP)支持。 我在思考如何处理客户端连接并使传输在 Kestrel 之外更可用。
纸张设计:
C# interface IIOService { Task<IDuplexPipe> ConnectTcpAsync(string host, int port); IAsyncDisposable AcceptOnTcp(IPAddress address, int port, Action<IDuplexPipe> onAccept); }
相关(从实现的角度来看)是这个开放问题https://github.com/aspnet/KestrelHttpServer/issues/1587允许端点由相同的 LibuvThreads 处理。

当然,由于传输抽象的 API 形状仍然不是一成不变的(公共 API 属于这一类别),我们可以对设计进行迭代。 我认为那个特定的 API 形状太小了,传输需要的不仅仅是双工管道。

我绝对知道我在这里很密集,但我对在 Kestrel 中拥有 TCP 传输和/或自定义协议意味着什么感到有些困惑(因为我一直认为 Kestrel 是 TCP/HTTP)。

在那种情况下,我决定使用 TCP 传输并编写自定义协议(让我们假设在本示例中暂时没有 SignalR),Kestrel 本身在做什么工作? 这种情况与使用旧的 TcpListener 类似,还是这些抽象给我的更多?

对不起,这个愚蠢的问题,所有人。

在那种情况下,我决定使用 TCP 传输并编写自定义协议(让我们假设在本示例中暂时没有 SignalR),Kestrel 本身在做什么工作?

Kestrel 是粘合剂,它连接传输层,处理连接管理和超时,正常和不正常的连接关闭。

这种情况与使用旧的 TcpListener 类似,还是这些抽象给我的更多?

连接抽象将您与底层传输分离。 您的协议解析只是从管道中获取字节,而这些字节来自何处并不重要。 您没有绑定到 TCP,这意味着您可以使用简单的内存管道轻松测试您的协议解析层,该管道手动推送字节(基本上在内存传输中)。

听起来很棒大卫,谢谢!

我正在编写有关管道和连接的

image

目前,TCP 传输在 Kestrel 中,WebSockets(和其他)传输在 SignalR 中。
他们有自己的内部调度员。

如果我正确理解了 Project Bedrock,2.2 中的下一步将围绕重构这些传输和调度程序,以便我们可以开发使用它们的应用程序,而无需依赖 SignalR 或 Kestrel。 正确的?

从我的角度来看,总是需要 kestrel,但在它上面会有更好的分层。 所以你可以这样做:
tcp > [TLS] > http > aspnet
tcp > [TLS] > http > 信号器
tcp > [TLS] > mqtt > [signalr]
tcp > 你自己的东西

我正在编写有关管道和连接的教程,但我被卡住了,因为目前很难解释连接库而不将其与 SignalR 或 Kestrel 联系起来。

这是两位主持人,您期待什么? Dispatchers 需要存在才能让你真正运行构建在连接之上的框架。 第 3 种类型的调度程序是内存测试连接中的手册。 在这里新建连接处理程序并传入测试ConnectionContext

目前,TCP 传输在 Kestrel 中,WebSockets(和其他)传输在 SignalR 中。
他们有自己的内部调度员。

这是正确的设计。 也可能有一个纯粹的 websockets 调度程序,但没有人需要它,所以它没有完成。

如果我正确理解了 Project Bedrock,2.2 中的下一步将围绕重构这些传输和调度程序,以便我们可以开发使用它们的应用程序,而无需依赖 SignalR 或 Kestrel。 正确的?

不完全是,这绝对低于其他事情的优先级。 2.2 的要点是完成 kestrel 的传输抽象并使其成为正确的公共 API(对于客户端和服务器)。

@KPixel你在哪里挂断电话? 依赖抽象的框架不关心它们运行在什么调度程序上。 SignalR 不知道托管它的内容以及为什么它可以在 TCP 或 WebSockets、SSE 或长轮询上工作。

@JanEggers

从我的角度来看,总是需要 kestrel,但在它上面会有更好的分层。 所以你可以这样做:
tcp > [TLS] > http > aspnet
tcp > [TLS] > http > 信号器
tcp > [TLS] > mqtt > [signalr]
tcp > 你自己的东西

没错,当我们完成设计时,我们将看到 Kestrel 传输层最终是否独立,但这将是良好设计的额外奖励。

我们将看看 Kestrel 传输层是否最终是独立的

这基本上就是我的意思。
所以,你回答了我的问题:)

现在 Microsoft.AspNetCore.Connections.Abstractions 已发布,我有疑问:

为什么它依赖于 Microsoft.AspNetCore.Http.Features?

如果它应该可用于普通的 tcp 为什么我需要 http 功能?

还有 tls 中间件/什么存储库/包名是什么的任何代码?

最后我想对 mqttnet 使用新的抽象。 该库的作者关注将 aspnetcore 依赖项更新到 2.1。 所以我想只依赖 System.IO,Pipelines 是一个好主意,因为它向后兼容 netstandard 1.3 并且根本不需要 kestrel。 所以问题是:tls 层是仅依赖于 System.IO.Piplines 还是位于连接抽象之上? 如果它依赖于连接,连接抽象是否有可能与 NetStandard1.3 兼容,也可能在其更高版本中?

为什么它依赖于 Microsoft.AspNetCore.Http.Features?

特征集合。 不幸的是,这是所有罪恶中较小的:

  1. 创建一个新的抽象,它是特征集合但不是 IFeatureCollection
  2. 输入到另一个程序集(这仍然是一个选项),但它不会修复命名空间
  3. 只需参考程序集。

我们选择了 3. 2 仍然可以以大多数非破坏性的方式进行,但它不会修复类型名称(命名空间将是 http)。

还有 tls 中间件/什么存储库/包名是什么的任何代码?

它还不存在。 它将在此存储库中。

最后我想对 mqttnet 使用新的抽象。 该库的作者关注将 aspnetcore 依赖项更新到 2.1。 所以我想只依赖 System.IO,Pipelines 是一个好主意,因为它向后兼容 netstandard 1.3 并且根本不需要 kestrel。

作者所说的 ASP.NET Core 2.1 是指 netstandard 2.0 对吗?

所以问题是:tls 层是仅依赖于 System.IO.Piplines 还是位于连接抽象之上? 如果它依赖于连接,连接抽象是否有可能与 NetStandard1.3 兼容,也可能在其更高版本中?

连接抽象。 也许吧,但我们要求至少以 netstandard 2.0 为目标。

作者所说的 ASP.NET Core 2.1 是指 netstandard 2.0 对吗?

如果我依赖 Connection.Abstractions,那么该包的使用者需要将 kestrel 更新到 2.1,否则没有用于挂钩连接处理程序的监听选项,或者我错过了什么? 我不能在 Kestrel 2.0 上做到这一点,或者我可以吗?
https://github.com/JanEggers/MQTTnet/blob/732ede1f2475610b8a181635a571210716a3da9f/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs#L16

https://github.com/JanEggers/MQTTnet/blob/732ede1f2475610b8a181635a571210716a3da9f/Frameworks/MQTTnet.AspnetCore/ConnectionBuilderExtensions.cs#L7 -L9

谢谢澄清!

您需要 ASP.NET Core 2.1 才能将ConnectionHandler与 Kestrel 一起使用。

我考虑使用Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions的 API 开发 FTP 服务器,因为它看起来(几乎)完美匹配。 这个 API 在 2.2 中会有什么变化? 它对非 HTTP 服务器的开发是否有用?

@fubar-coder 我会直接使用 Kestrel,而不是传输抽象层。

@davidfowl开发非 HTTP 服务的起点是什么? 我考虑M.ANC.S.K.Transport.Abstractions是为了避免所有那些 HTTP(S) 特定代码。

我正在尝试了解您需要实现什么才能在 Kestrel 中使用连接抽象。 查看@JanEggers MQTTnet,您似乎需要实现ConnectionHandler 和ConnectionContext。 还有什么?

@b3nt0就是这样,其他一切都取决于您的协议或您正在适应的库。 严格地说,您甚至不需要 ConnectionContext 您可以将所有代码放在 ConnectionHandler 类中。 我最缺少的是宣布的客户端支持,因为 2.2 必须将信号器样本中的内容复制到 polyfill

@davidfowl我想从传输层获取一些特定信息。 例如有关 Socket.Handle 的一些信息并将其带到应用程序层。 我可以用这个模型做吗? 或者我需要使用 http 解析器和许多其他工作创建自己的 http 服务器?

关于应用程序的更多信息:
我想听 HttpRequests,从传入的套接字连接中获取一些特定信息,并根据此信息将请求路由到不同的 webapi 应用程序,然后从 webapi 获取响应并将它们路由回客户端。
我知道这是非常具体的情况,但对我来说非常重要。

scheme

伪代码

var _incomingConnection = await HandleConnection();

var _info = GetSpecificInfo(incomingConnection.IncomingSocket.Handle);

while (true)
{
    var httpRequest = await _incomingConnection.ReadHttpRequest();

    switch (_info)
    {
        case _:
            await SendHttpRequestToWebApi5001(httpRequest);
            break;
        case _:
            await SendHttpRequestToWebApi5002(httpRequest);
            break;
    }

    var response = await ReceiveResponse();
    await SendHttpResponseToClient(response);
}

当然,您想摆脱哪些信息?

@davidfowl非常快,谢谢:)
在我们的项目中,我们在标准 Linux 上使用带有自定义安全策略的类似 debian 的操作系统。 它使用自定义子系统在用户、文件系统、套接字等上设置安全标签。

我使用非托管库从 Socket.Handle 中获取安全标签,在简单的 tcp 测试项目中它运行良好。 但是我需要正确地将 httprequest 和 httpresponse 路由到我的 webapi - 这是更复杂的任务。
如果我可以使用这个模型,我可以把我的路由逻辑放在哪里?

@davidfowl我查看了源代码以了解它的模型是如何工作的。 如果我错了,请纠正我。

传输层处理连接,然后调度程序处理它们,直到中间件。 在应用程序代码中,我可以使用来自 HttpContext.Features 的这个连接。

image

如果我是正确的,那么在我的情况下,我可以访问 SocketTransport 中的套接字对象,然后将我的安全标签放在 socketconnection 上。
为此,我需要修改现有的SocketTransportSocketConnection 。 路由逻辑放入自定义中间件。
这是正确的方法吗? 或者我可以通过另一种方式访问​​ incomig 套接字连接?

很抱歉我超出了讨论范围。

没错。 我们需要公开一个暴露套接字句柄的新特性。 然后你就可以写出你想写的逻辑了。

我们需要公开一个暴露套接字句柄的新特性。 然后你就可以写出你想写的逻辑了。

那会很好。 这需要什么?
我可以帮忙吗?

@westfin是的! 您可以提交一个问题,指定与您在此处所做的相同的事情,我们可以提出一个公开底层套接字句柄的功能,然后您可以发送 PR。

@davidfowl虽然我理解项目#bedrock 是允许非 HTTP 协议实现成为 AspNetCore 框架一部分的工作,但是否有一系列协议可以/可以被视为一等公民,即。 SFTP、FTP 和 FTPS

你可以看看我的示例网站: https :
您可以在这里做的是您可以动态连接/创建集线器,而不是静态集线器定义;
wss://wsecho.azurewebsites.net/hub/XYZ.....
您可以使用不同的集线器进行不同的连接,而不是侦听不同的端口。

SignalR v1 集线器实现很糟糕,v2 改进了但仍然难以实现。
使用 Kestrel,我为集线器创建了列表,基本上它是一个列表。 每当它接收到新的集线器时,它就会添加到列表中,我相应地修改了所有方法。

PS:有时 Kestrel 应用程序崩溃,因为 Kestrel 中的错误,此站点使用 Kestrel 的第一个版本。 稍后我会升级它。

@davidfowl自 2.2 版发布以来有任何更新吗?

自从2.2出来了?

🤔 还没想好?

@JanEggers看起来像,但只是标记为 2.2.0 找不到任何版本?

无论如何,我只是希望得到一些专门关于 Connections.Abstractions 的客户端实现的消息。

不,我们在 2.2 中没有取得任何进展

非常难过:( 我告诉开发人员等待 2.2,您将能够删除直接与套接字一起使用的丑陋代码。

嗯,实际上,您今天可以使用一个公共 API,它只是在当前状态下与 Kestrel 相关联。

@davidfowl我尝试直接使用 KestrelServer 类来实现类似 tcp 回显服务器的功能。 问题是它仍然与 HTTP 耦合。 当我从浏览器发送请求时,它有点工作。 但是当使用 telnet 时,它会关闭连接并且不保留它。 我认为这是因为某些强制性 HTTP 标头未发送或仅因为它依赖于请求 -> 响应而没有保持持久连接而丢弃它。 如果您可以共享一个示例,其实现类似于您在此处的实现https://github.com/davidfowl/TcpEcho,但使用 Kestrel 那就太好了。

3.0有进展吗?

我想移植https://github.com/AceHack/MultiplexedWebSockets以任何最有意义的方式使用基础。 我有一个正在使用https://github.com/Microsoft/bond的版本,有什么建议吗?

@davidfowl我真的很喜欢你的例子的简单 > 见https://github.com/davidfowl/MultiProtocolAspNetCore

关于如何为未与 HTTPS 耦合的事物(例如,使用 TLS 对其数据传输进行加密的 TCP 设备)实施 TLS 的任何提示或提示?

在此的WIP PR

也许 Bedrock 可以成为 Microsoft.Extensions 库和 TLS 可以成为该管道的一部分(具有客户端支持),例如:Microsoft.Extensions.{Transport,Connection,Networking}.Abstractions。

除了上面@davidfowl指定的内容之外,以下是我正在使用的核心接口:

```C#
// 客户端
公共接口 IConnectionFactory
{
任务ConnectAsync(string endPoint);
}

// 服务器端
公共接口 IConnectionListenerFactory
{
IConnectionListener Create(string endPoint, ConnectionDelegate connectionDelegate);
}

公共接口 IConnectionListener
{
任务 BindAsync();
任务 UnbindAsync();
任务停止异步();
}
``

这些可能会发生变化,并且在这些名称中,“运输”可能比“连接”更合适。

ASP.NET 使用IEndpointInformation接口而不是我的 PR 当前使用的string接口。 我没有强烈的意见,但IEndpointInformation对我来说感觉很尴尬。 我们可能会在合并之前改变它。

是否正确,当我想使用 TLS 时,必须执行以下步骤:

  1. 将管道包裹成流
  2. 使用 SslStream
  3. 将流包裹到管道中

我希望我可以避免这种管道 <-> 流 <-> 管道转换。

关闭这个是因为基岩的核心在 Kestrel。 我们仍然有一些我们想要做出的反应(例如#4623),但这些反应应该在单独的问题中进行跟踪。

此页面是否有帮助?
0 / 5 - 0 等级