Introdução
Imagine um plano de controle que precisa conversar continuamente com agentes instalados em vários hosts. A API envia comandos, cada agente publica heartbeats (sinais periódicos de que continua ativo), informa mudanças no inventário e pode abrir um canal interativo para um terminal. Uma sequência de chamadas HTTP independentes ainda funcionaria para operações pontuais, mas não expressaria tão naturalmente esse fluxo persistente nos dois sentidos. É nesse tipo de problema que gRPC no .NET 10 merece ser considerado.
gRPC é uma estrutura de chamadas de procedimentos remotos (RPC, de Remote Procedure Call): o cliente invoca métodos definidos por contrato em um servidor, usando mensagens tipadas que normalmente são serializadas com Protocol Buffers e transportadas por HTTP/2. Eu o escolheria quando os participantes são serviços sob controle da mesma equipe, precisam compartilhar contratos gerados ou manter um fluxo de mensagens contínuo, especialmente bidirecional. Isso não faz de gRPC um substituto universal de REST, nem prova que ele será mais rápido para qualquer aplicação.
No Dokpod, o navegador usa REST/OpenAPI para operações da interface e SignalR para notificações. O gRPC fica no canal interno entre a API e os agentes: o agente inicia uma conexão de saída, autentica-se com certificado de cliente e mantém um stream para trocar mensagens de controle. Essa escolha responde a uma necessidade concreta do sistema, não a uma regra para todos os produtos.
Este é o primeiro de três artigos da série APIs e Comunicação em .NET. A parte 2 será um guia introdutório de GraphQL; a parte 3 explicará SignalR no .NET, do primeiro Hub à produção. Os dois ainda não foram publicados, por isso não incluo links inexistentes.
ℹ️ Informação: Na data desta consulta, o repositório público do Dokpod não possui releases ou tags publicados. Os links de código neste artigo apontam para a branch
maine acompanham seu estado atual; por isso, podem mudar e não representam uma release estável.
RPC, REST e a função do HTTP/2
Uma chamada RPC começa com uma pergunta conhecida: “qual operação quero executar e qual mensagem preciso enviar?”. Um cliente chama um método como GetInventory; o servidor recebe os dados, executa a operação e devolve uma resposta. A rede está escondida atrás de uma interface semelhante a uma chamada local, mas a operação continua sendo remota: pode demorar, falhar, ser cancelada ou perder a conexão. Essa distinção importa porque uma rede não oferece as mesmas garantias de uma chamada dentro do processo.
Para uma RPC existir, cliente e servidor precisam concordar sobre o nome do método, os tipos de entrada e saída e como os dados serão representados. Esse acordo é o contrato. Em gRPC, costuma ser descrito em arquivos .proto; ferramentas geram código para construir mensagens e invocar o serviço. O código reduz diferenças de digitação e ajuda a detectar incompatibilidades durante o build, mas não elimina a necessidade de versionar e implantar os dois lados com cuidado.
REST parte de outra organização mental. Em vez de perguntar “qual método remoto chamo?”, o cliente interage com recursos identificados por URLs e usa a semântica HTTP, como GET, POST, PUT e DELETE. Uma API REST normalmente expõe representações, comumente JSON, que podem ser inspecionadas e consumidas por clientes diversos. gRPC descreve operações e mensagens com mais rigidez e costuma priorizar clientes que conhecem o contrato e podem usar código gerado. Não é uma divisão absoluta: ambos podem transportar dados estruturados e ambos dependem de decisões cuidadosas de design.
O gRPC tradicional usa HTTP/2. Essa versão do HTTP organiza mensagens em frames e permite multiplexar vários streams sobre uma conexão. Multiplexação significa que diferentes trocas podem compartilhar a conexão sem abrir uma conexão TCP para cada chamada. O HTTP/2 também define controle de fluxo para limitar quanto dado um receptor aceita. Esses recursos dão uma base adequada para chamadas persistentes, mas não tornam automaticamente uma aplicação mais rápida: serialização, tamanho das mensagens, rede, balanceamento, concorrência e trabalho no servidor continuam determinando o resultado.
Um stream gRPC é uma chamada lógica que pode conter uma mensagem ou várias. Não se deve confundi-lo com “uma conexão TCP por método” nem supor que uma conexão pode permanecer aberta para sempre em qualquer infraestrutura. Proxies, firewalls, NATs, limites de duração, certificados e reinicializações podem interromper o fluxo. A aplicação precisa decidir como detectar a queda, abrir outra sessão e recuperar o estado que ficou incerto.
Há também uma consequência prática: um cliente gRPC tradicional no navegador não é igual a um cliente C# ou Go. Navegadores não dão acesso irrestrito às primitivas HTTP/2 que o gRPC convencional espera. Para cenários web existem gRPC-Web e gateways que traduzem protocolos, mas eles adicionam componentes e restrições. No Dokpod, a interface usa HTTP e SignalR, enquanto os agentes usam gRPC; separar os consumidores evita obrigar o browser a falar o protocolo interno.
⚠️ Atenção: HTTP/2 multiplexa streams, mas a conexão continua sujeita a falhas e limites da rede. Trate toda desconexão como parte normal do desenho, não como um evento impossível.
Protocol Buffers, arquivos .proto e código gerado
Protocol Buffers, ou Protobuf, é um formato de serialização e uma linguagem para descrever mensagens. Serializar é transformar uma estrutura em bytes para transmiti-la ou armazená-la; desserializar é reconstruir a estrutura do outro lado. Um arquivo .proto declara mensagens, campos, números de campo, serviços e métodos. A partir dele, o compilador e os plugins da linguagem geram tipos para o cliente e o servidor.
Um campo tem tipo, nome e um número. O nome ajuda as pessoas que leem o contrato; o número identifica o campo no formato binário. Essa diferença é fundamental: depois de publicado e usado, um número não deve ser reaproveitado para outro significado. Se um campo for removido, reserve seu número e, quando apropriado, seu nome. Acrescentar campos opcionais costuma ser compatível no formato binário, mas isso não garante compatibilidade de comportamento. Um agente antigo pode ignorar um campo novo; já um código de negócio pode depender de uma capability (capacidade anunciada) que o agente não oferece.
Também é importante separar compatibilidade de wire format (formato transmitido) de compatibilidade de aplicação. Uma mudança pode continuar sendo decodificada e ainda quebrar um switch, uma validação ou uma regra de negócio. A implantação pode envolver várias versões de API e agentes ativas ao mesmo tempo. Por isso, mudanças de contrato precisam de uma estratégia de rollout, testes com versões consecutivas e observabilidade suficiente para identificar quem ainda usa o formato antigo.
No Dokpod, AgentControl declara dois métodos de streaming. Connect recebe mensagens do agente e devolve mensagens do plano de controle. Exec usa outro stream, separado, para quadros de terminal. Mensagens de envelope carregam metadados como versão do protocolo, identificador da sessão, fencing token e sequência. Um oneof agrupa tipos de payload alternativos, como AgentHello, Heartbeat, uma página de inventário ou um comando. Isso dá ao leitor uma visão explícita das mensagens possíveis sem transformar o canal em um proxy genérico para a API do engine.
O contrato também registra campos reservados e comentários de evolução. Por exemplo, mensagens de inventário têm revisões e páginas, e capabilities novas são aceitas somente quando o servidor as reconhece. Essa disciplina é parte do custo de um protocolo próprio: a equipe passa a ser responsável por documentar, testar e evoluir os contratos usados pelo produto.
Os quatro modos de chamada gRPC
O tipo de uma RPC é definido pelo número de mensagens que cada lado pode enviar durante a chamada. O método unary recebe uma mensagem e devolve uma mensagem. É o modelo mais simples: buscar detalhes de uma configuração, validar um token ou consultar uma informação pontual. Ele se parece com uma chamada HTTP de request/response, embora use método e mensagens tipados no contrato.
No streaming do servidor, o cliente envia uma requisição e o servidor responde com zero ou mais mensagens ao longo do tempo. Uma exportação paginada, uma sequência de progresso ou atualizações contínuas que não precisam de resposta do cliente são exemplos possíveis. O cliente pode cancelar o stream, e o servidor deve propagar o token de cancelamento para o trabalho assíncrono. Se o servidor tentar enviar uma resposta infinita sem limites, o custo de recursos também pode ser contínuo.
No streaming do cliente, o cliente envia várias mensagens e recebe uma resposta final. Isso pode fazer sentido para enviar lotes, fragmentos de uma tarefa ou amostras que o servidor consolida. O servidor lê até o cliente encerrar o stream e então responde. Esse padrão não é apenas “muitas chamadas unary”: mantém uma chamada aberta e uma sequência ordenada de mensagens.
No streaming bidirecional, ou duplex, os dois lados podem enviar várias mensagens durante a mesma chamada. Eles não precisam alternar uma mensagem de cada lado: cliente e servidor podem ler e escrever independentemente. É útil quando há troca contínua de comandos, respostas, estados e confirmações. O protocolo da aplicação ainda deve definir correlação, ordenação, controle de fluxo, prioridade e o que fazer quando a chamada termina.
| Modo | Mensagens do cliente | Mensagens do servidor | Exemplo de uso |
|---|---|---|---|
| Unary | Uma | Uma | Consulta pontual |
| Streaming do servidor | Uma | Muitas | Progresso ou feed de leitura |
| Streaming do cliente | Muitas | Uma | Envio de lotes para consolidação |
| Bidirecional | Muitas | Muitas | Canal interativo de controle |
O Connect do Dokpod é bidirecional porque os agentes e a API precisam enviar mensagens enquanto a sessão está ativa. Isso não significa que todo agente precise transmitir dados a cada instante. Heartbeats, inventário e comandos são mensagens de aplicação carregadas no stream; a aplicação ainda define quando e por que cada uma deve circular.
Por que o Dokpod escolheu gRPC para os agentes
O contexto do Dokpod é diferente de uma API pública voltada a qualquer navegador. O produto precisa alcançar engines de containers instalados em hosts que podem estar em redes privadas, atrás de NAT ou protegidos por regras que não permitem conexões iniciadas de fora. Fazer cada API central iniciar uma conexão até o host exigiria endereços acessíveis e regras de rede por ambiente.
Com uma conexão de saída, o agente inicia a sessão até a API. Isso costuma se encaixar melhor em redes restritas porque o host precisa permitir uma saída controlada, não publicar o socket Docker, um endpoint Podman ou SSH para a rede. O padrão não elimina a configuração de rede nem todas as ameaças, mas reduz a necessidade de abrir a interface administrativa do engine para conexões remotas.
O segundo motivo é o contrato de domínio. Um proxy genérico que encaminhasse qualquer chamada para o Docker Engine ampliaria o impacto de uma falha de autorização: a API poderia se tornar uma ponte para operações arbitrárias do host. O Dokpod envia comandos próprios e versionados, como iniciar ou parar um container, e o agente valida o que recebeu antes de usar o adapter do engine. Isso limita a superfície em comparação com um proxy irrestrito. Ainda assim, o agente é um componente privilegiado; o protocolo precisa autorizar cada operação, validar entradas e evitar exposição de dados sensíveis.
O streaming bidirecional permite que o servidor envie comandos e que o agente informe aceitação, resultado, heartbeat e diferenças de inventário no mesmo canal de controle. A escolha também permite que o servidor negocie sessão, versão e capabilities. Isso é valioso para um produto que controla as duas pontas, mas traz o custo de manter uma especificação e garantir compatibilidade entre elas.
Há limites importantes. O plano atual começa com uma instância da API. Escalar horizontalmente requer decidir qual instância é dona de cada stream, como rotear comandos e como recuperar ownership após falhas. O Dokpod adia essa escala distribuída para uma decisão futura. Os testes executados confirmaram o funcionamento do adapter com Podman Linux; isso não substitui a validação de cada combinação de versões e ambiente. O agente Windows ainda depende de gates de qualificação. A escolha do protocolo não certifica automaticamente todos os engines ou sistemas operacionais.
Como o fluxo gRPC do Dokpod funciona
O agente abre AgentControl.Connect e envia AgentHello como primeira mensagem. O hello informa versão do agente, engine e versão, sistema operacional, arquitetura, hostname e capabilities. O servidor obtém o certificado de cliente da conexão TLS e entrega certificado e hello ao negociador de sessão. Se a identidade ou a negociação forem rejeitadas, a chamada termina com um erro gRPC; não existe uma sessão válida apenas porque o TCP conectou.
Quando aceita a sessão, o plano de controle devolve SessionEstablished: versão de protocolo selecionada, identificador da sessão, fencing token, intervalo de heartbeat, limite de mensagem e capabilities aceitas. O agente valida esses metadados antes de iniciar o trabalho da sessão. O intervalo anunciado é de 15 segundos e o serviço usa timeout de heartbeat de 90 segundos. Esses números descrevem o código consultado, não uma recomendação universal para qualquer rede.
Depois da negociação, o agente pode publicar snapshots paginados e deltas do inventário. O snapshot reconstrói o estado completo em partes; o delta representa mudanças a partir de uma revisão-base. Heartbeats incluem a última sequência de comando aplicada e revisões de inventário. A API também pode enviar requisições de reconciliação, consultas e comandos de domínio. Separar “aceito” de “resultado concluído” permite representar que receber a ordem não significa que o engine já terminou a operação.

O trecho abaixo resume a forma do contrato, sem tentar reproduzir todas as mensagens:
| |
📂 Código Fonte: O contrato completo está na branch
maindo Dokpod:agent.proto.
No cliente, o agente escreve o hello, aguarda a confirmação inicial e só então considera a sessão estabelecida. O código gerado fornece os tipos e o proxy do serviço; a lógica abaixo mostra o ponto de validação, não um cliente completo:
| |
📂 Código Fonte: O fluxo de sessão e reconexão está em
AgentControlWorker.cs; o processamento no servidor está emAgentControlService.cs.
O terminal usa AgentControl.Exec, um stream separado que começa com handshake vinculado à identidade do certificado, sessão ativa, fencing token e sessão de terminal pendente. Ele transporta frames de entrada, saída, redimensionamento e status. Um canal separado evita misturar o fluxo interativo com heartbeats e inventário, mas exige limites, expiração e encerramento coordenado.
Segurança, reconexão e confiabilidade
gRPC não é uma política de segurança. TLS protege o canal e autentica o servidor; mTLS acrescenta certificado de cliente, que permite ao servidor autenticar a identidade do agente. No fluxo do Dokpod, a API exige o certificado de cliente e negocia a sessão a partir dele e das informações do agente. Certificados precisam ter emissão, rotação, revogação, armazenamento e escopo bem definidos. Um certificado válido identifica um participante, mas não substitui autorização de negócio para cada comando.
É útil separar quatro perguntas: quem estabeleceu o canal? A que ambiente essa identidade pertence? O protocolo aceita a versão e as capabilities anunciadas? A identidade pode executar esta operação, neste recurso e neste momento? Resolver apenas a primeira pergunta com mTLS deixaria o restante sem resposta. O servidor precisa validar autorização antes de persistir ou enviar comandos; o agente também deve recusar payloads inválidos e operações que não implementa.
Conexões persistentes caem. O processo pode reiniciar, a rede pode mudar, um NAT pode expirar o mapeamento ou o servidor pode encerrar uma chamada. O agente tenta reconectar, mas a nova conexão não deve simplesmente continuar como se fosse a antiga. Uma sessão recebe identificador e fencing token: um número crescente que permite distinguir a sessão vigente de uma conexão antiga que reapareceu atrasada. O servidor rejeita mensagens que chegam com sessão ou token obsoleto.
Sequências e identificadores de comando ajudam a detectar mensagens duplicadas e lacunas. Porém, transporte gRPC não fornece entrega exatamente uma vez. Se uma resposta se perde depois de a operação ter sido aplicada, o agente pode não saber se deve repetir. O Dokpod assume entrega at-least-once (ao menos uma vez) em alguns fluxos e combina deduplicação, journal e reconciliação para reduzir efeitos duplicados e recuperar divergências. Isso não é uma garantia de exactly-once (exatamente uma vez): o resultado precisa ser desenhado para lidar com repetição e estados incertos.
O tamanho de mensagem também é parte da segurança. Mensagens grandes podem consumir memória e atrasar outras atividades. O servidor do Dokpod define limite gRPC de 1 MiB, e respostas de consulta são fracionadas com limite documentado de 256 KiB. A aplicação deve validar os próprios limites, limitar filas e taxas, e cancelar operações quando deixam de ser necessárias. Um stream que fica aberto não é licença para acumular mensagens sem controle.
Por fim, alta disponibilidade não vem de um RPC duplex. O desenho atual começa com uma instância da API; ownership distribuído dos streams e roteamento durável ficam adiados. A revisão de prontidão registra pendências de compatibilidade N/N-1, carga e observabilidade de release, além da qualificação do agente Windows. Essa distinção impede que um exemplo arquitetural seja confundido com certificação de produção.
Quando escolher gRPC, REST, GraphQL ou SignalR
Eu começaria pela forma do consumidor e do fluxo, não por uma lista de “vantagens”. Se clientes são serviços controlados e a equipe consegue distribuir contratos e código gerado, gRPC pode simplificar uma integração tipada. Se clientes incluem browser, scripts, parceiros ou ferramentas variadas, REST costuma reduzir atrito e facilita observação com ferramentas HTTP conhecidas. GraphQL atende outro problema: permitir que consumidores consultem campos e relações de um grafo de dados por uma API orientada a consultas. SignalR atende comunicação em tempo real com clientes web e abstrações de alto nível como hubs e grupos no ecossistema ASP.NET Core.
| Opção | Consumidor típico | Direção do fluxo | Contrato e payload | Custo operacional |
|---|---|---|---|---|
| gRPC | Serviços e agentes controlados | Unary e streaming nos dois sentidos | .proto, código gerado, Protobuf por padrão | HTTP/2, contratos coordenados e diagnóstico de streams |
| REST | Navegadores, apps e integrações | Requisição/resposta; streaming requer desenho específico | Recursos HTTP, OpenAPI e JSON frequentes | Baixo atrito e ampla compatibilidade de ferramentas |
| GraphQL | Clientes com necessidades variáveis de leitura | Consulta/resposta por schema | Schema GraphQL e seleção de campos | Controle de custo de consultas, resolvers e cache |
| SignalR | Browser e clientes conectados | Eventos e mensagens em tempo real | Hubs, métodos e payloads da aplicação | Conexões persistentes, grupos e escala/backplane quando necessário |
No Dokpod, o navegador consome REST/OpenAPI para operações e SignalR para receber notificações segmentadas por ambiente. A relação entre browser e API é diferente da relação entre agente e API. Isso evita fazer a interface web depender do canal interno gRPC. Caso um produto precise de chamadas gRPC originadas pelo browser, gRPC-Web ou um gateway podem ser avaliados; cada opção introduz requisitos de proxy, compatibilidade e suporte a streaming que precisam ser comprovados.
Também não escolheria gRPC só porque o payload binário parece menor ou porque HTTP/2 tem multiplexação. Sem benchmark representativo, não há evidência para afirmar superioridade de desempenho. Se uma operação é pontual, simples e voltada a clientes heterogêneos, REST pode ser a escolha mais clara. Se o problema exige consulta flexível sobre muitos recursos, investigue GraphQL. Se o browser precisa receber eventos, avalie SignalR, SSE ou WebSockets. Se serviços controlados precisam trocar mensagens continuamente com contrato explícito, gRPC merece um protótipo.
Exemplo Prático
Considere o ciclo de vida de um agente do Dokpod. Primeiro, ele abre uma conexão de saída para a API e chama Connect. Em seguida, envia AgentHello com sua identidade operacional e as capacidades que anuncia. O servidor valida o certificado, relaciona-o a um ambiente e negocia a sessão. Se a negociação for aprovada, responde com SessionEstablished, que inclui o protocolo escolhido, o fencing token, o intervalo de heartbeat, o limite de mensagem e as capabilities aceitas.
A partir daí, o agente e a API podem escrever no stream. O agente envia heartbeats e publica inventário paginado ou deltas; o plano de controle envia comandos, consultas ou pedidos de reconciliação. Para uma operação, a mensagem de comando tem metadados de sessão e sequência. O agente valida a sessão ativa, deduplica a operação quando aplicável e devolve estados separados para aceitação e resultado. Se a conexão cair antes de o resultado chegar, a API não deve presumir que o comando falhou nem repeti-lo às cegas: precisa consultar o estado persistido e reconciliar com o agente após reconectar.
Este recorte do contrato ilustra como o payload muda sem criar uma chamada para cada tipo de evento:
| |
📂 Código Fonte: A definição completa, incluindo payloads e numeração dos campos, está no contrato
agent.proto.
O valor didático do exemplo está nos limites entre as partes. O protocolo define a forma das mensagens; o cliente mantém a conexão e coordena filas; o serviço da API negocia e processa eventos; os adapters falam com Docker ou Podman. A API não encaminha uma chamada arbitrária para o socket do engine. Essa separação torna mais explícito quem pode solicitar uma operação e qual capacidade do agente é necessária.
O fluxo de terminal é diferente. A API abre um Exec separado depois de validar que a identidade do agente, a sessão e o fencing token correspondem a uma sessão de terminal pendente. Frames transportam dados de entrada, saída, redimensionamento e status. Não é um shell genérico disponibilizado pelo gRPC: é uma funcionalidade de domínio com autorização, expiração e condições de suporte próprias. O repositório documenta que certas ações de terminal são limitadas a agentes Linux e capabilities anunciadas.
Para adaptar o padrão a outro sistema, comece com uma mensagem hello mínima, negociação explícita e um conjunto pequeno de tipos de evento. Defina como uma operação será identificada, como mensagens duplicadas serão tratadas e como o cliente descobre o estado atual depois de uma interrupção. Só adicione streaming bidirecional se os dois lados realmente precisarem produzir mensagens durante a mesma sessão.
Dicas e Boas Práticas
- Defina prazos e cancelamento. Chamadas unary devem ter deadline apropriado ao trabalho; operações longas devem observar o token de cancelamento. Streams contínuos precisam de política clara para encerramento e reconexão.
- Nunca reutilize números Protobuf. Ao remover um campo, reserve seu número e avalie reservar também o nome. Mudanças no
.protodevem passar por revisão de compatibilidade e testes entre versões. - Limite mensagens, filas e frequência. Defina o tamanho máximo, aplique paginação ou fragmentação e use filas limitadas. Sem limites, um cliente lento pode transformar um stream persistente em crescimento ilimitado de memória.
- Autentique e autorize separadamente. TLS protege o transporte; mTLS identifica o certificado do agente. Ainda é necessário associar a identidade a um escopo e autorizar cada comando e recurso.
- Projete repetição como comportamento normal. Use IDs idempotentes, deduplicação e reconciliação. Não prometa exatamente uma vez porque um RPC retornou sucesso ou porque um canal permaneceu aberto.
- Teste versões e interrupções. Exercite queda durante envio, resposta perdida, reinício do servidor, certificado revogado e agente antigo. Compatibilidade teórica do wire format não substitui teste N/N-1.
- Meça antes de falar em performance. Compare uma carga representativa, os mesmos dados e a mesma topologia. Registre latência, CPU, memória, bytes, conexões e taxa de erros para gRPC e alternativas.
Conclusão
gRPC combina RPC, contratos definidos em .proto, código gerado, mensagens Protobuf e transporte normalmente baseado em HTTP/2. Seu modelo suporta chamadas unary, streaming do servidor, streaming do cliente e streaming bidirecional. Esse conjunto é especialmente útil quando serviços controlados precisam trocar mensagens tipadas continuamente, mas também exige decisões sobre evolução de contrato, limites de recursos, autenticação, autorização, cancelamento e recuperação.
O caso do Dokpod mostra uma escolha coerente com o problema: agentes em hosts privados iniciam conexões de saída, autenticam-se por mTLS e mantêm um canal para controle e inventário. A API não precisa expor sockets Docker ou SSH e o protocolo transmite comandos de domínio, não chamadas arbitrárias ao engine. A interface web usa REST/OpenAPI e SignalR, pois navegador e agente são consumidores diferentes com necessidades diferentes.
Essa escolha não prova que gRPC seja sempre mais rápido, mais simples ou melhor que REST. Também não significa que a arquitetura já esteja qualificada para toda combinação de engine e sistema operacional: apesar de os testes executados confirmarem o funcionamento com Podman Linux, ainda há gates de carga, compatibilidade N/N-1, qualificação do agente Windows e observabilidade de release. A conclusão correta é mais modesta e útil: use gRPC quando contrato tipado e fluxo contínuo justificarem o custo operacional, valide as condições reais da rede e mantenha alternativas adequadas para outros clientes.
Na parte 2 da série APIs e Comunicação em .NET, vou tratar de GraphQL para iniciantes e dos problemas que uma API orientada a consultas resolve. Na parte 3, vou focar SignalR no .NET, incluindo hubs, clientes, reconexão e operação. Até lá, o artigo publicado sobre tempo real no Angular e .NET continua como leitura complementar sobre WebSockets, SSE, SignalR e Long Polling, mas não faz parte desta nova série.
Resumo Objetivo
- gRPC — estrutura de RPC que descreve serviços e mensagens em contratos, gera código cliente/servidor e normalmente transporta chamadas por HTTP/2.
- Protocol Buffers — linguagem e formato binário associados ao gRPC; cada campo possui número estável que não deve ser reaproveitado após publicação.
- Streaming bidirecional — permite que cliente e servidor enviem várias mensagens durante uma mesma chamada, sem exigir alternância entre cada envio.
- Dokpod — usa gRPC com mTLS no canal interno entre API e agentes; o browser usa REST/OpenAPI e SignalR.
- Confiabilidade — gRPC não oferece entrega exatamente uma vez nem alta disponibilidade por si só; repetição, deduplicação, fencing e reconciliação pertencem ao desenho da aplicação.
- Adoção — gRPC é adequado quando contratos tipados e fluxos contínuos justificam sua operação; REST, GraphQL e SignalR atendem necessidades diferentes de cliente e tráfego.
Leia Também
- Design de API REST: verbos HTTP e parameter binding no ASP.NET Core
- API Gateway, segurança de SPA e JWT com BFF
- Tempo real no Angular e .NET: WebSockets, SSE e SignalR
- Arquitetura de eventos sem caos com C#
Referências
- Introduction to gRPC — visão geral oficial de RPC, Protobuf, geração de código e streaming.
- Overview for gRPC on .NET — suporte de gRPC no ASP.NET Core e clientes .NET.
- Create gRPC services and methods — tipos de chamada e implementação de serviços em .NET.
- Protocol Buffers: Language Guide (proto3) — mensagens, campos, números, geração e evolução de contratos.
- RFC 9113: HTTP/2 — especificação de streams, multiplexação, conexão e controle de fluxo.
- Authentication and authorization in gRPC for ASP.NET Core — autenticação por certificado e autorização de chamadas.
- Reliable gRPC services with deadlines and cancellation — deadlines, cancelamento e propagação no .NET.
- ADR 2026-0001 do Dokpod — motivação arquitetural e trade-offs do canal entre API e agentes.

Ao comentar, você concorda com nossa Política de Privacidade, Termos de Uso e Política de Exclusão de Dados.