Skip to content

slim-gears/rxrpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

fa3aa74 · Jul 21, 2022
Mar 23, 2022
Jun 26, 2022
Jul 21, 2022
Jul 21, 2022
Jun 26, 2022
Feb 14, 2022
Mar 24, 2022
Jul 21, 2022
Jul 21, 2022
May 3, 2021
Feb 26, 2019
May 8, 2021
Aug 2, 2018
Feb 26, 2019
Sep 11, 2018
Feb 14, 2022
May 31, 2021
May 15, 2021
May 15, 2021
May 3, 2021
Jul 21, 2022
May 4, 2021

Repository files navigation

RxRpc: End-to-end asynchronus ReactiveX-based RPC framework for Java and TypeScript

Tag Build Status Download npm version

WORK IN PROGRESS...

Goal

To provide easy-to-use asynchronous RPC framework, oriented for Java backend and Java/TypeScript client

Features:
  • Fully asynchronous (both client and server side)
  • Automated client code generation for Java and TypeScript
  • Custom dependency injection framework support
  • WebSockets support

Getting started

Server side

Endpoint definition:

Endpoint is defined by class, annotated with @RxRpcEndpoint annotation. Each RPC method is annotated with @RxRpcMethod

Return types:

Following return types are allowed:

  • Asynchronous types
    • Observable<T>
    • Single<T>
    • Maybe<T>
    • Completable
    • Publisher<T>
    • Future<T>
  • Any other type will be handled as synchronous (from server side) invocation

Endpoint definition example

@RxRpcEndpoint
public interface SayHelloEndpoint {
    @RxRpcMethod
    Observable<String> sayHello(String name);
}

public class SayHelloEndpointImpl implements SayHelloEndpoint {
    public Observable<String> sayHello(String name) {
        Observable.just("Hello, " + name).delay(2, TimeUnit.SECONDS);
    }
}

Jetty-based embedded server, serving the endpoint, defined above

public class SampleServer {
    private final Server jetty;
    private final JettyWebSocketRxTransport.Server transportServer = JettyWebSocketRxTransport
            .builder()
            .buildServer();
            
    private final RxServer rxServer;

    public SampleServer(int port) {
        this.jetty = createJetty(port);
        this.rxServer = RxServer.configBuilder()
                .server(transportServer) // Use jetty WebSocket-servlet based transport
                .discoverModules()       // Discover auto-generated endpoint modules
                .resolver(ServiceResolvers
                        .builder()
                        .bind(SayHelloEndpoint.class).to(SayHelloEndpointImpl.class)
                        .build())
                .createServer();
    }

    public void start() throws Exception {
        this.jetty.start();
        this.rxServer.start();
    }

    public void stop() throws Exception {
        this.rxServer.stop();
        this.jetty.stop();
    }

    public void join() throws InterruptedException {
        this.jetty.join();
    }

    private Server createJetty(int port) {
        Server jetty = new Server(port);
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        ServletHolder servletHolder = new ServletHolder(transportServer);
        context.addServlet(servletHolder, "/api/");
        jetty.setHandler(context);
        return jetty;
    }
}

Client side

Java client example

    RxClient rxClient = RxClient.forClient(JettyWebSocketRxTransport.builder().buildClient());
    SayHelloEndpoint sayHelloClient = rxClient.connect(uri).resolve(SayHelloEndpoint_RxClient.class);
    sayHelloClient
            .sayHello("Alice")
            .test()
            .awaitDone(1000, TimeUnit.MILLISECONDS)
            .assertValueCount(1)
            .assertValue("Hello, Alice");

Component diagram

Diagram