Search code examples
asp.netsignalrstreaming

How to read from ChannelReader in ASP.NET SignalR client


I have an existing project build on ASP.NET SignalR (NOT core). I need to stream large files to the client without using a bunch of memory. I have found many examples of doing this with aspnetcore, but not legacy asp.net.

My server side implementation is straight forward and is just like an aspnetcore example.

public ChannelReader<byte[]> Download()
{
    var path = "path/to/file.big";
    var channel = Channel.CreateUnbounded<byte[]>();
    _ = WriteToChannel(channel, path);
    return channel.Reader;
    async Task WriteToChannel(ChannelWriter<byte[]> writer, string path)
    {
        using (FileStream fs = File.OpenRead(path))
        {
            var buffer = new byte[8 * 1024];
            while (await fs.ReadAsync(buffer, 0, buffer.Length) > 0)
            {
                await writer.WriteAsync(buffer);
            }
            writer.Complete();
        }
    }
}

However on the client side the examples want me to use:

_connection.StreamAsChannelAsync<byte[]>("Download");

This is not available in legacy asp.net. I tried using:

IHubProxy.Invoke<ChannelReader<byte[]>>("Download");

But the client side code just blocks and I don't know what is happening.

Does anyone know how to make this technique work in asp.net signalr? Or can you suggest any other technique?

I'm trying to avoid jumping out and using a traditional web api and http client, because the signalr infrustructure with authentication is already in place. I feel like the signalr approach should be easy, I just can't find any old examples. Everything is about aspnetcore.


Solution

  • Streaming was introduced with SignalR CORE and not available with SignalR ASP.NET.

    For SignalR ASP.Net you will want to provide a link to the file or do something like encoding the file to a base64 string in the hub and decoding it in the client.