簡體   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