Long Polling vs WebSocket em C#: o que escolher para tempo real?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Chamada longa ou canal eterno: como o C# entrega dados em tempo real

\n\n

Imagine: você está escrevendo um chat em C#. Ou um terminal de ações. Ou um sistema de notificações. O cliente espera por dados — e não está disposto a esperar muito. Antigamente, os desenvolvedores se viravam como podiam: colocavam timers, faziam requisições ao servidor a cada 5 segundos, geravam requisições desnecessárias. Hoje, temos duas abordagens civilizadas — Long Polling e WebSocket. Ambas permitem que o servidor envie dados ao cliente sem uma requisição explícita dele. Mas funcionam de maneiras fundamentalmente diferentes.

\n\n

Neste artigo, vamos analisar como implementar ambas as abordagens em C# (ASP.NET Core), compará-las em termos de velocidade, carga e complexidade, e entender o que escolher para o seu projeto. Vamos nessa.

\n\n

O que é Long Polling? (E por que não é mágica)

\n\n

Long Polling é uma emulação de tempo real sobre HTTP comum. O cliente envia uma requisição ao servidor, mas o servidor não responde imediatamente. Ele mantém a conexão aberta até que um novo evento ocorra (ou até que o tempo limite expire). Assim que os dados estão prontos — o servidor envia a resposta, o cliente a processa e imediatamente abre uma nova requisição "longa".

\n\n

Este é um truque esperto que funciona em qualquer servidor HTTP e em qualquer navegador. Mas tem um custo: cada conexão fica na memória do servidor e, se houver milhares de clientes, isso já é um problema.

\n\n

Exemplo de Long Polling em C# (ASP.NET Core)

\n\n

Vamos escrever um controlador simples que simula uma fila de notificações. O cliente acessa o endpoint, o servidor espera por novos dados (por exemplo, de um canal Channel<string>) e os envia.

\n\n
using Microsoft.AspNetCore.Mvc;\nusing System.Threading.Channels;\n\n[ApiController]\n[Route("api/[controller]")]\npublic class NotificationsController : ControllerBase\n{\n    private static readonly Channel<string> _channel = Channel.CreateUnbounded<string>();\n\n    // Endpoint para publicar uma notificação (por exemplo, de outro serviço)\n    [HttpPost("publish")]\n    public async Task<IActionResult> Publish([FromBody] string message)\n    {\n        await _channel.Writer.WriteAsync(message);\n        return Ok("Notificação enviada");\n    }\n\n    // Long Polling: o cliente espera até que uma nova mensagem apareça\n    [HttpGet("long-poll")]\n    public async Task<IActionResult> LongPoll(CancellationToken cancellationToken)\n    {\n        // Aguarda uma nova mensagem; se não houver, espera até 30 segundos\n        using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);\n        cts.CancelAfter(TimeSpan.FromSeconds(30));\n\n        try\n        {\n            var message = await _channel.Reader.ReadAsync(cts.Token);\n            return Ok(new { data = message });\n        }\n        catch (OperationCanceledException)\n        {\n            // Tempo limite — retorna resposta vazia, o cliente repetirá a requisição\n            return Ok(new { data = (string?)null });\n        }\n    }\n}\n
\n\n

O cliente (JavaScript) ficará assim:

\n\n
async function startLongPoll() {\n    while (true) {\n        const response = await fetch('/api/notifications/long-poll');\n        const result = await response.json();\n        if (result.data) {\n            console.log('Nova notificação:', result.data);\n        }\n        // Imediatamente inicia um novo poll\n    }\n}\nstartLongPoll();\n
\n\n

Tudo simples. Mas há um detalhe: se o servidor reiniciar ou o cliente perder a conexão — os dados serão perdidos. O Long Polling não garante a entrega.

\n\n

WebSocket: túnel bidirecional em C#

\n\n

WebSocket é um protocolo completo de comunicação bidirecional sobre TCP. Após o handshake (um HTTP GET comum com upgrade), o cliente e o servidor se comunicam diretamente, sem a sobrecarga dos cabeçalhos HTTP. O servidor pode enviar uma mensagem a qualquer momento, e o cliente a receberá instantaneamente.

\n\n

No ASP.NET Core, o WebSocket é integrado nativamente. Não são necessárias bibliotecas de terceiros (

Blogs

Book Recommendations