
hu.akarnokd.reactive.rpc.RpcServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of akarnokd-reactive-rpc Show documentation
Show all versions of akarnokd-reactive-rpc Show documentation
akarnokd-reactive-rpc developed by David Karnok
The newest version!
package hu.akarnokd.reactive.rpc;
import java.io.IOException;
import java.net.*;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import io.reactivex.Scheduler;
import io.reactivex.disposables.Disposable;
import io.reactivex.internal.schedulers.SingleScheduler;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;
public final class RpcServer {
final Object localAPI;
final Class remoteAPI;
static Scheduler scheduler = Schedulers.io();
private RpcServer(Object localAPI, Class remoteAPI) {
this.localAPI = localAPI;
this.remoteAPI = remoteAPI;
}
public static RpcServer createLocal(Object localAPI) {
Objects.requireNonNull(localAPI, "localAPI");
RpcServiceMapper.serverServiceMap(localAPI);
return new RpcServer<>(localAPI, null);
}
public static RpcServer createRemote(Class remoteAPI) {
Objects.requireNonNull(remoteAPI, "remoteAPI");
RpcServiceMapper.clientServiceMap(remoteAPI);
return new RpcServer<>(null, remoteAPI);
}
public static RpcServer createBidirectional(Object localAPI, Class remoteAPI) {
Objects.requireNonNull(localAPI, "localAPI");
RpcServiceMapper.serverServiceMap(localAPI);
Objects.requireNonNull(remoteAPI, "remoteAPI");
RpcServiceMapper.clientServiceMap(remoteAPI);
return new RpcServer<>(localAPI, remoteAPI);
}
public AutoCloseable start(int port) {
ServerSocket ssocket;
try {
ssocket = new ServerSocket(port);
} catch (IOException e) {
throw new RuntimeException(e);
}
return setup(ssocket);
}
AutoCloseable setup(ServerSocket ssocket) {
Scheduler acceptor = new SingleScheduler();
AtomicBoolean done = new AtomicBoolean();
Disposable c = acceptor.scheduleDirect(() -> {
socketAccept(ssocket, done);
});
return () -> {
if (done.compareAndSet(false, true)) {
c.dispose();
ssocket.close();
}
};
}
void socketAccept(ServerSocket ssocket, AtomicBoolean done) {
while (!Thread.currentThread().isInterrupted()) {
Socket socket;
try {
socket = ssocket.accept();
} catch (IOException e) {
if (!done.get()) {
RxJavaPlugins.onError(e);
}
return;
}
try {
RpcSocketManager.connect(socket, socket.getInetAddress(), socket.getPort(),
remoteAPI, localAPI, c -> { }, scheduler, true);
} catch (Throwable ex) {
RxJavaPlugins.onError(ex);
try {
socket.close();
} catch (IOException e) {
RxJavaPlugins.onError(e);
}
}
}
}
public AutoCloseable start(InetAddress localAddress, int port) {
ServerSocket ssocket;
try {
ssocket = new ServerSocket(port, 50, localAddress);
} catch (IOException e) {
throw new RuntimeException(e);
}
return setup(ssocket);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy