
com.github.davidmoten.rx.internal.operators.ObservableServerSocket Maven / Gradle / Ivy
package com.github.davidmoten.rx.internal.operators;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import com.github.davidmoten.rx.Actions;
import com.github.davidmoten.rx.Bytes;
import com.github.davidmoten.rx.Checked;
import com.github.davidmoten.rx.Checked.F0;
import com.github.davidmoten.rx.Functions;
import rx.Observable;
import rx.Observer;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Action2;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.observables.SyncOnSubscribe;
public final class ObservableServerSocket {
private ObservableServerSocket() {
// prevent instantiation
}
public static Observable> create(final int port, final int timeoutMs,
final int bufferSize, Action0 preAcceptAction, int acceptTimeoutMs) {
Func1>> observableFactory = createObservableFactory(
timeoutMs, bufferSize, preAcceptAction);
return Observable., ServerSocket> using( //
createServerSocketFactory(port, acceptTimeoutMs), //
observableFactory, //
new Action1() {
@Override
public void call(ServerSocket ss) {
try {
ss.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
},
true);
}
private static Func0 createServerSocketFactory(final int port,
final int acceptTimeoutMs) {
return Checked.f0(new F0() {
@Override
public ServerSocket call() throws Exception {
return createServerSocket(port, acceptTimeoutMs);
}
});
}
private static ServerSocket createServerSocket(int port, long timeoutMs) throws IOException {
ServerSocket s = new ServerSocket(port);
s.setSoTimeout((int) timeoutMs);
return s;
}
private static Func1>> createObservableFactory(
final int timeoutMs, final int bufferSize, final Action0 preAcceptAction) {
return new Func1>>() {
@Override
public Observable> call(ServerSocket serverSocket) {
return createServerSocketObservable(serverSocket, timeoutMs, bufferSize, preAcceptAction);
}
};
}
private static Observable> createServerSocketObservable(
ServerSocket serverSocket, final long timeoutMs, final int bufferSize, final Action0 preAcceptAction) {
return Observable.create( //
SyncOnSubscribe.> createSingleState( //
Functions.constant0(serverSocket), //
new Action2>>() {
@Override
public void call(ServerSocket ss,
Observer super Observable> observer) {
acceptConnection(timeoutMs, bufferSize, ss, observer, preAcceptAction);
}
}));
}
private static void acceptConnection(long timeoutMs, int bufferSize, ServerSocket ss,
Observer super Observable> observer, Action0 preAcceptAction) {
Socket socket;
while (true) {
try {
preAcceptAction.call();
socket = ss.accept();
observer.onNext(createSocketObservable(socket, timeoutMs, bufferSize));
break;
} catch (SocketTimeoutException e) {
// timed out so will loop around again
} catch (IOException e) {
// unknown problem
observer.onError(e);
break;
}
}
}
private static Observable createSocketObservable(final Socket socket, long timeoutMs,
final int bufferSize) {
setTimeout(socket, timeoutMs);
return Observable.using( //
Checked.f0(new F0() {
@Override
public InputStream call() throws Exception {
return socket.getInputStream();
}
}), //
new Func1>() {
@Override
public Observable call(InputStream is) {
return Bytes.from(is, bufferSize);
}
}, //
Actions.close(), //
true);
}
private static void setTimeout(Socket socket, long timeoutMs) {
try {
socket.setSoTimeout((int) timeoutMs);
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy