Streaming em Tempo Real com C#, SignalR e ChannelReader

Imagine transmitir cotações da bolsa, dados de sensores IoT ou logs📝 Logging com Serilog: Registre Tudo como um Detetive de Bugs!📝 Logging com Serilog: Registre Tudo como um Detetive de Bugs!Aprenda a usar Serilog em .NET para registrar logs estruturados, identificar erros e enriquecer informações, transformando seu código num enigma solucionável. de sistemas com latência de milissegundos e economia de 70% em banda. Este guia completo revela como implementar streaming em tempo real usando C#, SignalR🚀 SignalR Básico: Crie um Chat em Tempo Real!🚀 SignalR Básico: Crie um Chat em Tempo Real!Descubra como criar um chat em tempo real com SignalR e ASP.NET Core. Tutorial prático com passo a passo para iniciantes e especialistas. e ChannelReader, desde conceitos fundamentais até arquiteturas escaláveis para milhões de usuários!

🔗 Tabela de Conteúdo🔗

🚀 Por que Streaming?🔗

Cenário Tradicional (Polling):

// Cliente fazendo requisições a cada 2 segundos
while (true)
{
    var dados = await httpClient.GetAsync("api/dados");
    await Task.Delay(2000); // Latência de até 2s
}

Problemas:

Solução com Streaming:

// Conexão persistente com SignalR
hubConnection.On("NovosDados", (Dados dados) =>
{
    AtualizaDashboard(dados); // Reação imediata
});

⚡ SignalR: O Canhão de Dados do .NET🔗

Arquitetura Multiprotocolo:

ProtocoloVantagensCaso de Uso Ideal
WebSocketConexão full-duplex, baixa latênciaAplicações críticas
Server-Sent EventsSimples, servidor→clienteNotificações em massa
Long PollingCompatível com firewalls restritasAmbientes corporativos

Fluxo de Dados com Hub:

public class DadosHub : Hub
{
    public ChannelReader<Cotacao> StreamDados(CancellationToken ct)
    {
        var canal = Channel.CreateUnbounded<Cotacao>();
        _ = ProduzirDadosAsync(canal.Writer, ct);
        return canal.Reader;
    }
    private async Task ProduzirDadosAsync(ChannelWriter<Cotacao> escritor, CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            var cotacao = GerarCotacaoAleatoria();
            await escritor.WriteAsync(cotacao, ct);
            await Task.Delay(1000, ct);
        }
        escritor.Complete();
    }
}

🔧 ChannelReader: O Coração do Fluxo Contínuo🔗

Padrão Produtor-Consumidor Assíncrono⚡ Async/Await: Programação Assíncrona sem Callbacks!⚡ Async/Await: Programação Assíncrona sem Callbacks!Aprenda a aplicar Async/Await em C# para criar aplicações responsivas, evitar travamentos e melhorar a escalabilidade com exemplos práticos e dicas essenciais.:

public class SensorService
{
    private readonly Channel<LeituraSensor> _canal = Channel.CreateUnbounded<LeituraSensor>();
    public async Task IniciarColetaAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            var leitura = await _sensor.LerAsync();
            await _canal.Writer.WriteAsync(leitura, ct);
        }
        _canal.Writer.Complete();
    }
    public ChannelReader<LeituraSensor> ObterLeitor() => _canal.Reader;
}

Integração com SignalR🚀 SignalR Básico: Crie um Chat em Tempo Real!🚀 SignalR Básico: Crie um Chat em Tempo Real!Descubra como criar um chat em tempo real com SignalR e ASP.NET Core. Tutorial prático com passo a passo para iniciantes e especialistas.:

public async IAsyncEnumerable<LeituraSensor> StreamSensor(
    [EnumeratorCancellation] CancellationToken ct)
{
    var leitor = _sensorService.ObterLeitor();
    while (await leitor.WaitToReadAsync(ct))
    {
        while (leitor.TryRead(out var leitura))
        {
            yield return leitura; // Envio contínuo ao cliente
        }
    }
}

💻 Implementação em 4 Etapas🔗

1. Modelagem de Dados:

public record Cotacao(string Simbolo, decimal Valor, DateTime TimeStamp);

2. Configuração🚀 Scale Out com Redis: Atenda Milhões de Conexões!🚀 Scale Out com Redis: Atenda Milhões de Conexões!Integre o Redis com SignalR no .NET e distribua mensagens entre servidores, alcançando escalabilidade e alta performance em tempo real. do SignalR:

builder.Services.AddSignalR()
               .AddJsonProtocol(opts => opts.PayloadSerializerOptions.PropertyNamingPolicy = null);

3. Mapeamento do Endpoint📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos.:

app.MapHub<DadosHub>("/dados-realtime");

4. Cliente JavaScript:

const conexao = new signalR.HubConnectionBuilder()
    .withUrl("/dados-realtime")
    .build();
conexao.on("NovosDados", dados => {
    atualizarGrafico(dados);
});
conexao.start();

🌐 Exemplos Práticos (Bolsa vs IoT)🔗

Caso 1: Simulador de Ações

// Gerador de cotações
var cotacao = new Cotacao(
    Simbolo: "PETR4",
    Valor: Random.Shared.Next(20, 30),
    TimeStamp: DateTime.UtcNow
);

Caso 2: Monitoramento🚀 Kubernetes: Orquestração de Microservices na Nuvem!🚀 Kubernetes: Orquestração de Microservices na Nuvem!Descubra como Kubernetes revoluciona o gerenciamento de microsserviços na nuvem, garantindo escalabilidade, automação e alta disponibilidade. IoT

public class LeituraSensor
{
    public double Temperatura { get; set; }
    public double Umidade { get; set; }
    public DateTime TimeStamp { get; set; }
}

Clientes Específicos:

// Ações
conexao.on("CotacaoAtualizada", cotacao => {
    plotarGrafico(cotacao);
});
// IoT
conexao.on("LeituraSensor", leitura => {
    exibirAlertas(leitura.Temperatura);
});

🚦 Escalando para Milhões🔗

Arquitetura com Redis🚀 Scale Out com Redis: Atenda Milhões de Conexões!🚀 Scale Out com Redis: Atenda Milhões de Conexões!Integre o Redis com SignalR no .NET e distribua mensagens entre servidores, alcançando escalabilidade e alta performance em tempo real.:

Clientes → Azure SignalR Service → Redis Backplane → Instâncias

Configuração de Escalabilidade📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos.:

builder.Services.AddSignalR()
               .AddAzureSignalR("Endpoint=...;AccessKey=...;");

Métricas de Desempenho⏱️ Testes de Performance: Garanta Velocidade Além da Funcionalidade!⏱️ Testes de Performance: Garanta Velocidade Além da Funcionalidade!Descubra como medir, diagnosticar e otimizar performance em aplicações .NET com dicas práticas e ferramentas essenciais para devs.:

MétricaWebSocketSSELong Polling
Conexões/Node50k20k10k
Latência50ms100ms200ms
Throughput10MB/s5MB/s2MB/s

📊 Projeto: Dashboard Financeiro🔗

Funcionalidades Essenciais:

1. Gráfico em tempo real com Plotly.js

2. Alertas📊 Monitoramento com Prometheus: Métricas em Tempo Real!📊 Monitoramento com Prometheus: Métricas em Tempo Real!Descubra como implementar o Prometheus para monitoramento em sistemas .NET, com métricas em tempo real e dashboards inteligentes. personalizáveis por ativo

3. Histórico de 24h com suavização

4. Autenticação JWT📄 Swagger/OpenAPI: Documente sua API Automaticamente!📄 Swagger/OpenAPI: Documente sua API Automaticamente!Descubra como gerar documentação interativa e automatizada em APIs com o Swagger/OpenAPI. Aprenda a configurar no .NET e testar endpoints facilmente. para dados premium

Estrutura Frontend:

const configGrafico = {
    layout: {title: 'PETR4 - Tempo Real'},
    config: {responsive: true}
};
conexao.on('Atualizacao', dados => {
    Plotly.extendTraces('grafico', {y: [[dados.Valor]]}, [0]);
    if (dados.Valor > limite) dispararAlerta();
});

🏁 Conclusão e Boas Práticas🔗

Benefícios do Streaming:

Checklist de Implantação:

1. Use MessagePack para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! compactação:

services.AddSignalR().AddMessagePackProtocol();

2. Monitore conexões com Application Insights

3. Implemente Circuit Breaker🛡️ Circuit Breaker: Proteja seus Microservices de Falhas em Cascata!🛡️ Circuit Breaker: Proteja seus Microservices de Falhas em Cascata!Descubra como implementar o Circuit Breaker em .NET 8 para sistemas resilientes. Aprenda estratégias de fallback e monitore o desempenho com eficácia! para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! resiliência

4. Utilize Redis🚀 Scale Out com Redis: Atenda Milhões de Conexões!🚀 Scale Out com Redis: Atenda Milhões de Conexões!Integre o Redis com SignalR no .NET e distribua mensagens entre servidores, alcançando escalabilidade e alta performance em tempo real. para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! scale-out

Dica Profissional:

GlobalHost.Configuration.DefaultMessageBufferSize = 32; // Otimiza memória em dispositivos móveis
Próximo Nível: Explore Azure Functions + SignalR para arquiteturas serverless e processamento orientado a eventos em larga escala!
[FunctionName("ProcessarDados")]
public static async Task Run(
    [EventHubTrigger("dados")] EventData[] eventos,
    [SignalR(HubName = "dadosHub")] IAsyncCollector<SignalRMessage> signalRMensagens)
{
    foreach (var evento in eventos)
    {
        await signalRMensagens.AddAsync(new SignalRMessage
        {
            Target = "NovoDado",
            Arguments = new[] { JsonConvert.DeserializeObject<Dado>(evento.Body) }
        });
    }
Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo

Artigos Relacionados