|
47 | 47 | import reactor.core.publisher.Mono;
|
48 | 48 | import reactor.core.scheduler.Schedulers;
|
49 | 49 | import reactor.util.annotation.Nullable;
|
| 50 | +import reactor.util.function.Tuples; |
50 | 51 | import reactor.util.retry.Retry;
|
51 | 52 |
|
52 | 53 | /**
|
@@ -77,7 +78,7 @@ public class RSocketConnector {
|
77 | 78 | private static final BiConsumer<RSocket, Invalidatable> INVALIDATE_FUNCTION =
|
78 | 79 | (r, i) -> r.onClose().subscribe(null, __ -> i.invalidate(), i::invalidate);
|
79 | 80 |
|
80 |
| - private Payload setupPayload = EmptyPayload.INSTANCE; |
| 81 | + private Mono<Payload> setupPayloadMono = Mono.empty(); |
81 | 82 | private String metadataMimeType = "application/binary";
|
82 | 83 | private String dataMimeType = "application/binary";
|
83 | 84 | private Duration keepAliveInterval = Duration.ofSeconds(20);
|
@@ -118,22 +119,38 @@ public static Mono<RSocket> connectWith(ClientTransport transport) {
|
118 | 119 | }
|
119 | 120 |
|
120 | 121 | /**
|
121 |
| - * Provide a {@code Payload} with data and/or metadata for the initial {@code SETUP} frame. Data |
122 |
| - * and metadata should be formatted according to the MIME types specified via {@link |
| 122 | + * Provide a {@code Mono} from which to obtain the {@code Payload} for the initial SETUP frame. |
| 123 | + * Data and metadata should be formatted according to the MIME types specified via {@link |
123 | 124 | * #dataMimeType(String)} and {@link #metadataMimeType(String)}.
|
124 | 125 | *
|
125 |
| - * @param payload the payload containing data and/or metadata for the {@code SETUP} frame. Note, |
126 |
| - * if the instance of the given payload is not a {@link DefaultPayload}, its content will be |
127 |
| - * copied |
| 126 | + * @param setupPayloadMono the payload with data and/or metadata for the {@code SETUP} frame. |
| 127 | + * @return the same instance for method chaining |
| 128 | + * @since 1.0.2 |
| 129 | + * @see <a href="https://github.com/rsocket/rsocket/blob/master/Protocol.md#frame-setup">SETUP |
| 130 | + * Frame</a> |
| 131 | + */ |
| 132 | + public RSocketConnector setupPayload(Mono<Payload> setupPayloadMono) { |
| 133 | + this.setupPayloadMono = setupPayloadMono; |
| 134 | + return this; |
| 135 | + } |
| 136 | + |
| 137 | + /** |
| 138 | + * Variant of {@link #setupPayload(Mono)} that accepts a {@code Payload} instance. |
| 139 | + * |
| 140 | + * <p>Note: if the given payload is {@link io.rsocket.util.ByteBufPayload}, it is copied to a |
| 141 | + * {@link DefaultPayload} and released immediately. This ensures it can re-used to obtain a |
| 142 | + * connection more than once. |
| 143 | + * |
| 144 | + * @param payload the payload with data and/or metadata for the {@code SETUP} frame. |
128 | 145 | * @return the same instance for method chaining
|
129 | 146 | * @see <a href="https://github.com/rsocket/rsocket/blob/master/Protocol.md#frame-setup">SETUP
|
130 | 147 | * Frame</a>
|
131 | 148 | */
|
132 | 149 | public RSocketConnector setupPayload(Payload payload) {
|
133 | 150 | if (payload instanceof DefaultPayload) {
|
134 |
| - this.setupPayload = payload; |
| 151 | + this.setupPayloadMono = Mono.just(payload); |
135 | 152 | } else {
|
136 |
| - this.setupPayload = DefaultPayload.create(Objects.requireNonNull(payload)); |
| 153 | + this.setupPayloadMono = Mono.just(DefaultPayload.create(Objects.requireNonNull(payload))); |
137 | 154 | payload.release();
|
138 | 155 | }
|
139 | 156 | return this;
|
@@ -479,9 +496,20 @@ public Mono<RSocket> connect(Supplier<ClientTransport> transportSupplier) {
|
479 | 496 | mtu > 0
|
480 | 497 | ? new FragmentationDuplexConnection(connection, mtu, "client")
|
481 | 498 | : new ReassemblyDuplexConnection(connection));
|
| 499 | + |
482 | 500 | return connectionMono
|
483 | 501 | .flatMap(
|
484 |
| - connection -> { |
| 502 | + connection -> |
| 503 | + setupPayloadMono |
| 504 | + .defaultIfEmpty(EmptyPayload.INSTANCE) |
| 505 | + .map(setupPayload -> Tuples.of(connection, setupPayload)) |
| 506 | + .doOnError(ex -> connection.dispose()) |
| 507 | + .doOnCancel(connection::dispose)) |
| 508 | + .flatMap( |
| 509 | + tuple -> { |
| 510 | + DuplexConnection connection = tuple.getT1(); |
| 511 | + Payload setupPayload = tuple.getT2(); |
| 512 | + |
485 | 513 | ByteBuf resumeToken;
|
486 | 514 | KeepAliveHandler keepAliveHandler;
|
487 | 515 | DuplexConnection wrappedConnection;
|
|
0 commit comments