All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.scalecube.services.transport.rsocket.RSocketServerTransport Maven / Gradle / Ivy

package io.scalecube.services.transport.rsocket;

import io.rsocket.RSocketFactory;
import io.rsocket.transport.netty.server.CloseableChannel;
import io.rsocket.transport.netty.server.TcpServerTransport;
import io.rsocket.util.ByteBufPayload;
import io.scalecube.net.Address;
import io.scalecube.services.methods.ServiceMethodRegistry;
import io.scalecube.services.transport.api.ServerTransport;
import io.scalecube.services.transport.api.ServiceMessageCodec;
import java.net.InetSocketAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import reactor.netty.tcp.TcpServer;

/** RSocket server transport implementation. */
public class RSocketServerTransport implements ServerTransport {

  private static final Logger LOGGER = LoggerFactory.getLogger(RSocketServerTransport.class);

  private final ServiceMessageCodec codec;
  private final TcpServer tcpServer;

  private CloseableChannel serverChannel; // calculated

  /**
   * Constructor for this server transport.
   *
   * @param codec message codec
   * @param tcpServer tcp server
   */
  public RSocketServerTransport(ServiceMessageCodec codec, TcpServer tcpServer) {
    this.codec = codec;
    this.tcpServer = tcpServer;
  }

  @Override
  public Address address() {
    InetSocketAddress address = serverChannel.address();
    return Address.create(address.getHostString(), address.getPort());
  }

  @Override
  public Mono bind(ServiceMethodRegistry methodRegistry) {
    return Mono.defer(
        () -> {
          TcpServer tcpServer =
              this.tcpServer.doOnConnection(
                  connection -> {
                    LOGGER.info("Accepted connection on {}", connection.channel());
                    connection.onDispose(
                        () -> LOGGER.info("Connection closed on {}", connection.channel()));
                  });

          return RSocketFactory.receive()
              .frameDecoder(
                  frame ->
                      ByteBufPayload.create(
                          frame.sliceData().retain(), frame.sliceMetadata().retain()))
              .errorConsumer(
                  th -> LOGGER.warn("Exception occurred at rsocket server transport: " + th))
              .acceptor(new RSocketServiceAcceptor(codec, methodRegistry))
              .transport(() -> TcpServerTransport.create(tcpServer))
              .start()
              .doOnSuccess(channel -> serverChannel = channel)
              .thenReturn(this);
        });
  }

  @Override
  public Mono stop() {
    return Mono.defer(
        () -> {
          if (serverChannel == null) {
            return Mono.empty();
          }
          serverChannel.dispose();
          return serverChannel
              .onClose()
              .doOnError(e -> LOGGER.warn("Failed to close server: " + e));
        });
  }

  @Override
  public String toString() {
    return "RSocketServerTransport{"
        + "codec="
        + codec
        + ", tcpServer="
        + tcpServer
        + ", serverChannel="
        + serverChannel
        + '}';
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy