【发布时间】:2019-06-24 17:28:04
【问题描述】:
我的 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 应用程序运行时可用。
编辑:
数据报传输的顺序和可靠性并不那么重要(也许根本不重要),因为传输的数据是多路复用到 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))接收数据报并将它们转发到 WebSocket 的地方。我的问题是我不知道把它放在哪里,运行后台线程并让通信跨线程,而这个线程间数据流没有任何问题(如竞争条件)。
【问题讨论】:
-
没有一种单一的方法可以做到这一点。这在很大程度上取决于基于 UDP 的协议。请注意,您需要自己注意顺序和完整性,因为 UDP 既不可靠也不保持顺序(数据包可能无序到达或根本没有到达)。这意味着您需要再次实现请求丢失的数据包,并且您需要实现数据包排序......您还需要弄清楚您的“数据源”是否在线,因为 UDP 也是无连接的。
-
也就是说,我建议您与数据源团队(或至少其中一个)坐下来,让他们向您解释(应用程序)协议。
-
应用协议是一个简单的视频流,所以丢包完全没有问题。数据报传输的可靠性并不那么重要。现在,我什至根本不知道在哪里放置
UdpListener。 -
你支持多流吗?
-
@Fildor 我添加了一些有用的信息。
标签: c# asp.net-core