Negotiate + SignalR Service Support for the Java client (#2882)

This commit is contained in:
Mikael Mengistu 2018-09-05 16:53:07 -07:00 committed by GitHub
parent ac7ca5b270
commit dc6088bf21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 452 additions and 188 deletions

View File

@ -18,6 +18,7 @@ dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12' testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation "org.java-websocket:Java-WebSocket:1.3.8" implementation "org.java-websocket:Java-WebSocket:1.3.8"
implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
} }
task sourceJar(type: Jar) { task sourceJar(type: Jar) {

View File

@ -9,16 +9,18 @@ public class Chat {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
System.out.println("Enter the URL of the SignalR Chat you want to join"); System.out.println("Enter the URL of the SignalR Chat you want to join");
Scanner reader = new Scanner(System.in); // Reading from System.in Scanner reader = new Scanner(System.in); // Reading from System.in
String input; String input = reader.nextLine();
input = reader.nextLine();
System.out.print("Enter your name:");
String enteredName = reader.nextLine();
HubConnection hubConnection = new HubConnectionBuilder() HubConnection hubConnection = new HubConnectionBuilder()
.withUrl(input) .withUrl(input)
.configureLogging(LogLevel.Information).build(); .configureLogging(LogLevel.Information).build();
hubConnection.on("Send", (message) -> { hubConnection.on("Send", (name, message) -> {
System.out.println("REGISTERED HANDLER: " + message); System.out.println(name + ": " + message);
}, String.class); }, String.class, String.class);
hubConnection.onClosed((ex) -> { hubConnection.onClosed((ex) -> {
if (ex.getMessage() != null) { if (ex.getMessage() != null) {
@ -29,10 +31,11 @@ public class Chat {
//This is a blocking call //This is a blocking call
hubConnection.start(); hubConnection.start();
while (!input.equals("leave")){ String message = "";
while (!message.equals("leave")) {
// Scans the next token of the input as an int. // Scans the next token of the input as an int.
input = reader.nextLine(); message = reader.nextLine();
hubConnection.send("Send", input); hubConnection.send("Send", enteredName, message);
} }
hubConnection.stop(); hubConnection.stop();

View File

@ -5,9 +5,11 @@ package com.microsoft.aspnet.signalr;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
public class HubConnection { public class HubConnection {
@ -22,8 +24,14 @@ public class HubConnection {
private HubConnectionState connectionState = HubConnectionState.DISCONNECTED; private HubConnectionState connectionState = HubConnectionState.DISCONNECTED;
private Logger logger; private Logger logger;
private List<Consumer<Exception>> onClosedCallbackList; private List<Consumer<Exception>> onClosedCallbackList;
private boolean skipNegotiate = false;
private NegotiateResponse negotiateResponse;
private String accessToken;
private Map<String, String> headers = new HashMap<>();
public HubConnection(String url, Transport transport, Logger logger){ private static int MAX_NEGOTIATE_ATTEMPTS = 100;
public HubConnection(String url, Transport transport, Logger logger, boolean skipNegotiate) {
this.url = url; this.url = url;
this.protocol = new JsonHubProtocol(); this.protocol = new JsonHubProtocol();
@ -32,7 +40,7 @@ public class HubConnection {
} else { } else {
this.logger = new NullLogger(); this.logger = new NullLogger();
} }
this.skipNegotiate = skipNegotiate;
this.callback = (payload) -> { this.callback = (payload) -> {
if (!handshakeReceived) { if (!handshakeReceived) {
@ -92,19 +100,22 @@ public class HubConnection {
} }
}; };
if (transport == null){ if (transport != null) {
try {
this.transport = new WebSocketTransport(this.url, this.logger);
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else {
this.transport = transport; this.transport = transport;
} }
} }
public HubConnection(String url, Transport transport, Logger logger) {
this(url, transport, logger, false);
}
public HubConnection(String url, Transport transport, boolean skipNegotiate) {
this(url, transport, new NullLogger(), skipNegotiate);
}
/** /**
* Initializes a new instance of the {@link HubConnection} class. * Initializes a new instance of the {@link HubConnection} class.
*
* @param url The url of the SignalR server to connect to. * @param url The url of the SignalR server to connect to.
* @param transport The {@link Transport} that the client will use to communicate with the server. * @param transport The {@link Transport} that the client will use to communicate with the server.
*/ */
@ -114,6 +125,7 @@ public class HubConnection {
/** /**
* Initializes a new instance of the {@link HubConnection} class. * Initializes a new instance of the {@link HubConnection} class.
*
* @param url The url of the SignalR server to connect to. * @param url The url of the SignalR server to connect to.
*/ */
public HubConnection(String url) { public HubConnection(String url) {
@ -122,6 +134,7 @@ public class HubConnection {
/** /**
* Initializes a new instance of the {@link HubConnection} class. * Initializes a new instance of the {@link HubConnection} class.
*
* @param url The url of the SignalR server to connect to. * @param url The url of the SignalR server to connect to.
* @param logLevel The minimum level of messages to log. * @param logLevel The minimum level of messages to log.
*/ */
@ -131,6 +144,7 @@ public class HubConnection {
/** /**
* Indicates the state of the {@link HubConnection} to the server. * Indicates the state of the {@link HubConnection} to the server.
*
* @return HubConnection state enum. * @return HubConnection state enum.
*/ */
public HubConnectionState getConnectionState() { public HubConnectionState getConnectionState() {
@ -139,14 +153,47 @@ public class HubConnection {
/** /**
* Starts a connection to the server. * Starts a connection to the server.
*
* @throws Exception An error occurred while connecting. * @throws Exception An error occurred while connecting.
*/ */
public void start() throws Exception { public void start() throws Exception {
if (connectionState != HubConnectionState.DISCONNECTED) { if (connectionState != HubConnectionState.DISCONNECTED) {
return; return;
} }
if (!skipNegotiate) {
int negotiateAttempts = 0;
do {
accessToken = (negotiateResponse == null) ? null : negotiateResponse.getAccessToken();
negotiateResponse = Negotiate.processNegotiate(url, accessToken);
if (negotiateResponse.getConnectionId() != null) {
if (url.contains("?")) {
url = url + "&id=" + negotiateResponse.getConnectionId();
} else {
url = url + "?id=" + negotiateResponse.getConnectionId();
}
}
if (negotiateResponse.getAccessToken() != null) {
this.headers.put("Authorization", "Bearer " + negotiateResponse.getAccessToken());
}
if (negotiateResponse.getRedirectUrl() != null) {
url = this.negotiateResponse.getRedirectUrl();
}
negotiateAttempts++;
} while (negotiateResponse.getRedirectUrl() != null && negotiateAttempts < MAX_NEGOTIATE_ATTEMPTS);
if (!negotiateResponse.getAvailableTransports().contains("WebSockets")) {
throw new HubException("There were no compatible transports on the server.");
}
}
logger.log(LogLevel.Debug, "Starting HubConnection"); logger.log(LogLevel.Debug, "Starting HubConnection");
if (transport == null) {
transport = new WebSocketTransport(url, logger, headers);
}
transport.setOnReceive(this.callback); transport.setOnReceive(this.callback);
transport.start(); transport.start();
String handshake = HandshakeProtocol.createHandshakeRequestMessage(new HandshakeRequestMessage(protocol.getName(), protocol.getVersion())); String handshake = HandshakeProtocol.createHandshakeRequestMessage(new HandshakeRequestMessage(protocol.getName(), protocol.getVersion()));
@ -190,6 +237,7 @@ public class HubConnection {
/** /**
* Invokes a hub method on the server using the specified method name. * Invokes a hub method on the server using the specified method name.
* Does not wait for a response from the receiver. * Does not wait for a response from the receiver.
*
* @param method The name of the server method to invoke. * @param method The name of the server method to invoke.
* @param args The arguments to be passed to the method. * @param args The arguments to be passed to the method.
* @throws Exception If there was an error while sending. * @throws Exception If there was an error while sending.
@ -207,6 +255,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @return A {@link Subscription} that can be disposed to unsubscribe from the hub method. * @return A {@link Subscription} that can be disposed to unsubscribe from the hub method.
@ -220,6 +269,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -235,6 +285,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -254,6 +305,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -276,6 +328,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -300,6 +353,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -327,6 +381,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -356,6 +411,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -387,6 +443,7 @@ public class HubConnection {
/** /**
* Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Registers a handler that will be invoked when the hub method with the specified method name is invoked.
*
* @param target The name of the hub method to define. * @param target The name of the hub method to define.
* @param callback The handler that will be raised when the hub method is invoked. * @param callback The handler that will be raised when the hub method is invoked.
* @param param1 The first parameter. * @param param1 The first parameter.
@ -420,6 +477,7 @@ public class HubConnection {
/** /**
* Removes all handlers associated with the method with the specified method name. * Removes all handlers associated with the method with the specified method name.
*
* @param name The name of the hub method from which handlers are being removed. * @param name The name of the hub method from which handlers are being removed.
*/ */
public void remove(String name) { public void remove(String name) {

View File

@ -0,0 +1,63 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
package com.microsoft.aspnet.signalr;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
public class Negotiate {
public static NegotiateResponse processNegotiate(String url) throws IOException {
return processNegotiate(url, null);
}
public static NegotiateResponse processNegotiate(String url, String accessTokenHeader) throws IOException {
url = resolveNegotiateUrl(url);
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(null, new byte[]{});
Request.Builder requestBuilder = new Request.Builder()
.url(url)
.post(body);
if (accessTokenHeader != null) {
requestBuilder.addHeader("Authorization", "Bearer " + accessTokenHeader);
}
Request request = requestBuilder.build();
Response response = client.newCall(request).execute();
String result = response.body().string();
return new NegotiateResponse(result);
}
public static String resolveNegotiateUrl(String url) {
String negotiateUrl = "";
// Check if we have a query string. If we do then we ignore it for now.
int queryStringIndex = url.indexOf('?');
if (queryStringIndex > 0) {
negotiateUrl = url.substring(0, url.indexOf('?'));
} else {
negotiateUrl = url;
}
//Check if the url ends in a /
if (negotiateUrl.charAt(negotiateUrl.length() - 1) != '/') {
negotiateUrl += "/";
}
negotiateUrl += "negotiate";
// Add the query string back if it existed.
if (queryStringIndex > 0) {
negotiateUrl += url.substring(url.indexOf('?'));
}
return negotiateUrl;
}
}

View File

@ -0,0 +1,52 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
package com.microsoft.aspnet.signalr;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.HashSet;
import java.util.Set;
public class NegotiateResponse {
private String connectionId;
private Set<String> availableTransports = new HashSet<>();
private String redirectUrl;
private String accessToken;
private JsonParser jsonParser = new JsonParser();
public NegotiateResponse(String negotiatePayload) {
JsonObject negotiateResponse = jsonParser.parse(negotiatePayload).getAsJsonObject();
if (negotiateResponse.has("url")) {
this.redirectUrl = negotiateResponse.get("url").getAsString();
if (negotiateResponse.has("accessToken")) {
this.accessToken = negotiateResponse.get("accessToken").getAsString();
}
return;
}
this.connectionId = negotiateResponse.get("connectionId").getAsString();
JsonArray transports = (JsonArray) negotiateResponse.get("availableTransports");
for (int i = 0; i < transports.size(); i++) {
availableTransports.add(transports.get(i).getAsJsonObject().get("transport").getAsString());
}
}
public String getConnectionId() {
return connectionId;
}
public Set<String> getAvailableTransports() {
return availableTransports;
}
public String getRedirectUrl() {
return redirectUrl;
}
public String getAccessToken() {
return accessToken;
}
}

View File

@ -5,6 +5,9 @@ package com.microsoft.aspnet.signalr;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.java_websocket.client.WebSocketClient; import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake; import org.java_websocket.handshake.ServerHandshake;
@ -13,15 +16,21 @@ public class WebSocketTransport implements Transport {
private OnReceiveCallBack onReceiveCallBack; private OnReceiveCallBack onReceiveCallBack;
private URI url; private URI url;
private Logger logger; private Logger logger;
private Map<String, String> headers;
private static final String HTTP = "http"; private static final String HTTP = "http";
private static final String HTTPS = "https"; private static final String HTTPS = "https";
private static final String WS = "ws"; private static final String WS = "ws";
private static final String WSS = "wss"; private static final String WSS = "wss";
public WebSocketTransport(String url, Logger logger) throws URISyntaxException { public WebSocketTransport(String url, Logger logger, Map<String, String> headers) throws URISyntaxException {
this.url = formatUrl(url); this.url = formatUrl(url);
this.logger = logger; this.logger = logger;
this.headers = headers;
}
public WebSocketTransport(String url, Logger logger) throws URISyntaxException {
this(url, logger, null);
} }
public URI getUrl() { public URI getUrl() {
@ -31,17 +40,18 @@ public class WebSocketTransport implements Transport {
private URI formatUrl(String url) throws URISyntaxException { private URI formatUrl(String url) throws URISyntaxException {
if (url.startsWith(HTTPS)) { if (url.startsWith(HTTPS)) {
url = WSS + url.substring(HTTPS.length()); url = WSS + url.substring(HTTPS.length());
} } else if (url.startsWith(HTTP)) {
else if(url.startsWith(HTTP)){
url = WS + url.substring(HTTP.length()); url = WS + url.substring(HTTP.length());
} }
return new URI(url); return new URI(url);
} }
@Override @Override
public void start() throws Exception { public void start() throws Exception {
logger.log(LogLevel.Debug, "Starting Websocket connection."); logger.log(LogLevel.Debug, "Starting Websocket connection.");
webSocketClient = createWebSocket(); webSocketClient = createWebSocket(headers);
if (!webSocketClient.connectBlocking()) { if (!webSocketClient.connectBlocking()) {
String errorMessage = "There was an error starting the Websockets transport."; String errorMessage = "There was an error starting the Websockets transport.";
logger.log(LogLevel.Debug, errorMessage); logger.log(LogLevel.Debug, errorMessage);
@ -72,8 +82,8 @@ public class WebSocketTransport implements Transport {
logger.log(LogLevel.Information, "WebSocket connection stopped"); logger.log(LogLevel.Information, "WebSocket connection stopped");
} }
private WebSocketClient createWebSocket() { private WebSocketClient createWebSocket(Map<String, String> headers) {
return new WebSocketClient(url) { return new WebSocketClient(url, headers) {
@Override @Override
public void onOpen(ServerHandshake handshakedata) { public void onOpen(ServerHandshake handshakedata) {
System.out.println("Connected to " + url); System.out.println("Connected to " + url);

View File

@ -17,7 +17,7 @@ public class HubConnectionTest {
@Test @Test
public void checkHubConnectionState() throws Exception { public void checkHubConnectionState() throws Exception {
Transport mockTransport = new MockTransport(); Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.start(); hubConnection.start();
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());
@ -28,7 +28,7 @@ public class HubConnectionTest {
@Test @Test
public void HubConnectionClosesAfterCloseMessage() throws Exception { public void HubConnectionClosesAfterCloseMessage() throws Exception {
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.start(); hubConnection.start();
mockTransport.receiveMessage("{}" + RECORD_SEPARATOR); mockTransport.receiveMessage("{}" + RECORD_SEPARATOR);
@ -44,7 +44,7 @@ public class HubConnectionTest {
public void RegisteringMultipleHandlersAndBothGetTriggered() throws Exception { public void RegisteringMultipleHandlersAndBothGetTriggered() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action); hubConnection.on("inc", action);
@ -70,7 +70,7 @@ public class HubConnectionTest {
public void RemoveHandlerByName() throws Exception { public void RemoveHandlerByName() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action); hubConnection.on("inc", action);
@ -97,7 +97,7 @@ public class HubConnectionTest {
public void AddAndRemoveHandlerImmediately() throws Exception { public void AddAndRemoveHandlerImmediately() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
hubConnection.on("inc", action); hubConnection.on("inc", action);
@ -122,7 +122,7 @@ public class HubConnectionTest {
public void RemovingMultipleHandlersWithOneCallToRemove() throws Exception { public void RemovingMultipleHandlersWithOneCallToRemove() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
Action secondAction = () -> value.getAndUpdate((val) -> val + 2); Action secondAction = () -> value.getAndUpdate((val) -> val + 2);
@ -154,7 +154,7 @@ public class HubConnectionTest {
public void RemoveHandlerWithUnsubscribe() throws Exception { public void RemoveHandlerWithUnsubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription subscription = hubConnection.on("inc", action); Subscription subscription = hubConnection.on("inc", action);
@ -182,7 +182,7 @@ public class HubConnectionTest {
public void UnsubscribeTwice() throws Exception { public void UnsubscribeTwice() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription subscription = hubConnection.on("inc", action); Subscription subscription = hubConnection.on("inc", action);
@ -211,7 +211,7 @@ public class HubConnectionTest {
public void RemoveSingleHandlerWithUnsubscribe() throws Exception { public void RemoveSingleHandlerWithUnsubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
Action secondAction = () -> value.getAndUpdate((val) -> val + 2); Action secondAction = () -> value.getAndUpdate((val) -> val + 2);
@ -241,7 +241,7 @@ public class HubConnectionTest {
public void AddAndRemoveHandlerImmediatelyWithSubscribe() throws Exception { public void AddAndRemoveHandlerImmediatelyWithSubscribe() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action action = () -> value.getAndUpdate((val) -> val + 1); Action action = () -> value.getAndUpdate((val) -> val + 1);
Subscription sub = hubConnection.on("inc", action); Subscription sub = hubConnection.on("inc", action);
@ -260,7 +260,7 @@ public class HubConnectionTest {
public void RegisteringMultipleHandlersThatTakeParamsAndBothGetTriggered() throws Exception { public void RegisteringMultipleHandlersThatTakeParamsAndBothGetTriggered() throws Exception {
AtomicReference<Double> value = new AtomicReference<>(0.0); AtomicReference<Double> value = new AtomicReference<>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
Action1<Double> action = (number) -> value.getAndUpdate((val) -> val + number); Action1<Double> action = (number) -> value.getAndUpdate((val) -> val + number);
@ -282,7 +282,7 @@ public class HubConnectionTest {
public void SendWithNoParamsTriggersOnHandler() throws Exception { public void SendWithNoParamsTriggersOnHandler() throws Exception {
AtomicReference<Double> value = new AtomicReference<Double>(0.0); AtomicReference<Double> value = new AtomicReference<Double>(0.0);
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", () ->{ hubConnection.on("inc", () ->{
assertEquals(0.0, value.get(), 0); assertEquals(0.0, value.get(), 0);
@ -301,7 +301,7 @@ public class HubConnectionTest {
public void SendWithParamTriggersOnHandler() throws Exception { public void SendWithParamTriggersOnHandler() throws Exception {
AtomicReference<String> value = new AtomicReference<>(); AtomicReference<String> value = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param) ->{ hubConnection.on("inc", (param) ->{
assertNull(value.get()); assertNull(value.get());
@ -323,7 +323,7 @@ public class HubConnectionTest {
AtomicReference<Double> value2 = new AtomicReference<>(); AtomicReference<Double> value2 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2) ->{ hubConnection.on("inc", (param1, param2) ->{
assertNull(value1.get()); assertNull(value1.get());
@ -350,7 +350,7 @@ public class HubConnectionTest {
AtomicReference<String> value3 = new AtomicReference<>(); AtomicReference<String> value3 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3) ->{ hubConnection.on("inc", (param1, param2, param3) ->{
assertNull(value1.get()); assertNull(value1.get());
@ -381,7 +381,7 @@ public class HubConnectionTest {
AtomicReference<String> value4 = new AtomicReference<>(); AtomicReference<String> value4 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3, param4) ->{ hubConnection.on("inc", (param1, param2, param3, param4) ->{
assertNull(value1.get()); assertNull(value1.get());
@ -415,7 +415,7 @@ public class HubConnectionTest {
AtomicReference<Double> value5 = new AtomicReference<>(); AtomicReference<Double> value5 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3, param4, param5) ->{ hubConnection.on("inc", (param1, param2, param3, param4, param5) ->{
assertNull(value1.get()); assertNull(value1.get());
@ -453,7 +453,7 @@ public class HubConnectionTest {
AtomicReference<String> value6 = new AtomicReference<>(); AtomicReference<String> value6 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6) -> { hubConnection.on("inc", (param1, param2, param3, param4, param5, param6) -> {
assertNull(value1.get()); assertNull(value1.get());
@ -495,7 +495,7 @@ public class HubConnectionTest {
AtomicReference<String> value7 = new AtomicReference<>(); AtomicReference<String> value7 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7) -> { hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7) -> {
assertNull(value1.get()); assertNull(value1.get());
@ -541,7 +541,7 @@ public class HubConnectionTest {
AtomicReference<String> value8 = new AtomicReference<>(); AtomicReference<String> value8 = new AtomicReference<>();
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7, param8) -> { hubConnection.on("inc", (param1, param2, param3, param4, param5, param6, param7, param8) -> {
assertNull(value1.get()); assertNull(value1.get());
@ -580,8 +580,8 @@ public class HubConnectionTest {
@Test @Test
public void ReceiveHandshakeResponseAndMessage() throws Exception { public void ReceiveHandshakeResponseAndMessage() throws Exception {
AtomicReference<Double> value = new AtomicReference<Double>(0.0); AtomicReference<Double> value = new AtomicReference<Double>(0.0);
MockTransport transport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", transport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.on("inc", () ->{ hubConnection.on("inc", () ->{
assertEquals(0.0, value.get(), 0); assertEquals(0.0, value.get(), 0);
@ -591,9 +591,9 @@ public class HubConnectionTest {
// On start we're going to receive the handshake response and also an invocation in the same payload. // On start we're going to receive the handshake response and also an invocation in the same payload.
hubConnection.start(); hubConnection.start();
String expectedSentMessage = "{\"protocol\":\"json\",\"version\":1}" + RECORD_SEPARATOR; String expectedSentMessage = "{\"protocol\":\"json\",\"version\":1}" + RECORD_SEPARATOR;
assertEquals(expectedSentMessage, transport.getSentMessages()[0]); assertEquals(expectedSentMessage, mockTransport.getSentMessages()[0]);
transport.receiveMessage("{}" + RECORD_SEPARATOR + "{\"type\":1,\"target\":\"inc\",\"arguments\":[]}" + RECORD_SEPARATOR); mockTransport.receiveMessage("{}" + RECORD_SEPARATOR + "{\"type\":1,\"target\":\"inc\",\"arguments\":[]}" + RECORD_SEPARATOR);
// Confirming that our handler was called and that the counter property was incremented. // Confirming that our handler was called and that the counter property was incremented.
assertEquals(1, value.get(), 0); assertEquals(1, value.get(), 0);
@ -603,7 +603,7 @@ public class HubConnectionTest {
public void onClosedCallbackRunsWhenStopIsCalled() throws Exception { public void onClosedCallbackRunsWhenStopIsCalled() throws Exception {
AtomicReference<String> value1 = new AtomicReference<>(); AtomicReference<String> value1 = new AtomicReference<>();
Transport mockTransport = new MockTransport(); Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.start(); hubConnection.start();
hubConnection.onClosed((ex) -> { hubConnection.onClosed((ex) -> {
assertNull(value1.get()); assertNull(value1.get());
@ -620,7 +620,7 @@ public class HubConnectionTest {
AtomicReference<String> value1 = new AtomicReference<>(); AtomicReference<String> value1 = new AtomicReference<>();
AtomicReference<String> value2 = new AtomicReference<>(); AtomicReference<String> value2 = new AtomicReference<>();
Transport mockTransport = new MockTransport(); Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.start(); hubConnection.start();
hubConnection.onClosed((ex) -> { hubConnection.onClosed((ex) -> {
@ -645,7 +645,7 @@ public class HubConnectionTest {
@Test @Test
public void HubConnectionClosesAndRunsOnClosedCallbackAfterCloseMessageWithError() throws Exception { public void HubConnectionClosesAndRunsOnClosedCallbackAfterCloseMessageWithError() throws Exception {
MockTransport mockTransport = new MockTransport(); MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.onClosed((ex) -> { hubConnection.onClosed((ex) -> {
assertEquals(ex.getMessage(), "There was an error"); assertEquals(ex.getMessage(), "There was an error");
}); });
@ -662,7 +662,7 @@ public class HubConnectionTest {
@Test @Test
public void CallingStartOnStartedHubConnectionNoOps() throws Exception { public void CallingStartOnStartedHubConnectionNoOps() throws Exception {
Transport mockTransport = new MockTransport(); Transport mockTransport = new MockTransport();
HubConnection hubConnection = new HubConnection("http://example.com", mockTransport); HubConnection hubConnection = new HubConnection("http://example.com", mockTransport, true);
hubConnection.start(); hubConnection.start();
assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState());

View File

@ -0,0 +1,38 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
import com.microsoft.aspnet.signalr.NegotiateResponse;
import org.junit.Test;
import static org.junit.Assert.*;
public class NegotiateResponseTest {
@Test
public void VerifyNegotiateResponse() {
String stringNegotiateResponse = "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\"" +
"availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}," +
"{\"transport\":\"ServerSentEvents\",\"transferFormats\":[\"Text\"]}," +
"{\"transport\":\"LongPolling\",\"transferFormats\":[\"Text\",\"Binary\"]}]}";
NegotiateResponse negotiateResponse = new NegotiateResponse(stringNegotiateResponse);
assertTrue(negotiateResponse.getAvailableTransports().contains("WebSockets"));
assertTrue(negotiateResponse.getAvailableTransports().contains("ServerSentEvents"));
assertTrue(negotiateResponse.getAvailableTransports().contains("LongPolling"));
assertNull(negotiateResponse.getAccessToken());
assertNull(negotiateResponse.getRedirectUrl());
assertEquals("bVOiRPG8-6YiJ6d7ZcTOVQ", negotiateResponse.getConnectionId());
}
@Test
public void VerifyRedirectNegotiateResponse() {
String stringNegotiateResponse = "{\"url\":\"www.example.com\"," +
"\"accessToken\":\"some_access_token\"," +
"\"availableTransports\":[]}";
NegotiateResponse negotiateResponse = new NegotiateResponse(stringNegotiateResponse);
assertTrue(negotiateResponse.getAvailableTransports().isEmpty());
assertNull(negotiateResponse.getConnectionId());
assertEquals("some_access_token", negotiateResponse.getAccessToken());
assertEquals("www.example.com", negotiateResponse.getRedirectUrl());
assertNull(negotiateResponse.getConnectionId());
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
import com.microsoft.aspnet.signalr.Negotiate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class ResolveNegotiateUrlTest {
private String url;
private String resolvedUrl;
public ResolveNegotiateUrlTest(String url, String resolvedUrl) {
this.url = url;
this.resolvedUrl = resolvedUrl;
}
@Parameterized.Parameters
public static Collection protocols() {
return Arrays.asList(new String[][]{
{"http://example.com/hub/", "http://example.com/hub/negotiate"},
{"http://example.com/hub", "http://example.com/hub/negotiate"},
{"http://example.com/endpoint?q=my/Data", "http://example.com/endpoint/negotiate?q=my/Data"},
{"http://example.com/endpoint/?q=my/Data", "http://example.com/endpoint/negotiate?q=my/Data"},
{"http://example.com/endpoint/path/more?q=my/Data", "http://example.com/endpoint/path/more/negotiate?q=my/Data"},});
}
@Test
public void checkNegotiateUrl() {
String urlResult = Negotiate.resolveNegotiateUrl(this.url);
assertEquals(this.resolvedUrl, urlResult);
}
}