Anunciado na conferência SpringOne Platform, em Washington DC, o RSocket é uma nova camada 7, um protocolo de rede agnóstico (independente de linguagem) para aplicações. Trata-se de um protocolo binário bidirecional, multiplexado e baseado em mensagens, baseado na força de retorno do Reactive Streams. Foi desenvolvido por engenheiros do Facebook, Netifi e Pivotal, entre outros, com implementações disponíveis em Java, JavaScript, C++ e Kotlin.
O protocolo é projetado especificamente para funcionar bem com aplicativos Reativos, que são fundamentalmente não-bloqueantes e frequentemente (mas nem sempre) emparelhados com o comportamento assíncrono. O uso da força reversa Reativa, a ideia de que um editor não pode enviar dados a um assinante até que o assinante indique que ele está pronto, é o principal diferenciador do "assíncrono".
"Particularmente, eu acredito", disse Ben Hale, líder da Cloud Foundry Java Experience, "a programação Reativa é a próxima fronteira em Java para aplicações de alta eficiência". Há, segundo Hale, dois grandes obstáculos para a programação Reativa - acesso a dados e redes. O RSocket destina-se a resolver o último problema, enquanto o R2DBC destina-se ao primeiro.
Em um aplicativo no estilo de microservices, o protocolo HTTP é amplamente usado. Definindo o raciocínio por trás do desenvolvimento do novo protocolo, Stephane Maldini, líder do Projeto Reactor da Pivotal, apontou que o HTTP foi projetado para um mundo muito diferente.
Temos iPhones e celulares Android, ouvimos notificações não necessariamente para solicitarmos algo e receber uma resposta, mas recebemos várias respostas sem necessariamente interagir com o dispositivo. Também usamos relógios inteligentes (Smart watches) quando nos exercitamos, interagindo com um servidor de backend que nos fornece estatísticas. Temos assistentes inteligentes interagindo com um servidor de backend. E todos esses modelos de interação são parte do que poderíamos chamar de uma experiência conectada. O HTTP realmente não foi projetado para isso.
Um problema significativo com o HTTP, argumentou Maldini, é que todo o ônus é colocado no cliente para lidar com os diferentes tipos de erros com lógicas de novas tentativas, timeouts, circuit breakers e assim por diante. As aplicações construídas usando uma arquitetura Reativa podem obter ganhos de eficiência e escalar bem, mas, Maldini lembra, "o suporte Reativo é parado nos limites da aplicação".
Uma das maneiras que o RSocket difere do HTTP é por definir quatro modelos de interação:
- Fire-and-Forget: uma otimização de solicitação/resposta que é útil quando uma resposta não é necessária, como para o registro de eventos não-críticos.
- Solicitação/resposta: quando você envia uma solicitação e recebe uma resposta, exatamente como no HTTP. Mesmo aqui, o protocolo tem vantagens sobre o HTTP, pois é assíncrono e multiplexado.
- Solicitação/Transmissão: parecido com a Solicitação/Resposta quando é retornada uma coleção, a coleção é transmitida de volta em vez de ser consultada até ser concluída, portanto, por exemplo, se um número de conta bancária é enviado, responda com um fluxo em tempo real de transações da conta.
- Canal (Channel): um fluxo bidirecional de mensagens permitindo modelos de interação arbitrários.
Ser baseado em mensagens significa que o protocolo pode suportar multiplexação em uma única conexão. Além disso, como o TCP, o RSocket é verdadeiramente bidirecional, de modo que, quando um cliente inicia uma conexão com um servidor, ambas as partes na conexão se tornam equivalentes entre si - em essência, o servidor pode solicitar dados do cliente.
O RSocket também suporta controle de fluxo por mensagem. Durante a palestra, Steve Gury, engenheiro do Facebook, afirmou que:
Quando você envia uma mensagem, também especifica quantas respostas poderá satisfazer, e o servidor deve satisfazer essa restrição, mas quando essas respostas terminarem de ser processadas, posso pedir mais. O RSocket também funciona em toda a cadeia, portanto, se várias conexões do RSocket forem vinculadas, o controle de fluxo funcionará de ponta a ponta.
Em essência, como Hale afirmou em uma sessão posterior no final do dia, o problema que o RSocket resolve é o contrafluxo de processo cruzado, ou seja, contrapressão em uma rede.
Posso garantir que nunca solicito mais dados do que os que posso processar dentro de um processo, mas o que acontece quando tenho que fazer uma chamada para outro microservice na minha malha de serviço. Como posso garantir que não se materialize um monte de dados e que não tente enviar todos esses dados?
O RSocket é independente de transporte, suportando TCP, WebSocket e Aeron UDP, suportando protocolos de transporte mistos sem perda semântica - tanto a força de retorno quanto o controle de fluxo continuarão funcionando.
E também suporta a retomada de conexão. Quando uma conexão RSocket é estabelecida, é possível especificar o ID da conexão anterior e, se o servidor ainda tiver o fluxo na memória, será possível retomar o consumo do seu fluxo.
Durante sua palestra, Hale deu muito mais detalhes sobre como o protocolo funciona. Como mencionado acima, é um protocolo binário orientado por mensagens. "Temos a ideia de que, dada uma conexão de rede, uma interação entre cliente-servidor é dividida em um conjunto discreto de quadros", disse Hale. "Cada um desses quadros encapsula uma mensagem de algum tipo." O enquadramento é binário, em vez de legível por humanos, como JSON ou XML, proporcionando eficiências significativas para a comunicação máquina-a-máquina. Como acontece com todos os protocolos de mensagens, as cargas são apenas fluxos de bytes, portanto, pode ser o que quer que seja, incluindo XML ou JSON.
No Facebook, o RSocket é usado para um serviço chamado LiveServer, que é responsável por responder a uma consulta ao vivo que pode ser considerada uma assinatura do GraphQL. O servidor responde com os dados e também com um fluxo de atualizações futuras.