繁体   English   中英

如何将ConnectionHandler切换到UDP

[英]How to switch a ConnectionHandler to UDP

我的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");
    }
}

在ASP.Net Core应用程序运行时,UDP侦听器必须可用。

编辑:

数据报传输的顺序和可靠性不是那么重要(也许一点也不重要),因为传输的数据是复用到MPEG-TS中的MPEG1流。 数据源在第一台主机上,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连接,然后将流数据转发到许多已连接的WebSocket。 由于这不适用于UDP数据报,因此我需要将UdpClient放置在连续的位置(即while(true) )接收数据报并将其转发到WebSockets。 我的问题是,我不知道将它放在哪里,运行后台线程并没有通信跨线程,而对此线程间数据流(例如竞争条件)没有任何问题。

因此,得出以下结论:

我们将BackgroundWorkerUdpClient结合使用。 仅当至少有一个接收器时才实例化BackgroundWorker

StreamReceiver = new BackgroundWorker();
StreamReceiver.DoWork += ReceiveStream;
StreamReceiver.RunWorkerAsync();

ReceiveStream是建立UdpClient的私有方法,然后等待需要中继的传入数据。

private async void ReceiveStream(object sender, DoWorkEventArgs e)
{
    // DataSinkPort is a const int
    UdpClient datasource = new UdpClient(_DataSinkPort);

    while (true)
    {
        var rec = await datasource.ReceiveAsync();
        await RelayData(rec.Buffer);

        if (_CancellationToken.IsCancellationRequested)
        {
            return;
        }
    }
}

RelayData方法仅使用每个订阅接收者的传出TCP连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM