Introdução ao RSocket
1. Introdução
Neste tutorial, veremos primeiro RSocket e como ele habilita a comunicação cliente-servidor.
2. O que é o RSocket?
*RSocket é um protocolo de comunicação binário, ponto a ponto* , destinado ao uso em aplicativos distribuídos. Nesse sentido, ele fornece uma alternativa para outros protocolos como HTTP.
Uma comparação completa entre o RSocket e outros protocolos está além do escopo deste artigo. Em vez disso, vamos nos concentrar em um recurso importante do RSocket: seus modelos de interação.
*O RSocket fornece quatro modelos de interação.* Com isso em mente, exploraremos cada um com um exemplo.
3. Dependências do Maven
O RSocket precisa apenas de duas dependências diretas para nossos exemplos:
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-core</artifactId>
<version>0.11.13</version>
</dependency>
<dependency>
<groupId>io.rsocket</groupId>
<artifactId>rsocket-transport-netty</artifactId>
<version>0.11.13</version>
</dependency>
Https://search.maven.org/search?q=rsocket-core[rsocket-core] e rsocket-transport-netty dependências estão disponíveis no Maven Central.
*Uma observação importante é que a biblioteca RSocket faz uso frequente de https://projectreactor.io/[reactive streams]* . Os _https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html [Flux] _ e _https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[MonoExit_ classes são usadas ao longo deste artigo, portanto, um entendimento básico delas será útil.
4. Configuração do servidor
Primeiro, vamos criar a classe Server:
public class Server {
private final Disposable server;
public Server() {
this.server = RSocketFactory.receive()
.acceptor((setupPayload, reactiveSocket) -> Mono.just(new RSocketImpl()))
.transport(TcpServerTransport.create("localhost", TCP_PORT))
.start()
.subscribe();
}
public void dispose() {
this.server.dispose();
}
private class RSocketImpl extends AbstractRSocket {}
}
*Aqui usamos o _RSocketFactory_ para configurar e ouvir um soquete TCP.* Passamos nosso _RSocketImpl_ personalizado para lidar com solicitações de clientes. Adicionaremos métodos ao _RSocketImpl_ à medida que avançamos.
Em seguida, para iniciar o servidor, basta instanciar:
Server server = new Server();
*Uma instância de servidor único pode lidar com várias conexões* . Como resultado, apenas uma instância do servidor suportará todos os nossos exemplos.
Quando terminarmos, o método dispose irá parar o servidor e liberar a porta TCP.
4. Modelos de interação
4.1. Solicitação/resposta
O RSocket fornece um modelo de solicitação/resposta - cada solicitação recebe uma única resposta.
Para este modelo, criaremos um serviço simples que retorna uma mensagem para o cliente.
Vamos começar adicionando um método à nossa extensão de AbstractRSocket, RSocketImpl:
@Override
public Mono<Payload> requestResponse(Payload payload) {
try {
return Mono.just(payload);//reflect the payload back to the sender
} catch (Exception x) {
return Mono.error(x);
}
}
*O método _requestResponse_ retorna um único resultado para cada solicitação* , como podemos ver pelo tipo de resposta _Mono <Payload> _.
*_Payload_ é a classe que contém o conteúdo e os metadados da mensagem* . É usado por todos os modelos de interação. O conteúdo da carga útil é binário, mas existem métodos de conveniência que suportam conteúdo baseado em _String_.
Em seguida, podemos criar nossa classe de cliente:
public class ReqResClient {
private final RSocket socket;
public ReqResClient() {
this.socket = RSocketFactory.connect()
.transport(TcpClientTransport.create("localhost", TCP_PORT))
.start()
.block();
}
public String callBlocking(String string) {
return socket
.requestResponse(DefaultPayload.create(string))
.map(Payload::getDataUtf8)
.block();
}
public void dispose() {
this.socket.dispose();
}
}
O cliente usa o método RSocketFactory.connect () _ para iniciar uma conexão de soquete com o servidor. Usamos o método _requestResponse no soquete para enviar uma carga útil ao servidor