Fix Java Client transport select (#8143)

This commit is contained in:
Mikael Mengistu 2019-03-05 11:31:56 -08:00 committed by GitHub
parent 2665f6d238
commit 9b4f8d79fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 3 deletions

View File

@ -93,6 +93,14 @@ public class HubConnection {
this.tickRate = tickRateInMilliseconds;
}
TransportEnum getTransportEnum() {
return this.transportEnum;
}
Transport getTransport() {
return transport;
}
HubConnection(String url, Transport transport, boolean skipNegotiate, HttpClient httpClient,
Single<String> accessTokenProvider, long handshakeResponseTimeout, Map<String, String> headers, TransportEnum transportEnum) {
if (url == null || url.isEmpty()) {
@ -235,7 +243,8 @@ public class HubConnection {
return httpClient.post(Negotiate.resolveNegotiateUrl(url), request).map((response) -> {
if (response.getStatusCode() != 200) {
throw new RuntimeException(String.format("Unexpected status code returned from negotiate: %d %s.", response.getStatusCode(), response.getStatusText()));
throw new RuntimeException(String.format("Unexpected status code returned from negotiate: %d %s.",
response.getStatusCode(), response.getStatusText()));
}
NegotiateResponse negotiateResponse = new NegotiateResponse(response.getContent());
@ -377,8 +386,15 @@ public class HubConnection {
if (response.getRedirectUrl() == null) {
Set<String> transports = response.getAvailableTransports();
if ((this.transportEnum == TransportEnum.ALL && !(transports.contains("WebSockets") || transports.contains("LongPolling"))) ||
(this.transportEnum == TransportEnum.WEBSOCKETS && !transports.contains("WebSockets")) ||
if (this.transportEnum == TransportEnum.ALL) {
if (transports.contains("WebSockets")) {
this.transportEnum = TransportEnum.WEBSOCKETS;
} else if (transports.contains("LongPolling")) {
this.transportEnum = TransportEnum.LONG_POLLING;
} else {
throw new RuntimeException("There were no compatible transports on the server.");
}
} else if (this.transportEnum == TransportEnum.WEBSOCKETS && !transports.contains("WebSockets") ||
(this.transportEnum == TransportEnum.LONG_POLLING && !transports.contains("LongPolling"))) {
throw new RuntimeException("There were no compatible transports on the server.");
}

View File

@ -11,8 +11,10 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.subjects.CompletableSubject;
import org.junit.jupiter.api.Test;
import io.reactivex.Observable;
@ -1219,6 +1221,74 @@ class HubConnectionTest {
assertEquals("{\"protocol\":\"json\",\"version\":1}" + RECORD_SEPARATOR, sentMessages[0]);
}
@Test
public void TransportAllUsesLongPollingWhenServerOnlySupportLongPolling() {
AtomicInteger requestCount = new AtomicInteger(0);
TestHttpClient client = new TestHttpClient().on("POST",
(req) -> Single.just(new HttpResponse(200, "",
"{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"LongPolling\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")))
.on("GET", (req) -> {
if (requestCount.get() == 0) {
requestCount.incrementAndGet();
return Single.just(new HttpResponse(200, "", ""));
}
return Single.just(new HttpResponse(204, "", ""));
});
HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withTransport(TransportEnum.ALL)
.withHttpClient(client)
.build();
hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait();
assertTrue(hubConnection.getTransport() instanceof LongPollingTransport);
hubConnection.stop().timeout(1, TimeUnit.SECONDS).blockingAwait();
}
@Test
public void ClientThatSelectsWebsocketsThrowsWhenWebsocketsAreNotAvailable() {
TestHttpClient client = new TestHttpClient().on("POST",
(req) -> Single.just(new HttpResponse(200, "",
"{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"LongPolling\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")))
.on("GET", (req) -> {
return Single.just(new HttpResponse(204, "", ""));
});
HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withTransport(TransportEnum.WEBSOCKETS)
.withHttpClient(client)
.build();
assertEquals(TransportEnum.WEBSOCKETS, hubConnection.getTransportEnum());
RuntimeException exception = assertThrows(RuntimeException.class,
() -> hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait());
assertEquals(exception.getMessage(), "There were no compatible transports on the server.");
}
@Test
public void ClientThatSelectsLongPollingThrowsWhenLongPollingIsNotAvailable() {
TestHttpClient client = new TestHttpClient().on("POST",
(req) -> Single.just(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\""
+ "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")));
HubConnection hubConnection = HubConnectionBuilder
.create("http://example.com")
.withTransport(TransportEnum.LONG_POLLING)
.withHttpClient(client)
.build();
assertEquals(TransportEnum.LONG_POLLING, hubConnection.getTransportEnum());
RuntimeException exception = assertThrows(RuntimeException.class,
() -> hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait());
assertEquals(exception.getMessage(), "There were no compatible transports on the server.");
}
@Test
public void receivingServerSentEventsTransportFromNegotiateFails() {
TestHttpClient client = new TestHttpClient().on("POST", "http://example.com/negotiate",