Just a second...

Remote Servers

To connect to a Diffusion™ server that is not in the same cluster, create a remote server definition. This can be used by a remote topic view.

This feature allows a client session to manage remote servers.

A remote server provides the configuration to connect to a Diffusion server belonging to a different cluster. Each server in the local cluster will establish a session with each remote server.

Higher level components, such as remote topic views, can specify the use of such remote servers by name. The connecting and disconnecting is handled automatically by the server (or servers in the same cluster) where the remote servers are defined.

A component can specify a remote server by name even if it does not exist (has not yet been created) and when the remote server is created the connection will take place automatically. If a remote server is removed and there are components that depend upon it, those components will be disabled.

Currently only remote topic views use a remote server definition.

Create a remote server definition

Required permissions: control_server

A client can create a new remote server definition using the createRemoteServer method of the RemoteServers feature..

If a remote server with the same name already exists, an error is returned.

If a topic view that specifies the named remote server exists, the remote server connection is immediately established. However, if no topic views mention the remote server, a connection is not established when it is created.

You can use the checkRemoteServer API method to check if the connection works.

A builder is provided which allows the following parameters to be supplied:

Parameters:

name
the name of the remote server
url
the URL to use to connect to the remote server
principal

the name of a principal used by the remote server to connect to the primary server (default anonymous)

credentials
to use for connecting to the primary server (default none)
missing topic notification filter

A topic selector which if specified will propagate missing topic notifications to the primary server if it matches with the subscription selector that matched no local topics (default no missing topic notifications are propagated)

connection options

allowing various connection options to be supplied (default applies default session connection options)

Java and Android
final RemoteServer server =
    session.feature(RemoteServers.class).createRemoteServer(
        Diffusion.newRemoteServerBuilder()
            .principal("admin")
            .credentials(Diffusion.credentials().password("password"))
            .create("Server_1", "ws://remote_server:80"))
        .get(5, SECONDS);

C
static int on_remote_server_created(
        DIFFUSION_REMOTE_SERVER_T *remote_server,
        LIST_T *errors,
        void *context)
{
        if (remote_server == NULL) {
                printf("The following errors occurred while creating the remote server:\n");
                for (int i = 0; i < list_get_size(errors); i++) {
                    ERROR_REPORT_T *report = list_get_data_indexed(errors, i);
                    printf("\t[%d, %d] %s\n", report->line, report->column, report->message);
                }
        }
        else {
                printf("Remote Server successfully created\n");
                char *name = diffusion_remote_server_get_name(remote_server);
                char *principal = diffusion_remote_server_get_principal(remote_server);
                char *url = diffusion_remote_server_get_url(remote_server);

                printf("%s: %s (%s)\n", name, url, principal);

                free(name);
                free(principal);
                free(url);
        }
        return HANDLER_SUCCESS;
}

static int on_remote_server_created_failed(
        SESSION_T *session,
        const DIFFUSION_ERROR_T *error)
{
        printf("An error has occurred while adding remote server definition: %s\n", error->message);
        return HANDLER_SUCCESS;
}


...


DIFFUSION_REMOTE_SERVER_BUILDER_T *builder =
        diffusion_remote_server_builder_init();

builder = diffusion_remote_server_builder_principal(
        builder,
        "admin");

CREDENTIALS_T *remote_server_credentials = credentials_create_password("password");
builder = diffusion_remote_server_builder_credentials(
        builder,
        remote_server_credentials);

DIFFUSION_API_ERROR api_error = { 0 };
DIFFUSION_REMOTE_SERVER_T *remote_server =
        diffusion_remote_server_builder_create(
                builder,
                "New Remote Server",    // remote server name
                "10.0.0.4",             // remote server URL
                &api_error);            // api error in case of invalid parameters

DIFFUSION_CREATE_REMOTE_SERVER_PARAMS_T create_remote_server_params = {
        .remote_server = remote_server,
        .on_remote_server_created = on_remote_server_created,
        .on_error = on_remote_server_created_failed
};
diffusion_create_remote_server(session, create_remote_server_params, NULL);
Apple
let credentials = PTDiffusionCredentials.init(password: "password")

let remote_server_definition = PTDiffusionRemoteServerBuilder()
    .principal("admin")
    .credentials(credentials)
    .create(withName: "New Remote Server", andURL: "10.0.0.4")

session.remoteServers.createRemoteServer(remote_server_definition) { (result, error) in
    if (error != nil) {
        print("An error has occurred while adding remote server definition: %@",
              error!.localizedDescription)
    }
    else if (result!.isSuccess) {
        print("Remote Server '%@' successfully added.", remote_server_definition.name)
    }
    else {
        print("Remote Server '%@' not added. Errors:", remote_server_definition.name)
        for error in result!.errors {
            print("%@", error.localizedDescription);
        }
    }

}

Check a remote server definition

Required permissions: control_server

Used to check the current state of a named remote server.

It can be used to retrieve the current state of the named remote server, but it can also be used to forcibly retry a failed connection to the remote server

Parameters:

name
the name of the remote server
Java and Android
final CheckRemoteServerResult result =
    session.feature(RemoteServers.class).checkRemoteServer("Server_1")
        .get(5, SECONDS);

switch (result.getConnectionState()) {
case CONNECTED:
    LOG.info("Connected and in use");
    break;
case FAILED:
    LOG.info("Failed with " + result.getFailureMessage());
    break;
case INACTIVE:
    LOG.info("Can connect but not currently connected as not in use");
    break;
case MISSING:
    LOG.info("No such remote server");
    break;
case RETRYING:
    LOG.info("Failed with " + result.getFailureMessage() +
        " but retry is scheduled");
    break;
default:
    break;
}

C
static char *get_server_state_string(
        DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_T state)
{
        switch(state) {
                case DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_INACTIVE:
                        return "Remote Server is inactive";
                case DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_CONNECTED:
                        return "Remote Server is connected";
                case DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_RETRYING:
                        return "Attempting to connect to Remote Server";
                case DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_FAILED:
                        return "Connection to the Remote Server has failed";
                case DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_MISSING:
                        return "Unable to reach Remote Server";
                default:
                        return "Unknown connection state";
        }
}

static int on_remote_server_checked(
        DIFFUSION_CHECK_REMOTE_SERVER_RESPONSE_T *response,
        void *context)
{
        DIFFUSION_REMOTE_SERVER_CONNECTION_STATE_T state =
                diffusion_check_remote_server_response_get_state(response);

        printf("%s.\n", get_server_state_string(state));
        return HANDLER_SUCCESS;
}

static int on_remote_server_checked_failed(
        SESSION_T *session,
        const DIFFUSION_ERROR_T *error)
{
        printf("An error has occurred while checking remote server definition: %s\n", error->message);
        return HANDLER_SUCCESS;
}
Apple
session.remoteServers.checkRemoteServer("New Remote Server") { (result, error) in
    if (error != nil) {
        print("An error has occurred while checking remote server definition: %@",
              error!.localizedDescription)
    }
    else {
        let translation_map : [PTDiffusionRemoteServerConnectionState:String] = [
            PTDiffusionRemoteServerConnectionState.inactive(): "Remote Server is inactive",
            PTDiffusionRemoteServerConnectionState.connected(): "Remote Server is connected",
            PTDiffusionRemoteServerConnectionState.retrying(): "Attempting to connect to Remote Server",
            PTDiffusionRemoteServerConnectionState.failed(): "Connection to the Remote Server has failed",
            PTDiffusionRemoteServerConnectionState.missing(): "Unable to reach Remote Server"
        ]
        print("%@", translation_map[result!.state]!)
    }
}

List available remote server definitions

Required permissions: view_server

Used to list all the remote servers that have been defined in the server.

Java and Android
final List<RemoteServer> servers =
    session.feature(RemoteServers.class)
        .listRemoteServers()
        .get(5, SECONDS);

C
static int on_remote_servers_listed(
        LIST_T *remote_servers,
        void *context)
{
        int list_size = list_get_size(remote_servers);
        printf("Remote Servers found: %d\n", list_size);
        for (int i = 0; i < list_size; i++) {
            DIFFUSION_REMOTE_SERVER_T *remote_server = list_get_data_indexed(remote_servers, i);
            char *name = diffusion_remote_server_get_name(remote_server);
            char *principal = diffusion_remote_server_get_principal(remote_server);
            char *url = diffusion_remote_server_get_url(remote_server);

            printf("%s: %s (%s)\n", name, url, principal);

            free(name);
            free(principal);
            free(url);
        }
        return HANDLER_SUCCESS;
}

static int on_remote_servers_listed_failed(
        SESSION_T *session,
        const DIFFUSION_ERROR_T *error)
{
        printf("An error has occurred while listing available remote servers: %s\n", error->message);
        return HANDLER_SUCCESS;
}


...


DIFFUSION_LIST_REMOTE_SERVERS_PARAMS_T list_remote_servers_params = {
        .on_remote_servers_listed = on_remote_servers_listed,
        .on_error = on_remote_servers_listed_failed
};
diffusion_list_remote_servers(session, list_remote_servers_params, NULL);
Apple
session.remoteServers.listRemoteServers() { (result, error) in
    if (error != nil) {
        print("An error has occurred while listing available remote servers: %@",
              error!.localizedDescription)
    }
    else {
        for remote_server in result! {
            print("%@: %@ (%@)", remote_server.name, remote_server.url, remote_server.principal)

        }
    }
}

Remove a remote server definition

Required permissions: control_server

Used to remove a named remote server if it exists.

If provided with a remote server name that does not exist in the Server, this operation will complete successfully.

When a named remote server is removed, any components that specify it would be disabled.

Parameters:

name
the name of the remote server
Java and Android
session.feature(RemoteServers.class).removeRemoteServer("Server_1")
    .get(5, SECONDS);

C
static int on_remote_server_removed(void *context)
{
        printf("Remote server has been successfully removed.\n");
        return HANDLER_SUCCESS;
}


static int on_remote_server_removed_failed(
        SESSION_T *session,
        const DIFFUSION_ERROR_T *error)
{
        printf("An error has occurred while removing remote server: %s\n", error->message);
        return HANDLER_SUCCESS;
}
Apple
session.remoteServers.removeRemoteServer("New Remote Server") { (error) in
    if (error != nil) {
        print("An error has occurred while removing remote server: %@",
              error!.localizedDescription)
    }
    else {
        print("Remote Server has been successfully removed")
    }
}