[英]When using Channels with SignalR server-to-client streaming, is the server-side Complete guaranteed to be delivered to the client?
I'm doing SignalR server-to-client streaming using System.Threading.Channel
with a .NET client.我正在使用带有 .NET 客户端的
System.Threading.Channel
执行 SignalR 服务器到客户端流式传输。 The usage is fairly basic, similar to what is described in the introductory docs .用法相当基本,类似于介绍性文档中描述的内容。
The hub code is similar to this:集线器代码与此类似:
public ChannelReader<byte[]> Retrieve(Guid id, CancellationToken cancellationToken)
{
var channel = Channel.CreateBounded<byte[]>(_limit);
_ = WriteItemsAsync(channel.Writer, id, cancellationToken);
return channel.Reader;
}
private async Task WriteItemsAsync(ChannelWriter<byte[]> writer, Guid id, CancellationToken cancellationToken)
{
Exception localException = null;
try
{
//loop and write to the ChannelWriter until finished
}
catch (Exception ex)
{
localException = ex;
}
finally
{
writer.Complete(localException);
}
}
And client similar to this:和客户端类似:
var channel = await hubConnection.StreamAsChannelAsync<byte[]>("Retrieve", _guid, cancellationTokenSource.Token);
while (await channel.WaitToReadAsync())
{
while (channel.TryRead(out var data))
{
//handle data
}
}
When my hub method is done streaming, it calls Complete()
on its ChannelWriter
.当我的集线器方法完成流式传输时,它会在其
ChannelWriter
上调用Complete()
。 SignalR, presumably, internally sees the Complete
call on the corresponding ChannelReader
, translates that into an internal SignalR message and delivers that to the client. SignalR,大概是在内部看到对相应
ChannelReader
的Complete
调用,将其转换为内部 SignalR 消息并将其传递给客户端。 The client's own ChannelReader
is then marked as complete by SignalR and my client code wraps up its own work on the stream.然后,客户自己的
ChannelReader
被 SignalR 标记为完成,我的客户代码在 stream 上完成了自己的工作。
Is that "completed" notification, from server to client, guaranteed to be delivered?从服务器到客户端的“已完成”通知是否可以保证交付? In other cases where the hub is broadcasting non-streaming messages to clients, it generally "fires and forgets", but I've got to assume that calling
Complete
on the streaming Channel
has acknowledged delivery, otherwise the client could be in a state where it is holding a streaming ChannelReader
open indefinitely while the server sees the stream as closed.在集线器向客户端广播非流式消息的其他情况下,它通常“触发并忘记”,但我必须假设在流式
Channel
上调用Complete
已确认交付,否则客户端可能位于 state 中当服务器看到 stream 已关闭时,它无限期地打开流式ChannelReader
。
Less important to the question, but the reason I ask is that I am trying to narrow down just such a scenario where a data flow pipeline that consumes a SignalR streaming interface very occasionally hangs, and it seems that the only point where it is hanging is somewhere in the SignalR client.这个问题不太重要,但我问的原因是我试图缩小这样一种情况,即消耗 SignalR 流接口的数据流管道偶尔会挂起,而且似乎唯一挂起的地方是SignalR 客户端的某处。
I asked the devs over on github: https://github.com/dotnet/aspnetcore/issues/30128 .我在 github 上询问了开发人员: https://github.com/dotnet/aspnetcore/issues/30128 。
Here is a quick summary:这是一个快速的总结:
"Messages over SignalR are as reliable as TCP. Basically what this means is that either you get the message, or the connection closes. In both cases the channel on the client side will be completed." “SignalR 上的消息与 TCP 一样可靠。基本上这意味着要么您收到消息,要么连接关闭。在这两种情况下,客户端的通道都将完成。”
And:和:
"Right it should never hang forever. It'll either send the complete message or disconnect. Either way, a hang would be a bug in the client" “是的,它不应该永远挂起。它要么发送完整的消息,要么断开连接。无论哪种方式,挂起都是客户端的错误”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.