Support client round robin to multiple server addresses.

Change-Id: If87dc64a485b1c8a340c5f6fa39ca09d40133e30
This commit is contained in:
Peter Johnson
2016-04-08 13:31:35 -07:00
parent b8ad1de33c
commit 5ac68f74d4
12 changed files with 175 additions and 25 deletions

View File

@@ -25,6 +25,7 @@ static jclass connectionInfoCls = nullptr;
static jclass entryInfoCls = nullptr;
static jclass keyNotDefinedEx = nullptr;
static jclass persistentEx = nullptr;
static jclass illegalArgEx = nullptr;
// Thread-attached environment for listener callbacks.
static JNIEnv *listenerEnv = nullptr;
@@ -102,6 +103,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
if (!persistentEx) return JNI_ERR;
env->DeleteLocalRef(local);
local = env->FindClass("java/lang/IllegalArgumentException");
if (!local) return JNI_ERR;
illegalArgEx = static_cast<jclass>(env->NewGlobalRef(local));
if (!illegalArgEx) return JNI_ERR;
env->DeleteLocalRef(local);
// Initial configuration of listener start/exit
nt::SetListenerOnStart(ListenerOnStart);
nt::SetListenerOnExit(ListenerOnExit);
@@ -121,6 +128,7 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
if (entryInfoCls) env->DeleteGlobalRef(entryInfoCls);
if (keyNotDefinedEx) env->DeleteGlobalRef(keyNotDefinedEx);
if (persistentEx) env->DeleteGlobalRef(persistentEx);
if (illegalArgEx) env->DeleteGlobalRef(illegalArgEx);
jvm = nullptr;
}
@@ -1196,12 +1204,48 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
* Method: startClient
* Signature: (Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient__Ljava_lang_String_2I
(JNIEnv *env, jclass, jstring serverName, jint port)
{
nt::StartClient(JavaStringRef(env, serverName).c_str(), port);
}
/*
* Class: edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
* Method: startClient
* Signature: ([Ljava/lang/String;[I)V
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient___3Ljava_lang_String_2_3I
(JNIEnv *env, jclass, jobjectArray serverNames, jintArray ports)
{
int len = env->GetArrayLength(serverNames);
if (len != env->GetArrayLength(ports)) {
env->ThrowNew(illegalArgEx,
"serverNames and ports arrays must be the same size");
return;
}
jint* portInts = env->GetIntArrayElements(ports, nullptr);
if (!portInts) return;
std::vector<std::string> names;
std::vector<std::pair<nt::StringRef, unsigned int>> servers;
names.reserve(len);
servers.reserve(len);
for (int i = 0; i < len; ++i) {
JavaLocal<jstring> elem(
env, static_cast<jstring>(env->GetObjectArrayElement(serverNames, i)));
if (!elem) {
env->ThrowNew(illegalArgEx, "null string in serverNames");
return;
}
names.emplace_back(JavaStringRef(env, elem).str());
servers.emplace_back(std::make_pair(nt::StringRef(names.back()),
portInts[i]));
}
env->ReleaseIntArrayElements(ports, portInts, JNI_ABORT);
nt::StartClient(servers);
}
/*
* Class: edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
* Method: stopClient

View File

@@ -23,7 +23,7 @@ public class NetworkTable implements ITable, IRemote {
private static boolean client = false;
private static boolean running = false;
private static int port = DEFAULT_PORT;
private static String ipAddress = "";
private static String[] ipAddresses = new String[0];
private static String persistentFilename = "networktables.ini";
private synchronized static void checkInit() {
@@ -38,9 +38,12 @@ public class NetworkTable implements ITable, IRemote {
public synchronized static void initialize() {
if (running)
shutdown();
if (client)
NetworkTablesJNI.startClient(ipAddress, port);
else
if (client) {
int[] ports = new int[ipAddresses.length];
for (int i=0; i<ipAddresses.length; i++)
ports[i] = port;
NetworkTablesJNI.startClient(ipAddresses, ports);
} else
NetworkTablesJNI.startServer(persistentFilename, "", port);
running = true;
}
@@ -95,10 +98,31 @@ public class NetworkTable implements ITable, IRemote {
* mode
*/
public synchronized static void setIPAddress(final String address) {
if (ipAddress.equals(address))
if (ipAddresses.length == 1 && ipAddresses[0].equals(address))
return;
checkInit();
ipAddress = address;
ipAddresses = new String[1];
ipAddresses[0] = address;
}
/**
* @param addresses the adresses that network tables will connect to in
* client mode (in round robin order)
*/
public synchronized static void setIPAddress(final String[] addresses) {
if (ipAddresses.length == addresses.length) {
boolean match = true;
for (int i=0; i<addresses.length; i++) {
if (!ipAddresses[i].equals(addresses[i])) {
match = false;
break;
}
}
if (match)
return;
}
checkInit();
ipAddresses = addresses;
}
/**

View File

@@ -141,6 +141,7 @@ public class NetworkTablesJNI {
public static native void startServer(String persistFilename, String listenAddress, int port);
public static native void stopServer();
public static native void startClient(String serverName, int port);
public static native void startClient(String[] serverNames, int[] ports);
public static native void stopClient();
public static native void setUpdateRate(double interval);