Мое приложение ASP.Net Core предоставляет TCP-прослушиватель, реализованный с пользовательским ConnectionHandler
, для получения двоичных данных от другого процесса (назовем его Datasource
) на другом хосте.Эти данные затем отправляются в браузер через WebSocket (называемый DataSink
в коде).
Поскольку процесс Datasource
изменился с одного TCP-соединения на UDP-дейтаграммы, мне нужно адаптироваться (еговнутреннее устройство вне моей досягаемости).
Как я могу переключить текущую реализацию на прослушиватель UDP?Есть ли канонический способ, как это сделать с ASP.Net Core?
public class MySpecialConnectionHandler : ConnectionHandler
{
private readonly IMyDataSink DataSink;
public MySpecialConnectionHandler(IMyDataSink dataSink)
{
DataSink = dataSink;
}
public override async Task OnConnectedAsync(ConnectionContext context)
{
TransportConnection connection = context as TransportConnection;
Console.WriteLine("new connection: " + connection.RemoteAddress + ":" + connection.RemotePort);
while (true)
{
var result = await connection.Transport.Input.ReadAsync().ConfigureAwait(false);
var buffer = result.Buffer;
foreach (var segment in buffer)
{
await DataSink.RelayData(segment.Span.ToArray()).ConfigureAwait(false);
}
if (result.IsCompleted)
{
break;
}
connection.Transport.Input.AdvanceTo(buffer.End);
}
Console.WriteLine(connection.ConnectionId + " disconnected");
}
}
Прослушиватель UDP должен быть доступен во время работы приложения ASP.Net Core.
EDIT:
Порядок и надежность передачи дейтаграммы не так важны (возможно, вообще не важны), поскольку передаваемые данные представляют собой поток MPEG1, мультиплексированный в MPEG-TS.Источник данных находится на первом хосте, приложение ASP.Net Core - на втором хосте, а получатель / потребитель - третий хост.Хост, создающий поток, и процесс получения на третьем хосте находятся в отдельных сетях.Приложение ASP.Net Core действует как реле.Отправитель отправляет все время, но ему все равно, получены данные или нет.
РЕДАКТИРОВАТЬ 2:
Основная проблема сейчас заключается в том, куда поместитьUdpClient.Предыдущая реализация (назад, когда мы использовали TCP) настроила сервер Kestrel для дополнительного прослушивания TCP и использовала уже представленное ConnectionHandler
:
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((_, options) =>
{
// HTTP
options.Listen(networkInterface, httpPort);
// HTTPS
options.Listen(networkInterface, httpsPort, builder => builder.UseHttps());
// stream sink
options.Listen(streamInterface, streamPort, builder => builder.UseConnectionHandler<MySpecialConnectionHandler >());
});
ConnectionHandler
принимает входящее TCP-соединение и затем пересылает потоковую передачуданные для нескольких подключенных WebSockets.Поскольку это невозможно использовать с дейтаграммами UDP, мне нужно поместить UdpClient где-нибудь, где он непрерывно (т.е. while(true)
) получает дейтаграммы и передает их в WebSockets.Моя проблема в том, что я не знаю, где его разместить, запустить фоновый поток и иметь потоки коммуникационного потока, не имея проблем с этим потоком данных между потоками (например, в условиях гонки).