donky.microsoft.aspnet.signalr.client.hubs.HubConnection Maven / Gradle / Ivy
/*
Copyright (c) Microsoft Open Technologies, Inc.
All Rights Reserved
See License.txt in the project root for license information.
*/
package donky.microsoft.aspnet.signalr.client.hubs;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import donky.microsoft.aspnet.signalr.client.Action;
import donky.microsoft.aspnet.signalr.client.ConnectionState;
import donky.microsoft.aspnet.signalr.client.InvalidStateException;
import donky.microsoft.aspnet.signalr.client.LogLevel;
import donky.microsoft.aspnet.signalr.client.Logger;
import donky.microsoft.aspnet.signalr.client.Connection;
/**
* Represents a SignalRConnection that implements the Hubs protocol
*/
public class HubConnection extends Connection {
private Map> mCallbacks = Collections.synchronizedMap(new HashMap>());
private Map mHubs = Collections.synchronizedMap(new HashMap());
private Integer mCallbackId = 0;
/**
* Initializes the connection
*
* @param url
* The connection URL
* @param queryString
* The connection query string
* @param useDefaultUrl
* indicates if the default SignalR URL should be used
* @param logger
* The connection logger
*/
public HubConnection(String url, String queryString, boolean useDefaultUrl, Logger logger) {
super(getUrl(url, useDefaultUrl), queryString, logger);
}
/**
* Initialized the connection
*
* @param url
* The connection URL
*/
public HubConnection(String url) {
super(getUrl(url, true));
}
/**
* Initializes the connection
*
* @param url
* The connection URL
* @param useDefaultUrl
* indicates if the default SignalR URL should be used
*/
public HubConnection(String url, boolean useDefaultUrl) {
super(getUrl(url, useDefaultUrl));
}
@Override
public void onReceived(JsonElement message) {
super.onReceived(message);
log("Processing message", LogLevel.Information);
if (getState() == ConnectionState.Connected) {
if (message.isJsonObject() && message.getAsJsonObject().has("I")) {
log("Getting HubResult from message", LogLevel.Verbose);
HubResult result = mGson.fromJson(message, HubResult.class);
String id = result.getId().toLowerCase(Locale.getDefault());
log("Result Id: " + id, LogLevel.Verbose);
log("Result Data: " + result.getResult(), LogLevel.Verbose);
if (mCallbacks.containsKey(id)) {
log("Get and remove callback with id: " + id, LogLevel.Verbose);
Action callback = mCallbacks.remove(id);
try {
log("Execute callback for message", LogLevel.Verbose);
callback.run(result);
} catch (Exception e) {
onError(e, false);
}
}
} else {
HubInvocation invocation = mGson.fromJson(message, HubInvocation.class);
log("Getting HubInvocation from message", LogLevel.Verbose);
String hubName = invocation.getHub().toLowerCase(Locale.getDefault());
log("Message for: " + hubName, LogLevel.Verbose);
if (mHubs.containsKey(hubName)) {
HubProxy hubProxy = mHubs.get(hubName);
if (invocation.getState() != null) {
for (String key : invocation.getState().keySet()) {
JsonElement value = invocation.getState().get(key);
log("Setting state for hub: " + key + " -> " + value, LogLevel.Verbose);
hubProxy.setState(key, value);
}
}
String eventName = invocation.getMethod().toLowerCase(Locale.getDefault());
log("Invoking event: " + eventName + " with arguments " + arrayToString(invocation.getArgs()), LogLevel.Verbose);
try {
hubProxy.invokeEvent(eventName, invocation.getArgs());
} catch (Exception e) {
onError(e, false);
}
}
}
}
}
private static String arrayToString(JsonElement[] args) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < args.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(args[i].toString());
}
sb.append("]");
return sb.toString();
}
@Override
public String getConnectionData() {
JsonArray jsonArray = new JsonArray();
for (String hubName : mHubs.keySet()) {
JsonObject element = new JsonObject();
element.addProperty("name", hubName);
jsonArray.add(element);
}
String connectionData = jsonArray.toString();
log("Getting connection data: " + connectionData, LogLevel.Verbose);
return connectionData;
}
@Override
protected void onClosed() {
clearInvocationCallbacks("Connection closed");
super.onClosed();
}
private void clearInvocationCallbacks(String error) {
log("Clearing invocation callbacks: " + error, LogLevel.Verbose);
HubResult result = new HubResult();
result.setError(error);
for (String key : mCallbacks.keySet()) {
try {
log("Invoking callback with empty result: " + key, LogLevel.Verbose);
mCallbacks.get(key).run(result);
} catch (Exception e) {
}
}
mCallbacks.clear();
}
@Override
protected void onReconnecting() {
clearInvocationCallbacks("Reconnecting");
super.onReconnecting();
}
/**
* Creates a proxy for a hub
*
* @param hubName
* The hub name
* @return The proxy for the hub
* @throws InvalidStateException
* If called when not disconnected, the method will throw an
* exception
*/
public HubProxy createHubProxy(String hubName) {
if (mState != ConnectionState.Disconnected) {
throw new InvalidStateException(mState);
}
if (hubName == null) {
throw new IllegalArgumentException("hubName cannot be null");
}
String hubNameLower = hubName.toLowerCase(Locale.getDefault());
log("Creating hub proxy: " + hubNameLower, LogLevel.Information);
HubProxy proxy = null;
if (mHubs.containsKey(hubNameLower)) {
proxy = mHubs.get(hubNameLower);
} else {
proxy = new HubProxy(this, hubName, getLogger());
mHubs.put(hubNameLower, proxy);
}
return proxy;
}
/**
* Registers a callback
*
* @param callback
* The callback to register
* @return The callback Id
*/
String registerCallback(Action callback) {
String id = mCallbackId.toString().toLowerCase(Locale.getDefault());
log("Registering callback: " + id, LogLevel.Verbose);
mCallbacks.put(id, callback);
mCallbackId++;
return id;
}
/**
* Removes a callback
*
* @param callbackId
* Id for the callback to remove
*/
void removeCallback(String callbackId) {
log("Removing callback: " + callbackId, LogLevel.Verbose);
mCallbacks.remove(callbackId.toLowerCase(Locale.getDefault()));
}
/**
* Generates a standarized URL
*
* @param url
* The base URL
* @param useDefaultUrl
* Indicates if the default SignalR suffix should be appended
* @return The connection URL
*/
private static String getUrl(String url, boolean useDefaultUrl) {
if (!url.endsWith("/")) {
url += "/";
}
if (useDefaultUrl) {
return url + "signalr";
}
return url;
}
@Override
protected String getSourceNameForLog() {
return "HubConnection";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy