|
|
|
@ -24,6 +24,7 @@ import io.reactivex.netty.protocol.http.server.HttpServer; |
|
|
|
import org.reactivestreams.Publisher; |
|
|
|
import org.reactivestreams.Publisher; |
|
|
|
import org.reactivestreams.Subscriber; |
|
|
|
import org.reactivestreams.Subscriber; |
|
|
|
import org.reactivestreams.Subscription; |
|
|
|
import org.reactivestreams.Subscription; |
|
|
|
|
|
|
|
import reactor.core.reactivestreams.PublisherFactory; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.reactive.web.rxnetty.RequestHandlerAdapter; |
|
|
|
import org.springframework.reactive.web.rxnetty.RequestHandlerAdapter; |
|
|
|
@ -80,21 +81,10 @@ public class DispatcherApp { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Publisher<String> handle(ServerHttpRequest request, ServerHttpResponse response) { |
|
|
|
public Publisher<String> handle(ServerHttpRequest request, ServerHttpResponse response) { |
|
|
|
|
|
|
|
return PublisherFactory.forEach((subscriber) -> { |
|
|
|
return new Publisher<String>() { |
|
|
|
subscriber.onNext("Hello world."); |
|
|
|
|
|
|
|
subscriber.onComplete(); |
|
|
|
@Override |
|
|
|
}); |
|
|
|
public void subscribe(Subscriber<? super String> subscriber) { |
|
|
|
|
|
|
|
subscriber.onSubscribe(new AbstractSubscription<String>(subscriber) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
protected void requestInternal(long n) { |
|
|
|
|
|
|
|
invokeOnNext("Hello world."); |
|
|
|
|
|
|
|
invokeOnComplete(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
@ -113,40 +103,30 @@ public class DispatcherApp { |
|
|
|
PlainTextHandler textHandler = (PlainTextHandler) handler; |
|
|
|
PlainTextHandler textHandler = (PlainTextHandler) handler; |
|
|
|
final Publisher<String> resultPublisher = textHandler.handle(request, response); |
|
|
|
final Publisher<String> resultPublisher = textHandler.handle(request, response); |
|
|
|
|
|
|
|
|
|
|
|
return new Publisher<HandlerResult>() { |
|
|
|
return PublisherFactory.forEach((subscriber) -> { |
|
|
|
|
|
|
|
resultPublisher.subscribe(new Subscriber<Object>() { |
|
|
|
@Override |
|
|
|
|
|
|
|
public void subscribe(Subscriber<? super HandlerResult> handlerResultSubscriber) { |
|
|
|
@Override |
|
|
|
handlerResultSubscriber.onSubscribe(new AbstractSubscription<HandlerResult>(handlerResultSubscriber) { |
|
|
|
public void onSubscribe(Subscription subscription) { |
|
|
|
|
|
|
|
subscription.request(Long.MAX_VALUE); |
|
|
|
@Override |
|
|
|
} |
|
|
|
protected void requestInternal(long n) { |
|
|
|
|
|
|
|
resultPublisher.subscribe(new Subscriber<Object>() { |
|
|
|
@Override |
|
|
|
|
|
|
|
public void onNext(Object result) { |
|
|
|
@Override |
|
|
|
subscriber.onNext(new HandlerResult(result)); |
|
|
|
public void onSubscribe(Subscription subscription) { |
|
|
|
} |
|
|
|
subscription.request(Long.MAX_VALUE); |
|
|
|
|
|
|
|
} |
|
|
|
@Override |
|
|
|
|
|
|
|
public void onError(Throwable error) { |
|
|
|
@Override |
|
|
|
subscriber.onError(error); |
|
|
|
public void onNext(Object result) { |
|
|
|
} |
|
|
|
invokeOnNext(new HandlerResult(result)); |
|
|
|
|
|
|
|
} |
|
|
|
@Override |
|
|
|
|
|
|
|
public void onComplete() { |
|
|
|
@Override |
|
|
|
subscriber.onComplete(); |
|
|
|
public void onError(Throwable error) { |
|
|
|
} |
|
|
|
invokeOnError(error); |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void onComplete() { |
|
|
|
|
|
|
|
invokeOnComplete(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -159,74 +139,13 @@ public class DispatcherApp { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Publisher<Void> handleResult(ServerHttpRequest request, ServerHttpResponse response, |
|
|
|
public Publisher<Void> handleResult(ServerHttpRequest request, ServerHttpResponse response, HandlerResult result) { |
|
|
|
HandlerResult result) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
response.getHeaders().setContentType(MediaType.TEXT_PLAIN); |
|
|
|
response.getHeaders().setContentType(MediaType.TEXT_PLAIN); |
|
|
|
|
|
|
|
return response.writeWith(PublisherFactory.forEach((writeSubscriber) -> { |
|
|
|
return response.writeWith(new Publisher<byte[]>() { |
|
|
|
Charset charset = Charset.forName("UTF-8"); |
|
|
|
|
|
|
|
writeSubscriber.onNext(((String) result.getReturnValue()).getBytes(charset)); |
|
|
|
@Override |
|
|
|
writeSubscriber.onComplete(); |
|
|
|
public void subscribe(Subscriber<? super byte[]> writeSubscriber) { |
|
|
|
})); |
|
|
|
writeSubscriber.onSubscribe(new AbstractSubscription<byte[]>(writeSubscriber) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
protected void requestInternal(long n) { |
|
|
|
|
|
|
|
Charset charset = Charset.forName("UTF-8"); |
|
|
|
|
|
|
|
invokeOnNext(((String) result.getReturnValue()).getBytes(charset)); |
|
|
|
|
|
|
|
invokeOnComplete(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static abstract class AbstractSubscription<T> implements Subscription { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Subscriber<? super T> subscriber; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private volatile boolean terminated; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AbstractSubscription(Subscriber<? super T> subscriber) { |
|
|
|
|
|
|
|
this.subscriber = subscriber; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected boolean isTerminated() { |
|
|
|
|
|
|
|
return this.terminated; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void request(long n) { |
|
|
|
|
|
|
|
if (isTerminated()) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (n > 0) { |
|
|
|
|
|
|
|
requestInternal(n); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected abstract void requestInternal(long n); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void cancel() { |
|
|
|
|
|
|
|
this.terminated = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void invokeOnNext(T data) { |
|
|
|
|
|
|
|
this.subscriber.onNext(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void invokeOnError(Throwable error) { |
|
|
|
|
|
|
|
this.terminated = true; |
|
|
|
|
|
|
|
this.subscriber.onError(error); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void invokeOnComplete() { |
|
|
|
|
|
|
|
this.terminated = true; |
|
|
|
|
|
|
|
this.subscriber.onComplete(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|