SignalR服务器到客户端流式用Channel时,服务器端Complete能否保证送达客户端?
SignalR服务端到客户端流式传输的完成通知可靠性问题
目前基于.NET 客户端,使用System.Threading.Channel实现SignalR服务端到客户端的流式传输,实现逻辑和SignalR官方文档流式入门章节的基础实现方式基本一致。
服务端Hub代码
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 { // 循环写入ChannelWriter直到数据传输完成 } catch (Exception ex) { localException = ex; } finally { writer.Complete(localException); } }
客户端代码
var channel = await hubConnection.StreamAsChannelAsync<byte[]>("Retrieve", _guid, cancellationTokenSource.Token); while (await channel.WaitToReadAsync()) { while (channel.TryRead(out var data)) { // 处理接收到的分片数据 } }
结合实现逻辑做个推测:当服务端Hub完成流式传输时,会对ChannelWriter调用Complete()方法;SignalR内部应该会监听对应ChannelReader的完成状态,将完成状态封装为内部SignalR消息发送给客户端,客户端收到消息后会将本地的ChannelReader标记为完成状态,让客户端的流处理逻辑自然退出。
服务端向客户端发送的“已完成”通知是否能保证送达?
其他场景下,Hub向客户端发送非流式广播消息通常采用发后即忘的模式,但按照常识判断,对流式Channel调用Complete操作应该带送达确认机制——否则就会出现服务端已经判定流关闭、但客户端侧的流式ChannelReader始终处于打开状态的异常场景。
提出该疑问的原因和当前排查的偶发故障直接相关:目前遇到的问题是SignalR流式接口的数据管道偶发卡死,初步定位卡顿点出在SignalR客户端侧。
内容的提问来源于stack exchange,提问作者koopaking3
相关产品推荐
相关产品推荐

