Introdução ao RSocket

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