DN Engage Multicast Failover - rallytac/pub GitHub Wiki

Developer Note: Multicast Failover

A feature of Engage is its ability to automatically switch to multicast mode in those situations where a Rallypoint connection is desired but not possible due to reachability issues, misconfiguration of the Rallypoint link, invalid security parameters, system overload, or some other condition.

This capability is enabled by default but can be tuned and modified on a group-by-group basis. For example: you can configure group My Alpha Group to support failover to multicast mode but explicity deny group My Bravo Group from doing so. The minimal JSON snippet for group configurations would look as follows (where the Rallypoint we're using is 192.168.1.182:7443):

// My Alpha Group - supports multicast failover
{
    "type":1,
    "id":"{12345678-abcd-1234-abcd-1234567890ab}",
    "name":"My Alpha Group",                       
    "cryptoPassword":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",

    "enableMulticastFailover":true,       // Enable multicast failover (default is true)
    "multicastFailoverSecs":10,           // Failover to multicast operation after 10 seconds (the default)

    "rx":{                                
        "address":"239.42.42.1",
        "port":10000
    },

    "tx":{
        "address":"239.42.42.1",
        "port":10000
    },

    "txAudio":{
        "encoder":25,
    },

    "rallypoints":[
        {
            "host": {
                "address":"192.168.1.182",
                "port":7443
            },
            "certificate":"@certstore://rtsFactoryDefaultEngage",
            "certificateKey":"@certstore://rtsFactoryDefaultEngage",
            "verifyPeer":true,
            "allowSelfSignedCertificate":false,
            "transactionTimeoutMs":30000,
            "caCertificates": [
                "@certstore://rtsCA"
            ]
        }
    ]
}

// My Bravo Group - does not support multicast failover
{
    "type":1,
    "id":"{abcdefab-1234-abcd-1234-abcdefabcdef}",
    "name":"My Bravo Group",                       
    "cryptoPassword":"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",

    "enableMulticastFailover":false,       // Disable multicast failover
    "multicastFailoverSecs":10,            // Not necessary - ignored if enableMulticastFailover is false

    "rx":{                                
        "address":"239.42.42.2",
        "port":11000
    },

    "tx":{
        "address":"239.42.42.2",
        "port":11000
    },

    "txAudio":{
        "encoder":25,
    },

    "rallypoints":[
        {
            "host": {
                "address":"192.168.1.182",
                "port":7443
            },
            "certificate":"@certstore://rtsFactoryDefaultEngage",
            "certificateKey":"@certstore://rtsFactoryDefaultEngage",
            "verifyPeer":true,
            "allowSelfSignedCertificate":false,
            "transactionTimeoutMs":30000,
            "caCertificates": [
                "@certstore://rtsCA"
            ]
        }
    ]
}

Events

When a switch happens, the application is notified through the normal event mechanism wher the onGroupConnected and onGroupDisconnected event callbacks have a JSON-based qualifier passed as eventExtraJson. In this case in the form of an object named groupConnectionDetail. The elements of this object are as follows:

  • id: The ID of the group.
  • connectionType: The connection type of the event - 1 for multicast, 2 for Rallypoint.
  • peer: More information about the peer - either multicast information or Rallypoint information.
  • asFailover: Valid only for multicast (type 1) link types and then only when the link is connected.

For example, the following is for a CONNECTED event to a Rallypoint:

{
    "groupConnectionDetail": {
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "connectionType":2,        
        "peer":"192.168.1.182:7443",
        "asFailover":false
    }
}

Here is an example of a multicast link that has been established for failover purposes:

{
    "groupConnectionDetail": {
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "connectionType":1,        
        "peer":"239.42.43.1:49000/239.42.43.1:49000",
        "asFailover":true
    }
}

Example Event Flow

The following is a sequence of events that happen when we setup a group to use a Rallypoint at 192.168.1.182:7443 and where that link comes up at startup. Then, we take down the Rallypoint and the Engine, in turn, fails over to multicast operation. When the Rallypoint link is back up, the multicast link is dropped, and the Engine fails back to the Rallypoint.

In your application, you need to be tracking 2 "connected" states - one for Rallypoint, the other for multicast. And, when in multicast, whether that multicast link is up because its operating in failover mode. So, now your UI needs to check whether either of your Rallypoint or multicast connected states are true. If either is true, then your UI should indicate that the user can transmit and such. Basically, if either is true, then the app is operational.

Note that there may be times when both connected states are true (or false). This purely depends on the timings happening down in the guts of the Engine. Your application should, simplisticly treat notifications from the Engine as absolute and update the UI according to either of your connected states being true or, to show no operation possible, when both are false.

1. Normal connection to Rallypoint. We get a connected notification where the connectionType is 2 (rallypoint). You can ignore asFailover.

// on_ENGAGE_GROUP_CONNECTED: 
{
    "groupConnectionDetail":{
        "asFailover":false,
        "connectionType":2,
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "peer":"192.168.1.182:7443"
    }
}

2. Rallypoint link goes down. We get a disconnected event where the connectionType is 2 (rallypoint). You can ignore asFailover.

//on_ENGAGE_GROUP_DISCONNECTED: 
{
    "groupConnectionDetail":{
        "asFailover":false,
        "connectionType":2,
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "peer":"192.168.1.182:7443"
    }
}

3. After 10 seconds or so, the multicast link comes up for failover purposes. We get a connected event where the connectionType is 1 (multicast). The asFailover boolean is true indicating that this link is up for failover purposes.

// on_ENGAGE_GROUP_CONNECTED
{
    "groupConnectionDetail":{
        "asFailover":true,
        "connectionType":1,
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "peer":"239.42.43.1:49000/239.42.43.1:49000"
    }
}

4. A little while later, the Rallypoint comes back online. We get a connected event where the connectionType is 2 (Rallypoint). You can ignore asFailover.

// on_ENGAGE_GROUP_CONNECTED: 
{
    "groupConnectionDetail":{
        "asFailover":false,
        "connectionType":2,
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "peer":"192.168.1.182:7443"
    }
}

5. Very soon after Step 4. We get a disconnected event where the connectionType is 1 (multicast). This is the indication that the multicast link has dropped. You can ignore asFailover.

// on_ENGAGE_GROUP_DISCONNECTED: 
{
    "groupConnectionDetail":{
        "asFailover":true,
        "connectionType":1,
        "id":"{12345678-abcd-1234-abcd-1234567890ab}",
        "peer":"239.42.43.1:49000/239.42.43.1:49000"
    }
}