В основе проекта лежит дальнейшее разделение компонентов Kestrel, чтобы мы могли использовать его в качестве основы для нашего сетевого стека, не связанного с HTTP.
Мы хотим развить примитивы, шаблоны и сквозные проблемы, существующие сегодня в приложениях ASP.NET Core. Цель состоит в том, чтобы позволить фреймворкам более высокого уровня (например, SignalR или WCF и даже самому ASP.NET Core) строить поверх абстракций, которые не привязывают их к конкретной реализации соединения (OWIN для Connections). Например, он позволяет SignalR работать как поверх TCP, так и через веб-сокеты, не понимая, что такое базовый транспорт. Мы также хотим позволить создавать необработанные серверы протоколов низкого уровня для обработки таких вещей, как MQTT для сценариев IOT.
В этой модели программирования на стороне сервера есть 3 основных участника:
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 .
Этот рефакторинг позволит сделать следующее:
IConnectionBuilder
. Это означает, что такие вещи, как TLS, проверка подлинности Windows и ведение журнала подключений, могут быть отдельными компонентами промежуточного программного обеспечения.Транспорты отвечают за предоставление начальной реализации IFeatureCollection
для соединения и предоставление потока байтов приложению.
Сегодня у нас есть 2 реализации транспорта, которые находятся в Kestrel: реализация System.Net.Sockets и libuv. Мы планируем сохранить эти 2, потому что они оба предлагают разные наборы функций. Libuv может прослушивать дескрипторы файлов, именованные каналы, сокеты домена unix и сокеты tcp, в то время как System.Net.Sockets просто имеет реализацию сокета tcp (и сокеты домена unix)
Мы хотим, чтобы люди могли создавать фреймворки на основе веб-сокетов, не имея дело с низкоуровневыми деталями, такими как управление соединениями и буферизация. Таким образом, мы предоставим транспорт веб-сокетов, который предоставляет эти примитивы подключения. В настоящее время он находится в пакете Microsoft.AspNetCore.Http.Connectons .
SignalR в прошлом исторически предоставлял несколько транспортных реализаций для браузеров, которые не поддерживали веб-сокеты. Это не полнодуплексный транспорт, но они реализованы как таковые путем циклического переключения идентификатора соединения по HTTP-запросам. Мы также предоставим реализации транспортов для длинных опросов и событий, отправленных сервером. Эти реализации потребуют специальной клиентской библиотеки, которая понимает лежащий в основе недуплексный протокол. В настоящее время они находятся в пакетах Microsoft.AspNetCore.Http.Connectons и Microsoft.AspNetCore.Http.Connectons.Client .
QUIC - это быстро развивающийся стандарт, который стремится улучшить воспринимаемую производительность ориентированных на соединение веб-приложений, которые в настоящее время используют TCP. Когда появится QUIC, мы захотим иметь возможность поддерживать его с той же абстракцией.
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();
Было бы действительно здорово иметь что-то эквивалентное 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
Я предполагаю, что 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?
Спасибо.
@mnns, который находится в разработке (хотя официального https://github.com/dotnet/corefxlab/tree/master/src/System.IO.Pipelines.Networking.Windows.RIO и https: / /github.com/dotnet/corefxlab/tree/master/samples/System.IO.Pipelines.Samples
@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 , это
Сегодня мы приняли несколько решений:
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 Я посмотрел повнимательнее, и это выглядит довольно интересно, есть пара проблем:
@davidfowl Спасибо, что посмотрели.
Я также исследую новые слои ... Завтра я создам новый выпуск, чтобы продолжить это обсуждение.
`` С #
открытый абстрактный класс 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();
}
}
Это адаптеры подключения, существующие сегодня в пустельге, которые необходимо перенести на промежуточное ПО.
`` С #
открытый класс 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();
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, а это означает, что вы можете легко протестировать уровень анализа протокола с помощью простого канала памяти, который вручную проталкивает байты (в основном, в транспорте памяти).
Звучит потрясающе, Дэвид, спасибо!
@JanEggers написал реализацию прототипа MqttServer на основе основы https://github.com/JanEggers/Playground/blob/SignalR/MQTT/Playground.core/Program.cs#L24 https://github.com/JanEggers/Playground/blob /SignalR/MQTT/Playground.core/Hubs/MqttHubConnectionHandler.cs
Я работал над учебником по конвейерам и соединениям, и я застрял, потому что в настоящее время трудно объяснить библиотеку Connections, не привязывая ее ни к SignalR, ни к Kestrel.
В настоящее время транспорт 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. К сожалению, это было меньшее из зол:
Мы выбрали 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
спасибо за разъяснение!
Чтобы использовать 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 и направлять их обратно клиенту.
Я понимаю, что это очень конкретный случай, но для меня он очень важен.
Псевдокод
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.
Если я прав, то в моем случае я могу получить доступ к объекту сокета в 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 вышла?
🤔 Не думаете, что это еще?
https://github.com/aspnet/AspNetCore/releases/tag/2.2.0
разве это не финал?
@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
{
Задача
}
// На стороне сервера
открытый интерфейс IConnectionListenerFactory
{
IConnectionListener Create (строка endPoint, ConnectionDelegate connectionDelegate);
}
открытый интерфейс IConnectionListener
{
Задача BindAsync ();
Задача UnbindAsync ();
Задача StopAsync ();
}
`` ''
Они могут быть изменены, и, возможно, «Транспорт» более уместен, чем «Соединение» в этих названиях.
ASP.NET использует интерфейс IEndpointInformation
вместо string
который в настоящее время использует мой PR. Я не придерживаюсь твердого мнения, но IEndpointInformation
мне показалось неловким. Мы можем изменить это перед слиянием.
Верно ли, что я, когда хочу использовать TLS, должен выполнить следующие шаги:
Я надеялся, что смогу избежать этого преобразования pipe <-> stream <-> pipe.
Закрытие, потому что ядро коренных пород находится в пустельге. У нас все еще есть ряд реакций, которые мы хотим сделать (например, # 4623), но их следует отслеживать в отдельных выпусках.
Самый полезный комментарий
Было бы действительно здорово иметь что-то эквивалентное Transports на стороне клиента, чтобы вы могли иметь более абстрактный HttpClient с переключаемым базовым транспортным механизмом.