Secure Messages - Channels

publish method

The publish method allows a channelProvider and/or ChannelClient to publish a message to all applications subscribed to a topic. While this method operates over a channel, any message sent using this method will be sent to all applications within the channel.

📘

It is recommended to only use this method when publishing a message that is accessible to all applications on the channel.

Example

(async ()=> {
    const provider = await fin.InterApplicationBus.Channel.create('channelName');

    await provider.register('provider-action', async (payload, identity) => {
        console.log(payload, identity);
        return await Promise.all(provider.publish('client-action', { message: 'Broadcast from provider'}));
    });
})();

dispatch method

The dispatch method allows a channelProvider and/or channelClient to dispatch an action only between a chosen channelProvider and channelClient. In order for an application to participate in this type of message, the channelProvider or ChannelClient must know the identity of the opposing application.

📘

It is recommended to use this method when publishing a message that should only be accessible to one channelProvider or one channelClient.

Provider example

(async ()=> {
    const provider = await fin.InterApplicationBus.Channel.create('channelName');

    await provider.register('provider-action', async (payload, identity) => {
        console.log(payload, identity);
        return await provider.dispatch(identity, 'client-action', 'Hello, World!');
    });
})();

Client example

(async ()=> {
    const client = await fin.InterApplicationBus.Channel.connect('channelName');

    await client.register('client-action', (payload, identity) => {
        console.log(payload, identity);
        return {
            echo: payload
        };
    });

    const providerResponse = await client.dispatch('provider-action', { message: 'Hello From the client'});
    console.log(providerResponse);
})();

There are also several different methods available as part of the Channels API that will automate the process of securing a channel. Some of these include, but are not limited to, registering listeners for applications that connect or disconnect to/from a channel (modeled after IAB listeners), rejecting a connection, and adding middleware functions to return a specific action (such as logging unregistered actions as noted below).

Denying a connection

When a channelClient attempts to connect to a channel, the channelProvider has the ability to deny the connection. Who connects to a channel is at the discretion of the channelProvider. To maintain secure connections, we recommend that you only connect to Clients that you know and trust. However, it is at the developer’s discretion to make these decisions.

Denying a connection example

(async ()=> {
    const provider = await fin.InterApplicationBus.Channel.create('channelName');

    provider.onConnection(identity => {
        throw new Error('Connection Rejected');
    });
})();

Listeners

As noted previously, each channelClient will have to make a request to connect to a channel. As a channelProvider you can use the onChannelConnect method to employ a listener that will continuously listen for new channel connections. This method can also be employed by the ChannelClient if the Client is interested in learning more about the provider upon connection.

Creating a Listener

Use the onChannelConnect method to log channel payload information.

This method will return the channel payload and log the channel topic, channelName, and channelID, as well as the client's type, uuid, and name. This will help gather information about what applications are connected to your channel.

Listener example

const listener = (info) => console.log(info); // see return value below

fin.InterApplicationBus.Channel.onChannelConnect(channelPayload => {
    console.log(channelPayload);
});

// example shape
{
    "topic": "channel",
    "type": "connected",
    "uuid": "OpenfinPOC",
    "name": "OpenfinPOC",
    "channelName": "counter",
    "channelId": "OpenfinPOC/OpenfinPOC/counter"
}

Middleware

To automate the connection process, a channelProvider or channelClient can create a middleware function for default actions. channelProviders and channelClients can dispatch actions across a channel. When a connected application has dispatched an unregistered action, this example will log information about the client identity and unregistered action. This method is the best way to secure your application and connections as you can set the default channel action(s) as either the channelProvider or channelClient. Below are examples of setting a default action as a ChannelProvider or channelClient that will log unregistered actions as they occur.

Provider example

(async ()=> {
    const provider = await fin.InterApplicationBus.Channel.create('channelName');

    await provider.setDefaultAction((action, payload, identity) => {
        console.log(`Client with identity ${JSON.stringify(identity)} has attempted to dispatch unregistered action: ${action}.`);

        return {
            echo: payload
        };
    });

})();

Client example

(async ()=> {
    const client = await fin.InterApplicationBus.Channel.connect('channelName');

    await client.setDefaultAction((action, payload, identity) => {
        console.log(`Provider with identity ${JSON.stringify(identity)} has attempted to dispatch unregistered action: ${action}.`);

        return {
            echo: payload
        };
    });

})();

Did this page help you?