Aspnetcore: Проект Бедрок

Созданный на 4 авг. 2017  ·  126Комментарии  ·  Источник: dotnet/aspnetcore

Проект Бедрок

В основе проекта лежит дальнейшее разделение компонентов Kestrel, чтобы мы могли использовать его в качестве основы для нашего сетевого стека, не связанного с HTTP.
Мы хотим развить примитивы, шаблоны и сквозные проблемы, существующие сегодня в приложениях ASP.NET Core. Цель состоит в том, чтобы позволить фреймворкам более высокого уровня (например, SignalR или WCF и даже самому ASP.NET Core) строить поверх абстракций, которые не привязывают их к конкретной реализации соединения (OWIN для Connections). Например, он позволяет SignalR работать как поверх TCP, так и через веб-сокеты, не понимая, что такое базовый транспорт. Мы также хотим позволить создавать необработанные серверы протоколов низкого уровня для обработки таких вещей, как MQTT для сценариев IOT.

В этой модели программирования на стороне сервера есть 3 основных участника:

  • Applications / Middleware / Frameworks - код приложения, который обрабатывает соединения и реализует логику анализа протокола или другую логику, изменяющую поток данных (например, http, TLS).
  • Транспорты - Транспорты предоставляют реализацию IFeatureCollection которая реализует базовую семантику соединения. Короче говоря, транспорты предоставляют конкретную реализацию ConnectionContext которая проходит через диспетчер к приложению.
  • Диспетчеры . Диспетчер - это компонент, который объединяет транспортный уровень и уровень приложения. Его задача - управлять временем жизни транспортного соединения и приложения, работающего поверх него. Диспетчер предоставит IConnectionBuilder для конкретной привязки, относящейся к транспорту. Например, диспетчер http будет отображать IConnectionBuilder на основе определенного маршрута, а диспетчер TCP отобразит IConnectionBuilder на основе IP-адреса и порта.

Приложения / Промежуточное ПО / Фреймворки

В центре этой работы - новый набор примитивов, которые представляют базовое соединение:

`` С #
открытый абстрактный класс ConnectionContext
{
общедоступная абстрактная строка ConnectionId {получить; установленный; }

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; }
}

`` С #
открытый интерфейс IConnectionTransportFeature
{
IDuplexPipe Transport {get; установленный; }
}

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

ConnectionContext - это «HttpContext» юниверса подключения. Это абстракция, представляющая постоянное соединение некоторой формы. Это могло, это может
быть TCP-соединением, соединением websocket или чем-то более гибридным (например, соединение, реализованное по недуплексному протоколу, например, события, отправленные сервером + сообщения http). Коллекция функций
существует по той же причине, что и на HttpContext , сервер или различные части "промежуточного программного обеспечения" могут добавлять, дополнять или удалять функции
от связи, которая может обогатить лежащую в основе абстракцию. Две обязательные функции - это IConnectionTransportFeature и IConnectionIdFeature .

Далее мы представляем абстракцию для выполнения соединения.

`` С #
общедоступный делегат Task ConnectionDelegate (соединение ConnectionContext);

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 и ведение журнала подключений, могут быть отдельными компонентами промежуточного программного обеспечения.
  • SignalR будет построен поверх этого, что позволит запускать SignalR в любой инфраструктуре, основанной на подключении.

Транспорт

Транспорты отвечают за предоставление начальной реализации IFeatureCollection для соединения и предоставление потока байтов приложению.

Libuv и System.Net.Sockets

Сегодня у нас есть 2 реализации транспорта, которые находятся в Kestrel: реализация System.Net.Sockets и libuv. Мы планируем сохранить эти 2, потому что они оба предлагают разные наборы функций. Libuv может прослушивать дескрипторы файлов, именованные каналы, сокеты домена unix и сокеты tcp, в то время как System.Net.Sockets просто имеет реализацию сокета tcp (и сокеты домена unix)

WebSockets

Мы хотим, чтобы люди могли создавать фреймворки на основе веб-сокетов, не имея дело с низкоуровневыми деталями, такими как управление соединениями и буферизация. Таким образом, мы предоставим транспорт веб-сокетов, который предоставляет эти примитивы подключения. В настоящее время он находится в пакете Microsoft.AspNetCore.Http.Connectons .

Другие HTTP-транспорты

SignalR в прошлом исторически предоставлял несколько транспортных реализаций для браузеров, которые не поддерживали веб-сокеты. Это не полнодуплексный транспорт, но они реализованы как таковые путем циклического переключения идентификатора соединения по HTTP-запросам. Мы также предоставим реализации транспортов для длинных опросов и событий, отправленных сервером. Эти реализации потребуют специальной клиентской библиотеки, которая понимает лежащий в основе недуплексный протокол. В настоящее время они находятся в пакетах Microsoft.AspNetCore.Http.Connectons и Microsoft.AspNetCore.Http.Connectons.Client .

QUIC

QUIC - это быстро развивающийся стандарт, который стремится улучшить воспринимаемую производительность ориентированных на соединение веб-приложений, которые в настоящее время используют TCP. Когда появится QUIC, мы захотим иметь возможность поддерживать его с той же абстракцией.

Диспетчеры

ASP.NET Core

ASP.NET Core будет служить основой для нашего диспетчера HTTP. Будет реализация RequestDelegate которая будет служить диспетчером поверх маршрутизации.

`` С #
с помощью Microsoft.AspNetCore.Builder;
с использованием Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using SocketsSample.EndPoints;
using SocketsSample.Hubs;

пространство имен SocketsSample
{
открытый класс Startup
{
public void ConfigureServices (службы IServiceCollection)
{
services.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

Самый полезный комментарий

Было бы действительно здорово иметь что-то эквивалентное Transports на стороне клиента, чтобы вы могли иметь более абстрактный HttpClient с переключаемым базовым транспортным механизмом.

Все 126 Комментарий

Было бы действительно здорово иметь что-то эквивалентное Transports на стороне клиента, чтобы вы могли иметь более абстрактный HttpClient с переключаемым базовым транспортным механизмом.

@davidfowl, что вы думаете о

@davidfowl Отличная работа! Меня беспокоит только одно ...

Поскольку абстракции не будут работать только с aspnet, не думаете ли вы, что вместо использования Microsoft.AspNetCore.Sockets.Abstractions мы могли бы использовать только Microsoft.Sockets.Abstractions для основных абстракций?

Я согласен с тем, что абстракции Kestrel и AspNet должны иметь соответствующие имена, но я думаю, что эти абстракции очень ... абстрактны и, как вы упомянули, предназначены для подключения и управления примитивами очень низкого уровня.

Отличная работа! Жду этого с нетерпением! :)

Точно так же Microsoft.AspNetCore.Sockets.Tls => Microsoft.Sockets.Tls имеет смысл, но мне нужна эта функция больше, чем имя.

@davidfowl Что, если бы нам нужно было читать данные с USB или последовательных портов вместо сокетов, будет ли это сценарий, в котором нам нужно будет создать определенный транспорт?

@ dls314

но мне нужна эта функция больше, чем название.

Я тоже. Но я бы хотел, чтобы семантика пакета была более ясной. Лучше предложить сейчас, чем после релиза :)

@shaggygi

Что, если бы нам нужно было читать данные с USB или последовательных портов вместо сокетов, будет ли это сценарий, в котором нам нужно будет создать определенный транспорт?

Я предполагаю, что это цель транспорта.

По крайней мере, это то, что я понял из этой части:

Транспорты предоставляют реализацию IFeatureCollection, которая реализует базовую семантику соединения .

Означает ли это, что вы можете продвигать транспорт сообщений (msmq, rabbitMq, kafka) дальше по стеку? Я полагаю, что эти транспорты будут находиться на том же уровне абстракции, что и SignalR ....

@ aL3891

Было бы действительно здорово иметь что-то эквивалентное Transports на стороне клиента, чтобы вы могли иметь более абстрактный HttpClient с переключаемым базовым транспортным механизмом.

Я тоже думал об истории клиента, которая согласуется с этим. SignalR имеет начало, но я исключил его из этой спецификации.

@galvesribeiro

Поскольку абстракции не будут работать только с aspnet, не думаете ли вы, что вместо использования Microsoft.AspNetCore.Sockets.Abstractions мы могли бы использовать только Microsoft.Sockets.Abstractions для основных абстракций?

Это то, с чем мы боролись в прошлом, но AspNetCore будет означать больше, чем просто наш существующий стек HTTP, это стек сервера в целом. Мы не будем ничего помещать в корневое пространство имен (например, Microsoft.Sockets). Тем не менее, для именования нужно немного поработать, сокеты не очень хороши.

@shaggygi

@davidfowl Что, если бы нам нужно было читать данные с USB или последовательных портов вместо сокетов, будет ли это сценарий, в котором нам нужно будет создать определенный транспорт?

Да, это был бы транспорт.

@ no1melman

Означает ли это, что вы можете продвигать транспорт сообщений (msmq, rabbitMq, kafka) дальше по стеку? Я полагаю, что эти транспорты будут находиться на том же уровне абстракции, что и SignalR ....

Я не совсем понимаю вопрос. Транспорт может быть любым, но я бы не стал реализовывать HTTP через шину сообщений 😄.

Я просто подумал, что вы можете сделать очередь сообщений в качестве транспорта, как и в случае с signalR, тогда вы абстрагируетесь от механизма.

@davidfowl, хорошо, если теперь AspNetCore станет отсылкой ко всем серверным технологиям в .Net, а не только к веб-стеку, я за них! :)

Меня очень огорчает полное отсутствие упоминаний о Флинтстоунах в этом номере.

если теперь AspNetCore станет отсылкой ко всем серверным технологиям в .Net, а не только к веб-стеку, то я за них! :)

Асинхронная мощность обслуживания

@ no1melman

Я просто подумал, что вы можете сделать очередь сообщений в качестве транспорта, как и в случае с signalR, тогда вы абстрагируетесь от механизма.

SignalR не делал очередь сообщений транспортом, это были принципиально разные абстракции.

@davidfowl

Тем не менее, для именования нужно немного поработать, сокеты не очень хороши.

Microsoft.AspNetCore.Bungholes

Я действительно не возражал бы против лучшего названия, короче и без путаницы, для старой технологии полного фреймворка для AspNetCore. Особенно, если это будет ссылочное имя для стека серверов в целом.

Что касается названия, я согласен с тем, что, учитывая, насколько низкоуровневым и повсеместным будет этот API, удаление «AspNetCore» является хорошей идеей.

Я думаю, что наиболее подходящим ключевым словом для описания этого является «Сеть».
Так, может быть, Microsoft.Network?
Или просто Microsoft.Net (например, System.Net), но звучит как «Microsoft .NET» :)

Microsoft.Network

Что ж ... это было бы не совсем верно, абстракция транспорта довольно гибкая; так что вы можете написать stdin / out или транспорт файлового потока и конвейер для программы или читать и писать http из файлового потока. Или примеры ранее, это может быть USB или последовательный порт ...

Транспорт похож на водителя

Microsoft.Bedrock? :)
Это крутое имя, имо

Это также может быть Microsoft.Transport, тоже концептуально подходит неплохо.

Сеть - также довольно общий термин за пределами информатики. Одно из его определений: «Группа или система взаимосвязанных людей или вещей».
Итак, когда вы связываете что-то с чем-то другим, вы создаете сеть.

Было бы неплохо идентифицировать соединения по T вместо строки. Возможно, IConnectionIdFeatureс правильно сопоставимым T?

Я предполагаю, что ConnectionId - это строка, упрощающая ее передачу.
Если вы сделаете это T, вам нужно будет предоставить Comparer (как вы упомянули), а также сериализатор. Это большая сложность.
Можете ли вы дать убедительный сценарий, в котором было бы намного лучше использовать что-то еще, чем строку?

Было бы неплохо идентифицировать соединения по 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();
}

Мне нравится предложение о подключении

Можете ли вы дать убедительный сценарий, в котором было бы намного лучше использовать что-то еще, чем строку?

Я не уверен, что смогу. Я думаю, что идентификатор соединения может часто использоваться как хеш-ключ, и с некоторым T вы можете обойтись без вызова string.GetHashCode .

Если не T, как насчет перехода к int?

Мне нравится предложение о подключении

Избежать неоднозначности класса одноименного пространства имен с помощью System.IO.Connections?

Можете ли вы дать убедительный сценарий, в котором было бы намного лучше использовать что-то еще, чем строку?

а также

Я думаю, что идентификатор соединения часто может использоваться как хэш-ключ, и с некоторым T вы можете обойтись без вызова строки.

Если вы собираетесь использовать хеш-функцию с этим значением и используете свой собственный тип T в качестве идентификатора, вы обязаны переопределить GetHashCode() как и везде, где бы вы и хотели избегать столкновений. Я не понимаю, почему нам нужно применять string , int или любой другой тип.

Почему бы не позволить пользователю использовать любой тип, который они хотят?

Также да, предложение @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.

Это будет строка. Это проще, и мы уже используем строки для таких вещей, как идентификатор запроса.

Если IConnectionTransportFeature и IConnectionIdFeature являются обязательными функциями ConnectionContext , зачем дублировать свойства ConnectionId и Transport ?

Посмотреть дизайн HttpContext . Свойства, которые поднимаются на верхний уровень, являются наиболее часто используемыми и применимы к большинству реализаций подключения. Удобство, не более того. По сути, реализация этих свойств напрямую раскрывает свойства функции.

@NinoFloris

Я действительно не возражал бы против лучшего названия, короче и без путаницы, для старой технологии полного фреймворка для AspNetCore. Особенно, если это будет ссылочное имя для стека серверов в целом.

Вы имели в виду не ASP.NET, верно AspNetCore? В какой-то момент вы переходите от чистой абстракции соединения к HTTP-стеку ASP.NET Core (см. Пример «HTTP-протокол ASP.NET Core, работающий внутри сокетов ASP.NET Core»). Как бы вы назвали пакет моста, который является промежуточным программным обеспечением HTTP-соединения.

Возможно, название бренда решит проблему наименования 😄.

@benaadams

Socket обычно используется очень целенаправленно; может ли это быть более общим, как Connection? (Также соответствует ConnectionContext) какой Socket может быть из многих типов Connection.

Мне это нравится. Я пока не уверен, что мне нравится название сборки. Microsoft.AspNetCore.Connections ? Он будет расти на мне.

Это будет строка. Это проще, и мы уже используем строки для таких вещей, как идентификатор запроса.

Также упрощает работу с Activity of System.Diagnostics, например, HttpCorrelationProtocol ; byte[] вам нужно будет перераспределить обратно на 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

Некоторые из новых библиотек имеют Протокол в конце для пространства Протокола для единственной цели, но если у нас будет много здесь: множественное число кажется мне гораздо более правильным. Список для сравнения: https://apisof.net/catalog

@davidfowl да, я имел в виду, что ASP.NET изрядно перегружается. Как в наши дни называется его фактическая часть веб-фреймворка? 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 - это идентификатор платформы из двух частей (.NET и Core) и всего одна часть - «название продукта», которое вместо того, чтобы на самом деле быть хорошим названием для серверного стека, является всего лишь аббревиатурой отсылки к древним технологиям из девяностые, печатать долго и тяжело, возраст показывает.

Теперь мы все можем догадаться, что отделу маркетинга нравится узнаваемость бренда, которую ASP.NET имеет со старой гвардией (что означает без обид), и я понимаю, что использование того же имени может помочь этим людям найти переход на .NET Core. Однако его все большая и большая перегрузка никому не помогает.

Мне точно не хватает нескольких брендов / кодовых имен, которые я могу ссылаться на людей, которые напрямую соответствуют определенной части большего стека. Не всегда приходится ссылаться на длинную торговую марку перегруженного зонта, прикрепленную к точному описанию упомянутой части стопки.

Kestrel - очень удачный пример именно этого.

Извините за угон, есть ли какое-нибудь специальное место, где я могу поставить это на стол?

Извините за угон, есть ли какое-нибудь специальное место, где я могу поставить это на стол?

Конечно, сообщите о проблеме в aspnet / Home, но, честно говоря, я не уверен, что это что-то изменит. Тот факт, что ASP.NET Core даже называется ASP.NET Core, должен быть явным признаком этого. Возможно, мы могли бы переместить некоторые вещи под зонтик Microsoft.Extensions поскольку для этого есть другой уровень техники.

Конечно, сообщите о проблеме в aspnet / Home, но, честно говоря, я не уверен, что это что-то изменит.

У меня не будет никаких иллюзий;) Я знаю, что смены имени никогда не произойдет, все, о чем я прошу, - это немного большей конкретики под этим выпуклым зонтиком.

Возможно, ASP.NET (Core) останется названием зонтика, но сборки можно называть по-другому. Пустельга - хороший тому пример.

Такие имена просто трудно найти, поэтому вы можете по умолчанию использовать Microsoft.AspNetCore.XXX как безопасный выбор.

Но я за эти уникальные имена. Они отличительны, и их легко исследовать / ссылаться.

Возможно, ASP.NET (Core) останется названием зонтика, но сборки можно называть по-другому. Пустельга - хороший тому пример.

Никаких разногласий.

Такие имена просто трудно найти, поэтому вы можете по умолчанию использовать Microsoft.AspNetCore.XXX как безопасный выбор.

Наверное, последнее предложение Протоколов - это то, что мне пока нравится больше всего.

Но я за эти уникальные имена. Они отличительны, и их легко исследовать / ссылаться.

Вы имеете в виду такое имя, как пустельга, но символ представляет эти нижние слои. Бедрок 😄 может быть, но это приведет к слишком большому количеству отсылок к Флинтстоунам.

Я не вижу никаких проблем с тем, чтобы пустельга продолжала оставаться в номенклатуре AspNetCore, поскольку она в значительной степени принадлежит команде ASP.NET и является частью их платформы. Это изменение может немного разъединить компоненты Kestrel, чтобы добавить еще один уровень абстракции, но оно по-прежнему в значительной степени связано с той же командой / платформой.

Я вижу, что номенклатура Microsoft.Extensions охватывает использование фреймворками из нескольких команд, будь то веб, консоль, приложение Windows или библиотека.

Я предлагаю переместить все, что не зависит от платформы / фреймворка, в номенклатуру Microsoft.Extensions. *, Где это возможно и где это имеет смысл.

Кстати, мне бы хотелось, чтобы хост-провайдеры, используемые для начальной загрузки веб-приложений, не присутствовали на арене AspNetCore, так как есть опция хоста сервиса, которая мне больше похожа на реализацию конкретной платформы, поскольку для работы требуется только система Windows. . Было бы неплохо, если бы это была настоящая абстракция, если бы под ними могли быть реализации systemd и upstartd. Похоже, они были бы больше связаны с экосистемой .NET и вместо этого были бы частью System. *. Странно использовать хост службы для службы Windows, если она не работает в Интернете.

Кстати, мне бы хотелось, чтобы хост-провайдеры, используемые для начальной загрузки веб-приложений, не присутствовали на арене AspNetCore, так как есть опция хоста сервиса, которая мне больше похожа на реализацию конкретной платформы, поскольку для работы требуется только система Windows. . Было бы неплохо, если бы это была настоящая абстракция, если бы под ними могли быть реализации systemd и upstartd. Похоже, они были бы больше связаны с экосистемой .NET и вместо этого были бы частью System. *. Странно использовать хост службы для службы Windows, если она не работает в Интернете.

Microsoft.Extensions.Hosting приходит. Но это другая спецификация и другое кодовое имя (если я могу придумать одно). См. Тизер как часть выпуска 2.0 https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.Extensions.Hosting.Abstractions

Я обновил спецификацию новыми именами.

@davidfowl за хостинг проекта codename / spec, мне нравится 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, который обрабатывается хостингом.

Я не пытаюсь утверждать, что мы не можем сделать больше или предоставить лучшие абстракции. Меня просто интересуют твои идеи.

@ 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.OnStop или IHost.OnStop кажется намного проще, чем писать подобные вещи самостоятельно.

Я могу открыть вопрос, чтобы запросить его. Должен ли он перейти в dotnet / netstandard? @ halter73

@wholroyd подождите несколько дней. Я скоро опубликую спецификацию.

@davidfowl, как вы думаете,

@shaggygi конечно

Как потребитель, если я использую Microsoft.AspNetCore.Protocols.Http я лично ожидал бы получить от http 0.x до http2 и далее. Не возражал бы, чтобы это был мета-пакет, позволяющий использовать более сложные варианты использования (например, моя служба поддерживает только http2). Слияние сделало бы более приятным для новичков (и менее запутанным), имо.

С нетерпением жду возможности увидеть, как AMQP впишется в это в будущем (в целом, не привязанный к RabbitMQ и т. Д.)

Тем не менее, для именования нужно немного поработать, сокеты не очень хороши.

если речь идет об абстракции транспорта, вы должны назвать это:

Microsoft.AspNetCore.Transport (ы)

@ aL3891 Теперь я думаю, что нам

Я только что заметил, что это было перенесено на v2.2.
Но как это будет совместимо с грядущим SignalR (с ASP.NET 2.1)?

Между Bedrock и SignalR много общего, поэтому было бы идеально, если бы они разделяли некоторые уровни абстракции.

Изменить: например, они оба определяют класс ConnectionContext который делает в основном одно и то же.

И под «SignalR» я имею в виду библиотеки нижнего уровня, которые являются частью репозитория SignalR, например Microsoft.AspNetCore.Sockets.Abstractions .

@MuleaneEve , это

Сегодня мы приняли несколько решений:

  • Мы собираемся сохранить внешний вид транспортного уровня в 2.1 (как это было в 2.0). Мы чувствуем, что есть место для добавления клиентов к существующей абстракции, поэтому пока не хотим останавливаться на камне для API. Написание транспорта по-прежнему возможно, но API изменится и станет общедоступным в версии 2.2.
  • Это будет работа над несколькими релизами. В 2.1 мы собираемся раскрыть больше кишок пустельги в виде общедоступного API в 2.2 (HttpParser, базовый класс для обработки Http), чтобы позволить создавать высокоэффективные специализированные серверы (см. 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 здесь и уровень Sockets в SignalR также будут внутренними на данный момент?

Кстати, мне нравится название _Connections_.

Чтобы было ясно, означает ли это, что уровень Connections здесь и уровень Sockets в SignalR также будут внутренними на данный момент?

Нет, это будет публично.

Ok. Вы смотрели образец одноранговой сети, который я опубликовал?
Надеюсь, такие сценарии будут поддержаны.

@KPixel да, я видел это, но я не понимаю, как вы планируете использовать абстракции соединения.

Являются ли слои Connections & Sockets (в основном) окончательными?

Я перепишу этот образец и свое приложение, используя их, чтобы увидеть, где я застрял.

Являются ли слои Connections & Sockets (в основном) окончательными?

Теперь все соединения, и клиентский API не окончательный. Я почти уверен, что API ConnectionContext не сильно изменится. Тем не менее, мы собираемся добавить к нему больше вещей и переименовать пакеты и пространства имен.

@KPixel Я посмотрел повнимательнее, и это выглядит довольно интересно, есть пара проблем:

  • В настоящее время у нас нет ничего для udp или не потокового транспорта в целом. Это возникало в прошлом, но не конкретизировалось.
  • Текущий шаблон API означает, что вам перезвонят, поэтому связывание данных во всех привязках означает, что вам нужно каким-то образом передавать состояние. Для этого вы можете использовать DI или любой другой механизм разделения состояний.

@davidfowl Спасибо, что посмотрели.

Я также исследую новые слои ... Завтра я создам новый выпуск, чтобы продолжить это обсуждение.

Обновление Bedrock (среда, 28 марта 2018 г.)

Абстракции протокола (все общедоступные базовые API в 2.1)

  • Microsoft.AspNetCore.Connections.Abstractions

`` С #
открытый абстрактный класс ConnectionContext
{
общедоступная абстрактная строка ConnectionId {получить; установленный; }

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();

}

общедоступный делегат Task ConnectionDelegate (соединение ConnectionContext);

общедоступный абстрактный 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 и выше

  • Внесение соответствующих изменений, чтобы промежуточное ПО соединения работало должным образом при завершении работы.
    и управление подключением.
  • Устарели адаптеры подключения и замените их промежуточным ПО для подключения.
  • Отделите стек TCP Kestrel от реализации IServer в ASP.NET, что позволяет использовать его непосредственно в HostBuilder (а не в WebHostBuilder).

ПО промежуточного слоя подключения

  • Microsoft.AspNetCore.Connections.Http - имеет HttpConnectionHandler
  • Microsoft.AspNetCore.Connections.Tls - промежуточное ПО для подключения TLS
  • Microsoft.AspNetCore.Connections.Logging - ПО промежуточного слоя для ведения журнала подключений.

Это адаптеры подключения, существующие сегодня в пустельге, которые необходимо перенести на промежуточное ПО.

2.2 и выше

  • Фактически реализовать промежуточное ПО для подключения

SignalR

  • Microsoft.AspNetCore.Http.Connections - Транспорты на основе HTTP в ASP.NET Core и API для предоставления доступа к IConnectionBuilder
  • Microsoft.AspNetCore.Http.Connections.Common - общий код между сервером и клиентом
  • Microsoft.AspNetCore.Http.Connections.Client - Абстракция соединения по 3 транспортам (Websockets, LongPolling, ServerSentEvents)

`` С #
открытый класс Startup
{
public void ConfigureServices (службы IServiceCollection)
{
services.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 будет работать с чистым TCP на стороне сервера в 2.1 поверх существующих Kestrel.

      построитель подключений.

    • Здесь нам нужна первоклассная история о транспортировке клиентов. См. Дополнительные сведения в разделе «Рефераты по транспорту Kestrel.Core».

  • Возможно другие виды транспорта, где это имеет смысл.

SignalR 2.2 -> Первоклассная поддержка TCP

id хотел бы, чтобы это было раньше, чтобы запустить транспорт mqtt, но похоже, что это должно подождать немного дольше

id хотел бы, чтобы это было раньше, чтобы запустить транспорт mqtt, но похоже, что это должно подождать немного дольше

Транспорт для чего именно? Поддержка SignalR TCP является скорее официальным заявлением, мы явно не работаем над ней для версии 2.1, но она будет работать, и поддержки клиентов не будет (вы можете отправлять полезные данные из настраиваемого TCP-клиента). Однако мы поставляем API, необходимые для реализации любого протокола на стороне сервера (клиент в пути).

Я хочу создать транспорт mqtt для signalr, чтобы использовать модель программирования концентратора в качестве брокера mqtt

Я хочу создать транспорт mqtt для signalr, чтобы использовать модель программирования концентратора в качестве брокера mqtt

Чтобы быть ясным, websockets или tcp - это транспорт? Вы хотите описать вызовы хаба с помощью пакетов Mqtt? Похоже, вы хотите написать IHubProtocol
Говоря языком SignalR, это настраиваемый протокол концентратора https://github.com/aspnet/SignalR/blob/2f9942e1f20ff6b76542900eadd5828a2b61957a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocol.cs. Но если бы вы могли уточнить, это было бы здорово

@davidfowl Я вышел, чтобы увидеть поддержку клиента (исходящего TCP) в дорожной карте 2.2. Я немного размышлял о том, как работать с клиентскими подключениями и как сделать Транспорт более удобным для использования за пределами 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, я считаю, слишком минимальна, транспорты должны сообщать больше, чем просто дуплексный канал.

Я абсолютно уверен в том, что здесь слишком много, но я немного запутался в том, что значит иметь транспорт TCP и / или собственный протокол в Kestrel (поскольку я всегда думал о Kestrel как о TCP / HTTP).

В этом сценарии, где я решил использовать транспорт TCP и написать собственный протокол (давайте на данный момент предположим, что в этом примере нет SignalR), какую работу выполняет сама Kestrel? Этот сценарий похож на использование старого TcpListener, или эти абстракции дают мне немного больше?

Простите за тупой вопрос, все.

В этом сценарии, где я решил использовать транспорт TCP и написать собственный протокол (давайте на данный момент предположим, что в этом примере нет SignalR), какую работу выполняет сама Kestrel?

Kestrel - это клей, он связывает транспортный уровень, обрабатывает управление соединениями и тайм-ауты, изящное и некорректное отключение соединений.

Этот сценарий похож на использование старого TcpListener, или эти абстракции дают мне немного больше?

Абстракции соединения отделяют вас от базового транспорта. Анализ вашего протокола просто берет байты из конвейера, и не имеет значения, откуда эти байты. Вы не привязаны к TCP, а это означает, что вы можете легко протестировать уровень анализа протокола с помощью простого канала памяти, который вручную проталкивает байты (в основном, в транспорте памяти).

Звучит потрясающе, Дэвид, спасибо!

Я работал над учебником по конвейерам и соединениям, и я застрял, потому что в настоящее время трудно объяснить библиотеку Connections, не привязывая ее ни к SignalR, ни к Kestrel.

image

В настоящее время транспорт TCP находится в Kestrel, транспорт WebSockets (и другие) находится в SignalR.
И у них есть свои внутренние диспетчеры.

Если я правильно понимаю Project Bedrock, следующим шагом в 2.2 будет рефакторинг этих транспортов и диспетчеров, чтобы мы могли разрабатывать приложения, которые их используют, не принимая во внимание SignalR или Kestrel. Верный?

с моей точки зрения, пустельга понадобится всегда, но поверх нее будет лучше наслоение. так что вы можете сделать:
tcp> [TLS]> http> aspnet
tcp> [TLS]> http> signalr
tcp> [TLS]> mqtt> [signalr]
tcp> твоя собственная штука

Я работал над учебником по конвейерам и соединениям, и я застрял, потому что в настоящее время трудно объяснить библиотеку Connections, не привязывая ее ни к SignalR, ни к Kestrel.

Это 2 хозяина, чего вы ждете? Диспетчеры должны существовать, чтобы вы действительно запускали фреймворк, построенный на основе соединений. 3-й вид диспетчера - это инструкция по подключению к тесту памяти. Где вы обновляете свой обработчик подключения и проходите тест ConnectionContext .

В настоящее время транспорт TCP находится в Kestrel, транспорт WebSockets (и другие) находится в SignalR.
И у них есть свои внутренние диспетчеры.

Это правильно по замыслу. Также может быть диспетчер чистых веб-сокетов, но он никому не нужен, поэтому этого не было сделано.

Если я правильно понимаю Project Bedrock, следующим шагом в 2.2 будет рефакторинг этих транспортов и диспетчеров, чтобы мы могли разрабатывать приложения, которые их используют, не принимая во внимание SignalR или Kestrel. Верный?

Не совсем, это определенно более низкий приоритет, чем другие вещи. Основная идея 2.2 - завершить транспортную абстракцию для пустельги и сделать ее должным образом общедоступным API (как для клиентов, так и для серверов).

@KPixel, где ты

@JanEggers

с моей точки зрения, пустельга понадобится всегда, но поверх нее будет лучше наслоение. так что вы можете сделать:
tcp> [TLS]> http> aspnet
tcp> [TLS]> http> signalr
tcp> [TLS]> mqtt> [signalr]
tcp> твоя собственная штука

Это правильно, мы увидим, станет ли транспортный уровень Kestrel автономным к тому времени, когда мы закончим его проектирование, но это будет дополнительным бонусом к хорошему дизайну.

посмотрим, станет ли транспортный уровень Kestrel автономным

В основном это я имел в виду.
Итак, вы ответили на мой вопрос :)

теперь, когда выпущен Microsoft.AspNetCore.Connections.Abstractions, у меня есть вопрос:

почему это зависит от Microsoft.AspNetCore.Http.Features?

если его можно использовать для простого tcp, зачем мне функции http?

также есть ли какой-либо код для промежуточного программного обеспечения tls / какое репо / какое имя пакета?

и, наконец, я хотел использовать новую абстракцию для mqttnet. Автор этой библиотеки озабочен обновлением зависимости aspnetcore до версии 2.1. Поэтому я подумал о том, чтобы просто зависеть от System.IO, конвейеры были бы хорошей идеей, поскольку они обратно совместимы с netstandard 1.3, а пустельга вообще не требуется. Возникает вопрос: будет ли уровень tls зависеть только от System.IO.Piplines или он будет располагаться поверх абстракции соединения? И если это будет зависеть от Connections, есть ли шанс, что Connection Abstractions могут быть совместимы с NetStandard1.3, возможно, и в более поздней версии самого себя?

почему это зависит от Microsoft.AspNetCore.Http.Features?

IFeatureCollection. К сожалению, это было меньшее из зол:

  1. Создайте новую абстракцию, которая является набором функций, но не IFeatureCollection
  2. Введите переадресацию к другой сборке (это все еще вариант), но это не исправит пространство имен
  3. Просто укажите сборку.

Мы выбрали 3. 2, все еще можно сделать в основном без сбоев, но это не исправит имя типа (пространство имен будет http).

также есть ли какой-либо код для промежуточного программного обеспечения tls / какое репо / какое имя пакета?

Его еще нет. Он будет в этом репозитории.

и, наконец, я хотел использовать новую абстракцию для mqttnet. Автор этой библиотеки озабочен обновлением зависимости aspnetcore до версии 2.1. Поэтому я подумал о том, чтобы просто зависеть от System.IO, конвейеры были бы хорошей идеей, поскольку они обратно совместимы с netstandard 1.3, а пустельга вообще не требуется.

Под ASP.NET Core 2.1 автор имеет в виду netstandard 2.0, верно?

Возникает вопрос: будет ли уровень tls зависеть только от System.IO.Piplines или он будет располагаться поверх абстракции соединения? И если это будет зависеть от Connections, есть ли шанс, что Connection Abstractions могут быть совместимы с 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

спасибо за разъяснение!

Чтобы использовать ConnectionHandler с Kestrel, вам потребуется ASP.NET Core 2.1.

Я думаю о разработке FTP-сервера с использованием API в Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions , потому что это кажется (почти) идеальным совпадением. Как этот 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, должна была скопировать материал из образцов сигнального устройства в полифилл.

@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 очень быстро спасибо за это :)
В нашем проекте мы используем операционную систему, подобную debian, с настраиваемыми политиками безопасности по сравнению со стандартным Linux. Он использует настраиваемую подсистему для установки меток безопасности для пользователей, файловой системы, сокета и т. Д.

Я использую неуправляемую библиотеку для получения метки безопасности в форме Socket.Handle, в простом тестовом проекте tcp она работает хорошо. Но мне нужно правильно направить httprequest и httpresponse на мой webapi - это более сложная задача.
Если я могу использовать эту модель, где я могу разместить свою логику маршрутизации?

@davidfowl Я просмотрел исходный код, чтобы понять, как работает эта модель. Пожалуйста, поправьте меня, если я ошибаюсь.

Транспортный уровень обрабатывает соединения, затем диспетчер обрабатывает их и до промежуточного программного обеспечения. В коде приложения я могу использовать это соединение из HttpContext.Features.

image

Если я прав, то в моем случае я могу получить доступ к объекту сокета в SocketTransport, а затем поместить свою метку безопасности в socketconnection.
Для этого мне нужно изменить существующие SocketTransport и SocketConnection . Логика маршрутизации помещена в специализированное промежуточное программное обеспечение.
Это правильный путь? Или я могу получить доступ к подключению к входящему сокету другим способом?

Мне жаль, что я вышел за рамки обсуждения.

Это правильно. Нам нужно будет предоставить новую функцию, которая раскрывает дескриптор сокета. Тогда вы можете написать логику, которую хотите написать.

Нам нужно будет предоставить новую функцию, которая раскрывает дескриптор сокета. Тогда вы можете написать логику, которую хотите написать.

Было бы здорово. Что для этого нужно?
Могу я чем-то помочь?

@westfin Да! Вы можете сообщить о проблеме, указав то же самое, что и здесь, и мы можем предложить функцию, которая раскрывает базовый дескриптор сокета, после чего вы можете отправить PR.

@davidfowl, хотя я понимаю, что проект #bedrock - это работа, направленная на то, чтобы реализация протокола, отличного от HTTP, стала частью структуры AspNetCore, существует ли список протоколов, которые могут / могли бы считаться первоклассными гражданами, т.е. SFTP, FTP и FTPS

Вы можете посмотреть мой образец веб-сайта: https://wsecho.azurewebsites.net/
здесь вы можете подключать / создавать концентратор динамически на лету, вместо статического определения концентратора;
wss: //wsecho.azurewebsites.net/hub/XYZ .....
вместо прослушивания разных портов вы можете использовать разные концентраторы для разных подключений.

Реализация концентратора SignalR v1 была ужасной, v2 улучшена, но все еще трудно реализовать.
с помощью Kestrel я создал список для хаба, в основном это список. всякий раз, когда он получает новый концентратор, он добавляется в список, и я соответствующим образом изменил все методы.

PS: Иногда приложение Kestrel дает сбой, потому что для ошибки в Kestrel этот сайт использует первую версию Kestrel. Я обновлю его позже.

@davidfowl есть ли обновления по этому

так как 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

Любые советы или подсказки относительно того, как реализовать TLS для чего-то, что не связано с HTTPS (например, TCP-устройство, которое шифрует доставку своих данных с помощью TLS)?

Мой PR WIP здесь заменяет сеть Орлеана поверх общедоступных API-интерфейсов Bedrock и добавляет поддержку клиентов. В Орлеане есть внешние клиенты, но разрозненные серверы также должны взаимодействовать друг с другом (большинство распределенных систем имеют это требование), поэтому поддержка клиентских сетей очень желательна.

Возможно, Bedrock может стать Microsoft.Extensions lib и TLS может быть частью этого конвейера (с поддержкой клиента), например: Microsoft.Extensions. {Transport, Connection, Networking} .Abstractions.

Вот основные интерфейсы, которые я использую в дополнение к указанным выше @davidfowl :

`` С #
// Сторона клиента
открытый интерфейс IConnectionFactory
{
ЗадачаConnectAsync (строка endPoint);
}

// На стороне сервера
открытый интерфейс IConnectionListenerFactory
{
IConnectionListener Create (строка endPoint, ConnectionDelegate connectionDelegate);
}

открытый интерфейс IConnectionListener
{
Задача BindAsync ();
Задача UnbindAsync ();
Задача StopAsync ();
}
`` ''

Они могут быть изменены, и, возможно, «Транспорт» более уместен, чем «Соединение» в этих названиях.

ASP.NET использует интерфейс IEndpointInformation вместо string который в настоящее время использует мой PR. Я не придерживаюсь твердого мнения, но IEndpointInformation мне показалось неловким. Мы можем изменить это перед слиянием.

Верно ли, что я, когда хочу использовать TLS, должен выполнить следующие шаги:

  1. Оберните трубы в ручей
  2. Используйте SslStream
  3. Оберните ручей в трубы

Я надеялся, что смогу избежать этого преобразования pipe <-> stream <-> pipe.

Закрытие, потому что ядро ​​коренных пород находится в пустельге. У нас все еще есть ряд реакций, которые мы хотим сделать (например, # 4623), но их следует отслеживать в отдельных выпусках.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги